2222#include " moving_objects.h"
2323#include " doors_manager.h"
2424
25+ // ----------------------- Event processing-----------------------
26+
27+ CAI_Space::CEventCallback::CID CAI_Space::CEventCallbackStorage::RegisterCallback (CEventCallback* cb)
28+ {
29+ m_lock.lock ();
30+
31+ size_t i, cb_count = m_callbacks.size ();
32+
33+ for (i = 0 ; i < cb_count; ++i)
34+ {
35+ if (!m_callbacks[i])
36+ {
37+ break ;
38+ }
39+ }
40+
41+ if (i == cb_count)
42+ {
43+ m_callbacks.resize (cb_count + 1 );
44+ }
45+
46+ m_callbacks[i].reset (cb);
47+
48+ m_lock.unlock ();
49+ return i;
50+ }
51+ bool CAI_Space::CEventCallbackStorage::UnregisterCallback (CEventCallback::CID cid)
52+ {
53+ bool result = false ;
54+ m_lock.lock ();
55+
56+ if (cid < m_callbacks.size () && m_callbacks[cid])
57+ {
58+ m_callbacks[cid].reset (nullptr );
59+ result = true ;
60+ }
61+
62+ m_lock.unlock ();
63+ return result;
64+ }
65+
66+ void CAI_Space::CEventCallbackStorage::ExecuteCallbacks ()
67+ {
68+ m_lock.lock ();
69+
70+ for (auto & cb : m_callbacks)
71+ {
72+ if (cb)
73+ {
74+ cb->ProcessEvent ();
75+ }
76+ }
77+
78+ m_lock.unlock ();
79+ }
80+
81+ CAI_Space::CEventCallback::CID CAI_Space::CNotifier::RegisterCallback (CEventCallback* cb, EEventID event_id)
82+ {
83+ R_ASSERT (event_id < EVENT_COUNT);
84+ return m_callbacks[event_id].RegisterCallback (cb);
85+ }
86+
87+ bool CAI_Space::CNotifier::UnregisterCallback (CEventCallback::CID cid, EEventID event_id)
88+ {
89+ R_ASSERT (event_id < EVENT_COUNT);
90+ return m_callbacks[event_id].UnregisterCallback (cid);
91+ }
92+
93+ void CAI_Space::CNotifier::FireEvent (EEventID event_id)
94+ {
95+ R_ASSERT (event_id < EVENT_COUNT);
96+ m_callbacks[event_id].ExecuteCallbacks ();
97+ }
98+
99+ // ----------------------- Main CAI_Space stuff-----------------------
100+
25101static CAI_Space g_ai_space;
26102
27103CAI_Space& CAI_Space::GetInstance ()
@@ -48,14 +124,15 @@ void CAI_Space::init()
48124
49125 VERIFY (!GEnv.ScriptEngine );
50126 GEnv.ScriptEngine = new CScriptEngine ();
51- SetupScriptEngine ();
127+ RestartScriptEngine ();
52128 }
53129
54130 m_inited = true ;
55131}
56132
57133CAI_Space::~CAI_Space ()
58134{
135+ m_events_notifier.FireEvent (CNotifier::EVENT_SCRIPT_ENGINE_RESET);
59136 unload ();
60137 xr_delete (GEnv.ScriptEngine ); // XXX: wrapped into try..catch(...) in vanilla source
61138}
@@ -130,6 +207,21 @@ void CAI_Space::SetupScriptEngine()
130207 LoadCommonScripts ();
131208}
132209
210+ void CAI_Space::RestartScriptEngine ()
211+ {
212+ if (GEnv.ScriptEngine != nullptr )
213+ {
214+ m_events_notifier.FireEvent (CNotifier::EVENT_SCRIPT_ENGINE_RESET);
215+ }
216+
217+ SetupScriptEngine ();
218+ #ifdef DEBUG
219+ get_moving_objects ().clear ();
220+ #endif // DEBUG
221+
222+ m_events_notifier.FireEvent (CNotifier::EVENT_SCRIPT_ENGINE_STARTED);
223+ }
224+
133225void CAI_Space::load (LPCSTR level_name)
134226{
135227 VERIFY (m_game_graph);
@@ -173,3 +265,13 @@ void CAI_Space::set_alife(CALifeSimulator* alife_simulator)
173265 return ;
174266 SetGameGraph (nullptr );
175267}
268+
269+ CAI_Space::CEventCallback::CID CAI_Space::Subscribe (CEventCallback* cb, CNotifier::EEventID event_id)
270+ {
271+ return m_events_notifier.RegisterCallback (cb, event_id);
272+ }
273+
274+ bool CAI_Space::Unsubscribe (CAI_Space::CEventCallback::CID cid, CNotifier::EEventID event_id)
275+ {
276+ return m_events_notifier.UnregisterCallback (cid, event_id);
277+ }
0 commit comments