Changeset View
Changeset View
Standalone View
Standalone View
source/simulation2/Simulation2.cpp
Show First 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | |||||
#include <iomanip> | #include <iomanip> | ||||
class CSimulation2Impl | class CSimulation2Impl | ||||
{ | { | ||||
public: | public: | ||||
CSimulation2Impl(CUnitManager* unitManager, shared_ptr<ScriptContext> cx, CTerrain* terrain) : | CSimulation2Impl(CUnitManager* unitManager, shared_ptr<ScriptContext> cx, CTerrain* terrain) : | ||||
m_SimContext(), m_ComponentManager(m_SimContext, cx), | m_SimContext(), m_ComponentManager(m_SimContext, cx), | ||||
m_EnableOOSLog(false), m_EnableSerializationTest(false), m_RejoinTestTurn(-1), m_TestingRejoin(false), | m_EnableOOSLog(false), m_EnableSerializationTest(false), m_RejoinTestTurn(-1), m_TestingRejoin(false), | ||||
m_SecondaryTerrain(nullptr), m_SecondaryContext(nullptr), m_SecondaryComponentManager(nullptr), m_SecondaryLoadedScripts(nullptr), | m_SecondaryTerrain(nullptr), m_SecondaryContext(nullptr), m_SecondaryComponentManager(nullptr), m_SecondaryLoadedScripts(nullptr), m_InitAttributes(cx->GetGeneralJSContext()) | ||||
m_MapSettings(cx->GetGeneralJSContext()), m_InitAttributes(cx->GetGeneralJSContext()) | |||||
{ | { | ||||
m_SimContext.m_UnitManager = unitManager; | m_SimContext.m_UnitManager = unitManager; | ||||
m_SimContext.m_Terrain = terrain; | m_SimContext.m_Terrain = terrain; | ||||
m_ComponentManager.LoadComponentTypes(); | m_ComponentManager.LoadComponentTypes(); | ||||
RegisterFileReloadFunc(ReloadChangedFileCB, this); | RegisterFileReloadFunc(ReloadChangedFileCB, this); | ||||
// Tests won't have config initialised | // Tests won't have config initialised | ||||
Show All 35 Lines | public: | ||||
{ | { | ||||
componentManager.ResetState(); | componentManager.ResetState(); | ||||
componentManager.InitSystemEntity(); | componentManager.InitSystemEntity(); | ||||
componentManager.AddSystemComponents(skipScriptedComponents, skipAI); | componentManager.AddSystemComponents(skipScriptedComponents, skipAI); | ||||
} | } | ||||
static bool LoadDefaultScripts(CComponentManager& componentManager, std::set<VfsPath>* loadedScripts); | static bool LoadDefaultScripts(CComponentManager& componentManager, std::set<VfsPath>* loadedScripts); | ||||
static bool LoadScripts(CComponentManager& componentManager, std::set<VfsPath>* loadedScripts, const VfsPath& path); | static bool LoadScripts(CComponentManager& componentManager, std::set<VfsPath>* loadedScripts, const VfsPath& path); | ||||
static bool LoadTriggerScripts(CComponentManager& componentManager, JS::HandleValue mapSettings, std::set<VfsPath>* loadedScripts); | static bool LoadTriggerScripts(CComponentManager& componentManager, JS::HandleValue initAttributes, std::set<VfsPath>* loadedScripts); | ||||
Status ReloadChangedFile(const VfsPath& path); | Status ReloadChangedFile(const VfsPath& path); | ||||
static Status ReloadChangedFileCB(void* param, const VfsPath& path) | static Status ReloadChangedFileCB(void* param, const VfsPath& path) | ||||
{ | { | ||||
return static_cast<CSimulation2Impl*>(param)->ReloadChangedFile(path); | return static_cast<CSimulation2Impl*>(param)->ReloadChangedFile(path); | ||||
} | } | ||||
int ProgressiveLoad(); | int ProgressiveLoad(); | ||||
void Update(int turnLength, const std::vector<SimulationCommand>& commands); | void Update(int turnLength, const std::vector<SimulationCommand>& commands); | ||||
static void UpdateComponents(CSimContext& simContext, fixed turnLengthFixed, const std::vector<SimulationCommand>& commands); | static void UpdateComponents(CSimContext& simContext, fixed turnLengthFixed, const std::vector<SimulationCommand>& commands); | ||||
void Interpolate(float simFrameLength, float frameOffset, float realFrameLength); | void Interpolate(float simFrameLength, float frameOffset, float realFrameLength); | ||||
void DumpState(); | void DumpState(); | ||||
CSimContext m_SimContext; | CSimContext m_SimContext; | ||||
CComponentManager m_ComponentManager; | CComponentManager m_ComponentManager; | ||||
double m_DeltaTime; | double m_DeltaTime; | ||||
float m_LastFrameOffset; | float m_LastFrameOffset; | ||||
std::string m_StartupScript; | std::string m_StartupScript; | ||||
JS::PersistentRootedValue m_InitAttributes; | JS::PersistentRootedValue m_InitAttributes; | ||||
JS::PersistentRootedValue m_MapSettings; | |||||
std::set<VfsPath> m_LoadedScripts; | std::set<VfsPath> m_LoadedScripts; | ||||
uint32_t m_TurnNumber; | uint32_t m_TurnNumber; | ||||
bool m_EnableOOSLog; | bool m_EnableOOSLog; | ||||
OsPath m_OOSLogPath; | OsPath m_OOSLogPath; | ||||
▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | if (loadedScripts) | ||||
loadedScripts->insert(scriptPath); | loadedScripts->insert(scriptPath); | ||||
LOGMESSAGE("Loading simulation script '%s'", scriptPath.string8()); | LOGMESSAGE("Loading simulation script '%s'", scriptPath.string8()); | ||||
if (!componentManager.LoadScript(scriptPath)) | if (!componentManager.LoadScript(scriptPath)) | ||||
ok = false; | ok = false; | ||||
} | } | ||||
return ok; | return ok; | ||||
} | } | ||||
bool CSimulation2Impl::LoadTriggerScripts(CComponentManager& componentManager, JS::HandleValue mapSettings, std::set<VfsPath>* loadedScripts) | bool CSimulation2Impl::LoadTriggerScripts(CComponentManager& componentManager, JS::HandleValue initAttributes, std::set<VfsPath>* loadedScripts) | ||||
{ | |||||
bool ok = true; | |||||
if (componentManager.GetScriptInterface().HasProperty(mapSettings, "TriggerScripts")) | |||||
{ | { | ||||
ScriptInterface& scriptInterface = componentManager.GetScriptInterface(); | |||||
ScriptRequest rq(scriptInterface); | |||||
if (!scriptInterface.HasProperty(initAttributes, "settings")) | |||||
return true; | |||||
JS::RootedValue settings(rq.cx); | |||||
scriptInterface.GetProperty(initAttributes, "settings", &settings); | |||||
if (!scriptInterface.HasProperty(settings, "TriggerScripts")) | |||||
return true; | |||||
std::vector<std::string> scriptNames; | std::vector<std::string> scriptNames; | ||||
componentManager.GetScriptInterface().GetProperty(mapSettings, "TriggerScripts", scriptNames); | scriptInterface.GetProperty(settings, "TriggerScripts", scriptNames); | ||||
bool ok = true; | |||||
for (const std::string& triggerScript : scriptNames) | for (const std::string& triggerScript : scriptNames) | ||||
{ | { | ||||
std::string scriptName = "maps/" + triggerScript; | std::string scriptName = "maps/" + triggerScript; | ||||
if (loadedScripts) | if (loadedScripts) | ||||
{ | { | ||||
if (loadedScripts->find(scriptName) != loadedScripts->end()) | if (loadedScripts->find(scriptName) != loadedScripts->end()) | ||||
continue; | continue; | ||||
loadedScripts->insert(scriptName); | loadedScripts->insert(scriptName); | ||||
} | } | ||||
LOGMESSAGE("Loading trigger script '%s'", scriptName.c_str()); | LOGMESSAGE("Loading trigger script '%s'", scriptName.c_str()); | ||||
if (!componentManager.LoadScript(scriptName.data())) | if (!componentManager.LoadScript(scriptName.data())) | ||||
ok = false; | ok = false; | ||||
} | } | ||||
} | |||||
return ok; | return ok; | ||||
} | } | ||||
Status CSimulation2Impl::ReloadChangedFile(const VfsPath& path) | Status CSimulation2Impl::ReloadChangedFile(const VfsPath& path) | ||||
{ | { | ||||
// Ignore if this file wasn't loaded as a script | // Ignore if this file wasn't loaded as a script | ||||
// (TODO: Maybe we ought to load in any new .js files that are created in the right directories) | // (TODO: Maybe we ought to load in any new .js files that are created in the right directories) | ||||
if (m_LoadedScripts.find(path) == m_LoadedScripts.end()) | if (m_LoadedScripts.find(path) == m_LoadedScripts.end()) | ||||
▲ Show 20 Lines • Show All 91 Lines • ▼ Show 20 Lines | if (secondaryStateAfter) | ||||
DumpSerializationTestState(*secondaryStateAfter, path, L"after.b"); | DumpSerializationTestState(*secondaryStateAfter, path, L"after.b"); | ||||
debug_warn(L"Serialization test failure"); | debug_warn(L"Serialization test failure"); | ||||
} | } | ||||
void CSimulation2Impl::InitRNGSeedSimulation() | void CSimulation2Impl::InitRNGSeedSimulation() | ||||
{ | { | ||||
u32 seed = 0; | u32 seed = 0; | ||||
if (!m_ComponentManager.GetScriptInterface().HasProperty(m_MapSettings, "Seed") || | if (!m_ComponentManager.GetScriptInterface().HasProperty(m_InitAttributes, "Seed") || | ||||
!m_ComponentManager.GetScriptInterface().GetProperty(m_MapSettings, "Seed", seed)) | !m_ComponentManager.GetScriptInterface().GetProperty(m_InitAttributes, "Seed", seed)) | ||||
LOGWARNING("CSimulation2Impl::InitRNGSeedSimulation: No seed value specified - using %d", seed); | LOGWARNING("CSimulation2Impl::InitRNGSeedSimulation: No seed value specified - using %d", seed); | ||||
m_ComponentManager.SetRNGSeed(seed); | m_ComponentManager.SetRNGSeed(seed); | ||||
} | } | ||||
void CSimulation2Impl::InitRNGSeedAI() | void CSimulation2Impl::InitRNGSeedAI() | ||||
{ | { | ||||
u32 seed = 0; | u32 seed = 0; | ||||
if (!m_ComponentManager.GetScriptInterface().HasProperty(m_MapSettings, "AISeed") || | if (!m_ComponentManager.GetScriptInterface().HasProperty(m_InitAttributes, "AISeed") || | ||||
!m_ComponentManager.GetScriptInterface().GetProperty(m_MapSettings, "AISeed", seed)) | !m_ComponentManager.GetScriptInterface().GetProperty(m_InitAttributes, "AISeed", seed)) | ||||
LOGWARNING("CSimulation2Impl::InitRNGSeedAI: No seed value specified - using %d", seed); | LOGWARNING("CSimulation2Impl::InitRNGSeedAI: No seed value specified - using %d", seed); | ||||
CmpPtr<ICmpAIManager> cmpAIManager(m_SimContext, SYSTEM_ENTITY); | CmpPtr<ICmpAIManager> cmpAIManager(m_SimContext, SYSTEM_ENTITY); | ||||
if (cmpAIManager) | if (cmpAIManager) | ||||
cmpAIManager->SetRNGSeed(seed); | cmpAIManager->SetRNGSeed(seed); | ||||
} | } | ||||
void CSimulation2Impl::Update(int turnLength, const std::vector<SimulationCommand>& commands) | void CSimulation2Impl::Update(int turnLength, const std::vector<SimulationCommand>& commands) | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | if (m_EnableSerializationTest || startRejoinTest) | ||||
delete m_SecondaryLoadedScripts; | delete m_SecondaryLoadedScripts; | ||||
m_SecondaryLoadedScripts = new std::set<VfsPath>(); | m_SecondaryLoadedScripts = new std::set<VfsPath>(); | ||||
ENSURE(LoadDefaultScripts(*m_SecondaryComponentManager, m_SecondaryLoadedScripts)); | ENSURE(LoadDefaultScripts(*m_SecondaryComponentManager, m_SecondaryLoadedScripts)); | ||||
ResetComponentState(*m_SecondaryComponentManager, false, false); | ResetComponentState(*m_SecondaryComponentManager, false, false); | ||||
// Load the trigger scripts after we have loaded the simulation. | // Load the trigger scripts after we have loaded the simulation. | ||||
{ | { | ||||
ScriptRequest rq2(m_SecondaryComponentManager->GetScriptInterface()); | ScriptRequest rq2(m_SecondaryComponentManager->GetScriptInterface()); | ||||
JS::RootedValue mapSettingsCloned(rq2.cx, | JS::RootedValue initAttributesCloned(rq2.cx, | ||||
m_SecondaryComponentManager->GetScriptInterface().CloneValueFromOtherCompartment(scriptInterface, m_MapSettings)); | m_SecondaryComponentManager->GetScriptInterface().CloneValueFromOtherCompartment(scriptInterface, m_InitAttributes)); | ||||
ENSURE(LoadTriggerScripts(*m_SecondaryComponentManager, mapSettingsCloned, m_SecondaryLoadedScripts)); | ENSURE(LoadTriggerScripts(*m_SecondaryComponentManager, initAttributesCloned, m_SecondaryLoadedScripts)); | ||||
} | } | ||||
// Load the map into the secondary simulation | // Load the map into the secondary simulation | ||||
LDR_BeginRegistering(); | LDR_BeginRegistering(); | ||||
std::unique_ptr<CMapReader> mapReader = std::make_unique<CMapReader>(); | std::unique_ptr<CMapReader> mapReader = std::make_unique<CMapReader>(); | ||||
std::string mapType; | std::string mapType; | ||||
▲ Show 20 Lines • Show All 360 Lines • ▼ Show 20 Lines | |||||
const std::string& CSimulation2::GetStartupScript() | const std::string& CSimulation2::GetStartupScript() | ||||
{ | { | ||||
return m->m_StartupScript; | return m->m_StartupScript; | ||||
} | } | ||||
void CSimulation2::SetInitAttributes(JS::HandleValue attribs) | void CSimulation2::SetInitAttributes(JS::HandleValue attribs) | ||||
{ | { | ||||
m->m_InitAttributes = attribs; | m->m_InitAttributes = attribs; | ||||
m->InitRNGSeedSimulation(); | |||||
m->InitRNGSeedAI(); | |||||
} | } | ||||
JS::Value CSimulation2::GetInitAttributes() | JS::Value CSimulation2::GetInitAttributes() | ||||
{ | { | ||||
return m->m_InitAttributes.get(); | return m->m_InitAttributes.get(); | ||||
} | } | ||||
void CSimulation2::GetInitAttributes(JS::MutableHandleValue ret) | void CSimulation2::GetInitAttributes(JS::MutableHandleValue ret) | ||||
{ | { | ||||
ret.set(m->m_InitAttributes); | ret.set(m->m_InitAttributes); | ||||
} | } | ||||
void CSimulation2::SetMapSettings(const std::string& settings) | std::string CSimulation2::GetSettingsFromInitAttributes() | ||||
{ | { | ||||
m->m_ComponentManager.GetScriptInterface().ParseJSON(settings, &m->m_MapSettings); | ScriptRequest rq(GetScriptInterface()); | ||||
if (!GetScriptInterface().HasProperty(m->m_InitAttributes, "settings")) | |||||
return "{}"; | |||||
JS::RootedValue settingsVal(rq.cx); | |||||
if (!GetScriptInterface().GetProperty(m->m_InitAttributes, "settings", &settingsVal)) | |||||
{ | |||||
LOGERROR("Error getting settings from init attributes"); | |||||
return "{}"; | |||||
} | |||||
return GetScriptInterface().StringifyJSON(&settingsVal); | |||||
} | } | ||||
void CSimulation2::SetMapSettings(JS::HandleValue settings) | void CSimulation2::SetInitAttributesFromSettings(const std::string& settings) | ||||
{ | { | ||||
m->m_MapSettings = settings; | ScriptRequest rq(GetScriptInterface()); | ||||
JS::RootedValue settingsVal(rq.cx); | |||||
GetScriptInterface().ParseJSON(settings, &settingsVal); | |||||
GetScriptInterface().CreateObject(rq, &m->m_InitAttributes, "settings", settingsVal); | |||||
m->InitRNGSeedSimulation(); | m->InitRNGSeedSimulation(); | ||||
m->InitRNGSeedAI(); | m->InitRNGSeedAI(); | ||||
} | } | ||||
std::string CSimulation2::GetMapSettingsString() | |||||
{ | |||||
return m->m_ComponentManager.GetScriptInterface().StringifyJSON(&m->m_MapSettings); | |||||
} | |||||
void CSimulation2::GetMapSettings(JS::MutableHandleValue ret) | |||||
{ | |||||
ret.set(m->m_MapSettings); | |||||
} | |||||
void CSimulation2::LoadPlayerSettings(bool newPlayers) | void CSimulation2::ParsePlayerSettings(bool newPlayers) | ||||
{ | { | ||||
ScriptRequest rq(GetScriptInterface()); | ScriptRequest rq(GetScriptInterface()); | ||||
JS::RootedValue global(rq.cx, rq.globalValue()); | JS::RootedValue global(rq.cx, rq.globalValue()); | ||||
GetScriptInterface().CallFunctionVoid(global, "LoadPlayerSettings", m->m_MapSettings, newPlayers); | GetScriptInterface().CallFunctionVoid(global, "ParsePlayerSettings", m->m_InitAttributes, newPlayers); | ||||
} | } | ||||
void CSimulation2::LoadMapSettings() | void CSimulation2::ParseMapSettings() | ||||
{ | { | ||||
ScriptRequest rq(GetScriptInterface()); | ScriptRequest rq(GetScriptInterface()); | ||||
JS::RootedValue global(rq.cx, rq.globalValue()); | JS::RootedValue global(rq.cx, rq.globalValue()); | ||||
// Initialize here instead of in Update() | // Initialize here instead of in Update() | ||||
GetScriptInterface().CallFunctionVoid(global, "LoadMapSettings", m->m_MapSettings); | GetScriptInterface().CallFunctionVoid(global, "ParseMapSettings", m->m_InitAttributes); | ||||
GetScriptInterface().FreezeObject(m->m_InitAttributes, true); | GetScriptInterface().FreezeObject(m->m_InitAttributes, true); | ||||
GetScriptInterface().SetGlobal("InitAttributes", m->m_InitAttributes, true, true, true); | GetScriptInterface().SetGlobal("InitAttributes", m->m_InitAttributes, true, true, true); | ||||
if (!m->m_StartupScript.empty()) | if (!m->m_StartupScript.empty()) | ||||
GetScriptInterface().LoadScript(L"map startup script", m->m_StartupScript); | GetScriptInterface().LoadScript(L"map startup script", m->m_StartupScript); | ||||
// Load the trigger scripts after we have loaded the simulation and the map. | // Load the trigger scripts after we have loaded the simulation and the map. | ||||
m->LoadTriggerScripts(m->m_ComponentManager, m->m_MapSettings, &m->m_LoadedScripts); | m->LoadTriggerScripts(m->m_ComponentManager, m->m_InitAttributes, &m->m_LoadedScripts); | ||||
} | } | ||||
int CSimulation2::ProgressiveLoad() | int CSimulation2::ProgressiveLoad() | ||||
{ | { | ||||
return m->ProgressiveLoad(); | return m->ProgressiveLoad(); | ||||
} | } | ||||
Status CSimulation2::ReloadChangedFile(const VfsPath& path) | Status CSimulation2::ReloadChangedFile(const VfsPath& path) | ||||
▲ Show 20 Lines • Show All 132 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator