Skip to content

Commit

Permalink
Create events system for script engine restarting
Browse files Browse the repository at this point in the history
  • Loading branch information
FreeZoneMods committed Nov 3, 2018
1 parent eec4a57 commit bb5e0eb
Show file tree
Hide file tree
Showing 9 changed files with 214 additions and 28 deletions.
16 changes: 16 additions & 0 deletions src/xrGame/MainMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,20 @@ CMainMenu* MainMenu() { return (CMainMenu*)g_pGamePersistent->m_pMainMenu; };

CMainMenu::CMainMenu()
{
class CResetEventCb : public CAI_Space::CEventCallback
{
CMainMenu* m_mainmenu;

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

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

m_Flags.zero();
m_startDialog = NULL;
m_screenshotFrame = u32(-1);
Expand Down Expand Up @@ -156,6 +170,8 @@ CMainMenu::~CMainMenu()

xr_delete(m_demo_info_loader);
delete_data(m_pMB_ErrDlgs);

ai().Unsubscribe(m_script_reset_event_cid, CAI_Space::CNotifier::EVENT_SCRIPT_ENGINE_RESET);
}

void CMainMenu::ReadTextureInfo()
Expand Down
3 changes: 3 additions & 0 deletions src/xrGame/MainMenu.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class demo_info_loader;
#include "xrUICore/Callbacks/UIWndCallback.h"
#include "xrUICore/ui_base.h"
#include "DemoInfo.h"
#include "ai_space.h"

namespace gamespy_gp
{
Expand Down Expand Up @@ -196,6 +197,8 @@ class CMainMenu : public IMainMenu,
LPCSTR GetCDKeyFromRegistry();

demo_info const* GetDemoInfo(LPCSTR file_name);

CAI_Space::CEventCallback::CID m_script_reset_event_cid;
};

extern CMainMenu* MainMenu();
104 changes: 103 additions & 1 deletion src/xrGame/ai_space.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,82 @@
#include "moving_objects.h"
#include "doors_manager.h"

//----------------------- Event processing-----------------------

CAI_Space::CEventCallback::CID CAI_Space::CEventCallbackStorage::RegisterCallback(CEventCallback* cb)
{
m_lock.lock();

size_t i, cb_count = m_callbacks.size();

for (i = 0; i < cb_count; ++i)
{
if (!m_callbacks[i])
{
break;
}
}

if (i == cb_count)
{
m_callbacks.resize(cb_count + 1);
}

m_callbacks[i].reset(cb);

m_lock.unlock();
return i;
}
bool CAI_Space::CEventCallbackStorage::UnregisterCallback(CEventCallback::CID cid)
{
bool result = false;
m_lock.lock();

if (cid < m_callbacks.size() && m_callbacks[cid])
{
m_callbacks[cid].reset(nullptr);
result = true;
}

m_lock.unlock();
return result;
}

void CAI_Space::CEventCallbackStorage::ExecuteCallbacks()
{
m_lock.lock();

for (auto& cb : m_callbacks)
{
if (cb)
{
cb->ProcessEvent();
}
}

m_lock.unlock();
}

CAI_Space::CEventCallback::CID CAI_Space::CNotifier::RegisterCallback(CEventCallback* cb, EEventID event_id)
{
R_ASSERT(event_id < EVENT_COUNT);
return m_callbacks[event_id].RegisterCallback(cb);
}

bool CAI_Space::CNotifier::UnregisterCallback(CEventCallback::CID cid, EEventID event_id)
{
R_ASSERT(event_id < EVENT_COUNT);
return m_callbacks[event_id].UnregisterCallback(cid);
}

void CAI_Space::CNotifier::FireEvent(EEventID event_id)
{
R_ASSERT(event_id < EVENT_COUNT);
m_callbacks[event_id].ExecuteCallbacks();
}

//----------------------- Main CAI_Space stuff-----------------------

static CAI_Space g_ai_space;

CAI_Space& CAI_Space::GetInstance()
Expand All @@ -48,14 +124,15 @@ void CAI_Space::init()

VERIFY(!GEnv.ScriptEngine);
GEnv.ScriptEngine = new CScriptEngine();
SetupScriptEngine();
RestartScriptEngine();
}

m_inited = true;
}

CAI_Space::~CAI_Space()
{
m_events_notifier.FireEvent(CNotifier::EVENT_SCRIPT_ENGINE_RESET);
unload();
xr_delete(GEnv.ScriptEngine); // XXX: wrapped into try..catch(...) in vanilla source
}
Expand Down Expand Up @@ -130,6 +207,21 @@ void CAI_Space::SetupScriptEngine()
LoadCommonScripts();
}

void CAI_Space::RestartScriptEngine()
{
if (GEnv.ScriptEngine != nullptr)
{
m_events_notifier.FireEvent(CNotifier::EVENT_SCRIPT_ENGINE_RESET);
}

SetupScriptEngine();
#ifdef DEBUG
get_moving_objects().clear();
#endif // DEBUG

m_events_notifier.FireEvent(CNotifier::EVENT_SCRIPT_ENGINE_STARTED);
}

void CAI_Space::load(LPCSTR level_name)
{
VERIFY(m_game_graph);
Expand Down Expand Up @@ -173,3 +265,13 @@ void CAI_Space::set_alife(CALifeSimulator* alife_simulator)
return;
SetGameGraph(nullptr);
}

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

bool CAI_Space::Unsubscribe(CAI_Space::CEventCallback::CID cid, CNotifier::EEventID event_id)
{
return m_events_notifier.UnregisterCallback(cid, event_id);
}
50 changes: 49 additions & 1 deletion src/xrGame/ai_space.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
#pragma once

#include "xrAICore/AISpaceBase.hpp"
#include "xrCommon/xr_array.h"

#include <memory>
#include <mutex>

class CGameGraph;
class CGameLevelCrossTable;
Expand All @@ -30,6 +32,47 @@ class manager;

class CAI_Space : public AISpaceBase
{
public:
class CEventCallback
{
public:
using CID = size_t;
static const CID INVALID_CID = std::numeric_limits<CID>::max();

virtual void ProcessEvent() = 0;
virtual ~CEventCallback(){};
};

class CEventCallbackStorage
{
xr_vector<std::unique_ptr<CEventCallback>> m_callbacks;
std::mutex m_lock;

public:
CEventCallback::CID RegisterCallback(CEventCallback* cb);
bool UnregisterCallback(CEventCallback::CID cid);
void ExecuteCallbacks();
};

class CNotifier
{
public:
enum EEventID
{
EVENT_SCRIPT_ENGINE_STARTED,
EVENT_SCRIPT_ENGINE_RESET,
EVENT_COUNT,
};

private:
xr_array<CEventCallbackStorage, EVENT_COUNT> m_callbacks;

public:
CEventCallback::CID RegisterCallback(CEventCallback* cb, EEventID event_id);
bool UnregisterCallback(CEventCallback::CID cid, EEventID event_id);
void FireEvent(EEventID event_id);
};

private:
friend class CALifeSimulator;
friend class CALifeGraphRegistry;
Expand All @@ -39,6 +82,7 @@ class CAI_Space : public AISpaceBase

private:
bool m_inited = false;
CNotifier m_events_notifier;

std::unique_ptr<CEF_Storage> m_ef_storage;
std::unique_ptr<CCoverManager> m_cover_manager;
Expand All @@ -54,6 +98,7 @@ class CAI_Space : public AISpaceBase
void set_alife(CALifeSimulator* alife_simulator);
void LoadCommonScripts();
void RegisterScriptClasses();
void SetupScriptEngine();

public:
CAI_Space() = default;
Expand All @@ -62,7 +107,10 @@ class CAI_Space : public AISpaceBase
virtual ~CAI_Space();
static CAI_Space& GetInstance();

void SetupScriptEngine();
CEventCallback::CID Subscribe(CEventCallback* cb, CNotifier::EEventID event_id);
bool Unsubscribe(CEventCallback::CID cid, CNotifier::EEventID event_id);
void RestartScriptEngine();

IC CEF_Storage& ef_storage() const;

IC const CALifeSimulator& alife() const;
Expand Down
9 changes: 1 addition & 8 deletions src/xrGame/alife_simulator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@

LPCSTR alife_section = "alife";

extern void destroy_lua_wpn_params();

CALifeSimulator::CALifeSimulator(IPureServer* server, shared_str* command_line)
: CALifeUpdateManager(server, alife_section), CALifeInteractionManager(server, alife_section),
Expand All @@ -32,13 +31,7 @@ CALifeSimulator::CALifeSimulator(IPureServer* server, shared_str* command_line)
// XXX: why do we need to reinitialize script engine?
if (!strstr(Core.Params, "-keep_lua"))
{
destroy_lua_wpn_params();
MainMenu()->DestroyInternal(true);
xr_delete(g_object_factory);
ai().SetupScriptEngine();
#ifdef DEBUG
ai().get_moving_objects().clear();
#endif // DEBUG
ai().RestartScriptEngine();
}

ai().set_alife(this);
Expand Down
29 changes: 21 additions & 8 deletions src/xrGame/ui/UIWpnParams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#include "UIXmlInit.h"
#include "Level.h"
#include "game_base_space.h"
#include "ai_space.h"
#include "xrScriptEngine/script_engine.hpp"
#include "inventory_item_object.h"
#include "UIInventoryUtilities.h"
Expand All @@ -21,6 +20,22 @@ struct SLuaWpnParams
~SLuaWpnParams();
};

static SLuaWpnParams* g_lua_wpn_params = nullptr;

static CAI_Space::CEventCallback::CID g_wpn_params_cb_cid = CAI_Space::CEventCallback::INVALID_CID;

class CResetEventCb : public CAI_Space::CEventCallback
{
public:
void ProcessEvent() override
{
if (g_lua_wpn_params)
{
xr_delete(g_lua_wpn_params);
}
}
};

SLuaWpnParams::SLuaWpnParams()
{
bool functor_exists;
Expand All @@ -34,16 +49,14 @@ SLuaWpnParams::SLuaWpnParams()
VERIFY(functor_exists);
functor_exists = GEnv.ScriptEngine->functor("ui_wpn_params.GetAccuracy", m_functorAccuracy);
VERIFY(functor_exists);

if (g_wpn_params_cb_cid == CAI_Space::CEventCallback::INVALID_CID)
{
g_wpn_params_cb_cid = ai().Subscribe(new CResetEventCb(), CAI_Space::CNotifier::EVENT_SCRIPT_ENGINE_RESET);
}
}

SLuaWpnParams::~SLuaWpnParams() {}
SLuaWpnParams* g_lua_wpn_params = NULL;

void destroy_lua_wpn_params()
{
if (g_lua_wpn_params)
xr_delete(g_lua_wpn_params);
}

// =====================================================================

Expand Down
2 changes: 0 additions & 2 deletions src/xrGame/xrgame_dll_detach.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,9 @@ void init_game_globals()
extern CUIXml* g_uiSpotXml;
extern CUIXml* pWpnScopeXml;

extern void destroy_lua_wpn_params();

void clean_game_globals()
{
destroy_lua_wpn_params();
// destroy object factory
xr_delete(g_object_factory);
// destroy monster squad global var
Expand Down
4 changes: 0 additions & 4 deletions src/xrServerEntities/object_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@
// Description : Object factory
////////////////////////////////////////////////////////////////////////////

#ifndef object_factoryH
#define object_factoryH

#pragma once

#include "object_item_abstract.h"
Expand Down Expand Up @@ -91,4 +88,3 @@ extern CObjectFactory* g_object_factory;
IC const CObjectFactory& object_factory();

#include "object_factory_inline.h"
#endif
Loading

0 comments on commit bb5e0eb

Please sign in to comment.