Skip to content

Commit

Permalink
Change subscriptions logic for CAI_Space
Browse files Browse the repository at this point in the history
It's better to create callbacks in the same place where deletion happens. So, let's make template functions to automatically create callbacks and subscribe it.
  • Loading branch information
FreeZoneMods committed Nov 7, 2018
1 parent 685e47d commit 83a67af
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 21 deletions.
8 changes: 7 additions & 1 deletion src/utils/xrSE_Factory/ai_space.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,13 @@ class CAI_Space
EVENT_SCRIPT_ENGINE_RESET,
EVENT_COUNT,
};
CEventNotifierCallback::CID Subscribe(CEventNotifierCallback* cb, EEventID event_id) { return 0; }

template <class CB, class... Args>
CEventNotifierCallback::CID Subscribe(EEventID event_id, Args&&... args)
{
return 0;
}

bool Unsubscribe(CEventNotifierCallback::CID cid, EEventID event_id) { return true; }
};

Expand Down
47 changes: 47 additions & 0 deletions src/xrCore/Events/Notifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ class CEventNotifierCallback
virtual ~CEventNotifierCallback(){};
};

class CEventNotifierCallbackWithCid : public CEventNotifierCallback
{
private:
const CID m_cid;

public:
CEventNotifierCallbackWithCid(CID cid) : m_cid(cid), CEventNotifierCallback(){};
CID GetCid() const { return m_cid; }
};

template <unsigned int CNT>
class CEventNotifier
{
Expand All @@ -41,6 +51,14 @@ class CEventNotifier
xr_vector<CCallbackWrapper> m_callbacks;
Lock m_lock;

CEventNotifierCallback::CID FindFreeCid()
{
ScopeLock lock(&m_lock);
auto it = std::find(m_callbacks.begin(), m_callbacks.end(), nullptr);
return (it == m_callbacks.end()) ? CEventNotifierCallback::INVALID_CID :
std::distance(m_callbacks.begin(), it);
}

public:
CEventNotifierCallback::CID RegisterCallback(CEventNotifierCallback* cb)
{
Expand All @@ -50,6 +68,28 @@ class CEventNotifier
(it->callback.reset(cb), std::distance(m_callbacks.begin(), it));
}

template <class CB, class... Args>
CEventNotifierCallback::CID CreateRegisteredCallback(Args&&... args)
{
static_assert(std::is_base_of<CEventNotifierCallbackWithCid, CB>::value);

ScopeLock lock(&m_lock);

auto cid = FindFreeCid();
CB* cb = new CB((cid == CEventNotifierCallback::INVALID_CID) ? m_callbacks.size() : cid, args...);

if (cid == CEventNotifierCallback::INVALID_CID)
{
m_callbacks.emplace_back(cb);
}
else
{
m_callbacks[cid].callback.reset(cb);
}

return cb->GetCid();
}

bool UnregisterCallback(CEventNotifierCallback::CID cid)
{
bool result = false;
Expand Down Expand Up @@ -100,6 +140,13 @@ class CEventNotifier
return m_callbacks[event_id].RegisterCallback(cb);
}

template <class CB, class... Args>
CEventNotifierCallback::CID CreateRegisteredCallback(unsigned int event_id, Args&&... args)
{
R_ASSERT(event_id < CNT);
return m_callbacks[event_id].CreateRegisteredCallback<CB>(args...);
}

bool UnregisterCallback(CEventNotifierCallback::CID cid, unsigned int event_id)
{
R_ASSERT(event_id < CNT);
Expand Down
6 changes: 3 additions & 3 deletions src/xrGame/MainMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,16 +67,16 @@ CMainMenu* MainMenu() { return (CMainMenu*)g_pGamePersistent->m_pMainMenu; };

CMainMenu::CMainMenu()
{
class CResetEventCb : public CEventNotifierCallback
class CResetEventCb : public CEventNotifierCallbackWithCid
{
CMainMenu* m_mainmenu;

public:
CResetEventCb(CMainMenu* mm) : m_mainmenu(mm) {}
CResetEventCb(CID cid, CMainMenu* mm) : m_mainmenu(mm), CEventNotifierCallbackWithCid(cid) {}
void ProcessEvent() override { m_mainmenu->DestroyInternal(true); }
};

m_script_reset_event_cid = ai().Subscribe(new CResetEventCb(this), CAI_Space::EVENT_SCRIPT_ENGINE_RESET);
m_script_reset_event_cid = ai().Subscribe<CResetEventCb>(CAI_Space::EVENT_SCRIPT_ENGINE_RESET, this);

m_Flags.zero();
m_startDialog = NULL;
Expand Down
5 changes: 0 additions & 5 deletions src/xrGame/ai_space.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,11 +197,6 @@ void CAI_Space::set_alife(CALifeSimulator* alife_simulator)
SetGameGraph(nullptr);
}

CEventNotifierCallback::CID CAI_Space::Subscribe(CEventNotifierCallback* cb, EEventID event_id)
{
return m_events_notifier.RegisterCallback(cb, event_id);
}

bool CAI_Space::Unsubscribe(CEventNotifierCallback::CID cid, EEventID event_id)
{
return m_events_notifier.UnregisterCallback(cid, event_id);
Expand Down
7 changes: 6 additions & 1 deletion src/xrGame/ai_space.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,12 @@ class CAI_Space : public AISpaceBase
virtual ~CAI_Space();
static CAI_Space& GetInstance();

CEventNotifierCallback::CID Subscribe(CEventNotifierCallback* cb, EEventID event_id);
template <class CB, class... Args>
CEventNotifierCallback::CID Subscribe(EEventID event_id, Args&&... args)
{
return m_events_notifier.CreateRegisteredCallback<CB>(event_id, args...);
}

bool Unsubscribe(CEventNotifierCallback::CID cid, EEventID event_id);
void RestartScriptEngine();

Expand Down
10 changes: 4 additions & 6 deletions src/xrGame/ui/UIWpnParams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,21 +108,19 @@ void CUIWpnParams::SetInfo(CInventoryItem* slot_wpn, CInventoryItem& cur_wpn)
{
if (!g_lua_wpn_params)
{
class CResetEventCb : public CEventNotifierCallback
class CResetEventCb : public CEventNotifierCallbackWithCid
{
public:
CID m_cid = INVALID_CID;

CResetEventCb(CID cid) : CEventNotifierCallbackWithCid(cid) {}
void ProcessEvent() override
{
xr_delete(g_lua_wpn_params);
ai().Unsubscribe(m_cid, CAI_Space::EVENT_SCRIPT_ENGINE_RESET);
ai().Unsubscribe(GetCid(), CAI_Space::EVENT_SCRIPT_ENGINE_RESET);
}
};

g_lua_wpn_params = new SLuaWpnParams();
auto cb = new CResetEventCb();
cb->m_cid = ai().Subscribe(cb, CAI_Space::EVENT_SCRIPT_ENGINE_RESET);
ai().Subscribe<CResetEventCb>(CAI_Space::EVENT_SCRIPT_ENGINE_RESET);
}

LPCSTR cur_section = cur_wpn.object().cNameSect().c_str();
Expand Down
9 changes: 4 additions & 5 deletions src/xrServerEntities/object_factory_inline.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,19 @@ IC const CObjectFactory& object_factory()
g_object_factory = new CObjectFactory();
g_object_factory->init();

class CResetEventCb : public CEventNotifierCallback
class CResetEventCb : public CEventNotifierCallbackWithCid
{
public:
CID m_cid;
CResetEventCb(CID cid) : CEventNotifierCallbackWithCid(cid) {}

void ProcessEvent() override
{
xr_delete(g_object_factory);
ai().Unsubscribe(m_cid, CAI_Space::EVENT_SCRIPT_ENGINE_RESET);
ai().Unsubscribe(GetCid(), CAI_Space::EVENT_SCRIPT_ENGINE_RESET);
}
};

CResetEventCb* e = new CResetEventCb();
e->m_cid = ai().Subscribe(e, CAI_Space::EVENT_SCRIPT_ENGINE_RESET);
ai().Subscribe<CResetEventCb>(CAI_Space::EVENT_SCRIPT_ENGINE_RESET);
}
return (*g_object_factory);
}
Expand Down

0 comments on commit 83a67af

Please sign in to comment.