diff --git a/Nuake/Engine.cpp b/Nuake/Engine.cpp index 7c07d71f..6465b58e 100644 --- a/Nuake/Engine.cpp +++ b/Nuake/Engine.cpp @@ -14,14 +14,13 @@ #include "src/Threading/JobSystem.h" #include "src/Core/RegisterCoreTypes.h" #include "src/Modules/Modules.h" +#include "src/Subsystems/EngineSubsystemScriptable.h" #include #include #include #include -#include "src/Subsystems/EngineSubsystemScript.h" -#include "src/Subsystems/TickableEngineSubsystem.h" namespace Nuake @@ -97,20 +96,27 @@ namespace Nuake } } + + float scaledTimeStep = timeStep * timeScale; // Tick all subsystems - for (auto subsystem : tickableSubsystems) + if (Engine::IsPlayMode()) { - if (subsystem != nullptr) + for (auto subsystem : subsystems) { - subsystem->Tick(); + if (subsystem == nullptr) + continue; + + if (subsystem->CanEverTick()) + { + subsystem->Tick(scaledTimeStep); + } } } // Dont update if no scene is loaded. if (currentWindow->GetScene()) { - float scaledTimeStep = timeStep * timeScale; currentWindow->Update(scaledTimeStep); // Play mode update all the entities, Editor does not. @@ -136,12 +142,14 @@ namespace Nuake void Engine::EnterPlayMode() { + SetGameState(GameState::Loading); + lastFrameTime = (float)glfwGetTime(); // Reset timestep timer. // Dont trigger init if already in player mode. - if (GetGameState() == GameState::Playing) + if (GetGameState() == GameState::Playing || GetGameState() == GameState::Loading) { - Logger::Log("Cannot enter play mode if is already in play mode.", "engine", WARNING); + Logger::Log("Cannot enter play mode if is already in play mode or is loading.", "engine", WARNING); return; } @@ -155,6 +163,9 @@ namespace Nuake { Logger::Log("Cannot enter play mode. Scene OnInit failed", "engine", CRITICAL); GetCurrentScene()->OnExit(); + + // Precautionary measure + SetGameState(GameState::Stopped); } } @@ -231,7 +242,7 @@ namespace Nuake return currentProject; } - Ref Engine::GetScriptedSubsystem(const std::string& subsystemName) + Ref Engine::GetScriptedSubsystem(const std::string& subsystemName) { if (scriptedSubsystemMap.contains(subsystemName)) { @@ -240,18 +251,32 @@ namespace Nuake return nullptr; } + Ref Engine::GetScriptedSubsystem(const int subsystemId) + { + if (subsystemId >= subsystems.size()) + { + return nullptr; + } + return std::reinterpret_pointer_cast(subsystems[subsystemId]); + } + void Engine::InitializeCoreSubsystems() { } void Engine::OnScriptingEngineGameAssemblyLoaded() { + if (!Engine::IsPlayMode() && Engine::GetGameState() != GameState::Loading) + { + return; + } + subsystems.clear(); scriptedSubsystemMap.clear(); - - auto& gameAssembly = ScriptingEngineNet::Get().GetGameAssembly(); - auto scriptTypeEngineSubsystem = gameAssembly.GetType("Nuake.Net.EngineSubsystem"); + const Coral::ManagedAssembly& gameAssembly = ScriptingEngineNet::Get().GetGameAssembly(); + + const auto scriptTypeEngineSubsystem = gameAssembly.GetType("Nuake.Net.EngineSubsystem"); const auto& types = gameAssembly.GetTypes(); for (const auto& type : types) @@ -263,10 +288,13 @@ namespace Nuake Logger::Log("Creating Scripted Subsystem " + typeName); Coral::ManagedObject scriptedSubsystem = type->CreateInstance(); - Ref subsystemScript = CreateRef(scriptedSubsystem); + scriptedSubsystem.SetPropertyValue("EngineSubsystemID", subsystems.size()); + Ref subsystemScript = CreateRef(scriptedSubsystem); subsystems.push_back(subsystemScript); scriptedSubsystemMap[typeName] = subsystemScript; + + subsystemScript->Initialize(); } } } diff --git a/Nuake/Engine.h b/Nuake/Engine.h index 83072cfa..d20ca984 100644 --- a/Nuake/Engine.h +++ b/Nuake/Engine.h @@ -10,11 +10,11 @@ namespace Nuake class Project; class Scene; class EngineSubsystem; - class TickableEngineSubsystem; - class EngineSubsystemScript; + class EngineSubsystemScriptable; enum GameState { + Loading, Playing, Paused, Stopped @@ -54,7 +54,8 @@ namespace Nuake static bool LoadProject(Ref project); static Ref GetProject(); - static Ref GetScriptedSubsystem(const std::string& subsystemName); + static Ref GetScriptedSubsystem(const std::string& subsystemName); + static Ref GetScriptedSubsystem(const int subsystemId); protected: static void InitializeCoreSubsystems(); @@ -67,9 +68,7 @@ namespace Nuake static std::string queuedScene; static inline std::vector> subsystems; - static inline std::vector> tickableSubsystems; - - static inline std::unordered_map> scriptedSubsystemMap; + static inline std::unordered_map> scriptedSubsystemMap; static GameState gameState; diff --git a/Nuake/src/Scripting/NetModules/EngineNetAPI.cpp b/Nuake/src/Scripting/NetModules/EngineNetAPI.cpp index 9569aed6..551fb7eb 100644 --- a/Nuake/src/Scripting/NetModules/EngineNetAPI.cpp +++ b/Nuake/src/Scripting/NetModules/EngineNetAPI.cpp @@ -9,7 +9,7 @@ #include #include #include "Coral/Type.hpp" -#include "src/Subsystems/EngineSubsystemScript.h" +#include "..\..\Subsystems\EngineSubsystemScriptable.h" namespace Nuake { @@ -119,7 +119,7 @@ namespace Nuake { Coral::ManagedObject GetEngineSubsystemByName(Coral::String subsystemName) { - const Ref scriptedSubsystem = Engine::GetScriptedSubsystem(subsystemName); + const Ref scriptedSubsystem = Engine::GetScriptedSubsystem(subsystemName); if (scriptedSubsystem == nullptr) { return {}; diff --git a/Nuake/src/Scripting/NetModules/EngineSubsystemNetAPI.cpp b/Nuake/src/Scripting/NetModules/EngineSubsystemNetAPI.cpp new file mode 100644 index 00000000..eedc766b --- /dev/null +++ b/Nuake/src/Scripting/NetModules/EngineSubsystemNetAPI.cpp @@ -0,0 +1,37 @@ +#include "EngineSubsystemNetAPI.h" + +#include "Engine.h" +#include "src/Subsystems/EngineSubsystemScriptable.h" + +namespace Nuake +{ + void SetCanTick(int subsystemId, bool tick) + { + auto subsystem = Engine::GetScriptedSubsystem(subsystemId); + if (subsystem == nullptr) + { + Logger::Log("Subsystem isn't a valid scripted subsystem", "EngineSubsystemNetAPI", WARNING); + return; + } + + subsystem->SetCanTick(tick); + } + + bool GetCanTick(int subsystemId) + { + auto subsystem = Engine::GetScriptedSubsystem(subsystemId); + if (subsystem == nullptr) + { + Logger::Log("Subsystem isn't a valid scripted subsystem", "EngineSubsystemNetAPI", WARNING); + return false; + } + + return subsystem->CanEverTick(); + } + + void EngineSubsystemNetAPI::RegisterMethods() + { + RegisterMethod("EngineSubsystem.SetCanTickIcall", &SetCanTick); + RegisterMethod("EngineSubsystem.GetCanTickIcall", &GetCanTick); + } +} diff --git a/Nuake/src/Scripting/NetModules/EngineSubsystemNetAPI.h b/Nuake/src/Scripting/NetModules/EngineSubsystemNetAPI.h new file mode 100644 index 00000000..f827118c --- /dev/null +++ b/Nuake/src/Scripting/NetModules/EngineSubsystemNetAPI.h @@ -0,0 +1,14 @@ +#pragma once + +#include "NetAPIModule.h" + +namespace Nuake +{ + class EngineSubsystemNetAPI : public Nuake::NetAPIModule + { + public: + virtual const std::string GetModuleName() const override { return "EngineSubsystem"; } + virtual void RegisterMethods() override; + }; +} + diff --git a/Nuake/src/Scripting/ScriptingEngineNet.cpp b/Nuake/src/Scripting/ScriptingEngineNet.cpp index 080665a1..6a7d0716 100644 --- a/Nuake/src/Scripting/ScriptingEngineNet.cpp +++ b/Nuake/src/Scripting/ScriptingEngineNet.cpp @@ -8,6 +8,7 @@ #include "src/Scene/Components/NetScriptComponent.h" #include "NetModules/EngineNetAPI.h" +#include "NetModules/EngineSubsystemNetAPI.h" #include "NetModules/InputNetAPI.h" #include "NetModules/SceneNetAPI.h" #include "NetModules/UINetAPI.h" @@ -53,6 +54,7 @@ namespace Nuake modules = { CreateRef(), + CreateRef(), CreateRef(), CreateRef(), CreateRef() diff --git a/Nuake/src/Subsystems/EngineSubsystem.cpp b/Nuake/src/Subsystems/EngineSubsystem.cpp index 08b50654..d3dc51a1 100644 --- a/Nuake/src/Subsystems/EngineSubsystem.cpp +++ b/Nuake/src/Subsystems/EngineSubsystem.cpp @@ -1 +1,11 @@ #include "EngineSubsystem.h" + +void Nuake::EngineSubsystem::SetCanTick(bool canTick) +{ + canEverTick = canTick; +} + +bool Nuake::EngineSubsystem::CanEverTick() const +{ + return canEverTick; +} diff --git a/Nuake/src/Subsystems/EngineSubsystem.h b/Nuake/src/Subsystems/EngineSubsystem.h index 4b53a1ab..9dbc228c 100644 --- a/Nuake/src/Subsystems/EngineSubsystem.h +++ b/Nuake/src/Subsystems/EngineSubsystem.h @@ -9,6 +9,13 @@ namespace Nuake class EngineSubsystem { public: + void SetCanTick(bool canTick); + bool CanEverTick() const; + virtual void Initialize() {} + virtual void Tick(float deltaTime) {} + + private: + bool canEverTick = true; }; } diff --git a/Nuake/src/Subsystems/EngineSubsystemScript.cpp b/Nuake/src/Subsystems/EngineSubsystemScript.cpp deleted file mode 100644 index 6074293d..00000000 --- a/Nuake/src/Subsystems/EngineSubsystemScript.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "EngineSubsystemScript.h" - -namespace Nuake -{ - -EngineSubsystemScript::EngineSubsystemScript(const Coral::ManagedObject& object) - : cSharpObjectInstance(object) -{ - -} - -Coral::ManagedObject& EngineSubsystemScript::GetManagedObjectInstance() -{ - return cSharpObjectInstance; -} -} - - diff --git a/Nuake/src/Subsystems/EngineSubsystemScriptable.cpp b/Nuake/src/Subsystems/EngineSubsystemScriptable.cpp new file mode 100644 index 00000000..4076ae5f --- /dev/null +++ b/Nuake/src/Subsystems/EngineSubsystemScriptable.cpp @@ -0,0 +1,35 @@ +#include "EngineSubsystemScriptable.h" + +namespace Nuake +{ + +EngineSubsystemScriptable::EngineSubsystemScriptable(const Coral::ManagedObject& object) + : cSharpObjectInstance(object) +{ + +} + +Coral::ManagedObject& EngineSubsystemScriptable::GetManagedObjectInstance() +{ + return cSharpObjectInstance; +} + +void EngineSubsystemScriptable::Initialize() +{ + if (!cSharpObjectInstance.IsValid()) + return; + + cSharpObjectInstance.InvokeMethod("Initialize"); +} + +void EngineSubsystemScriptable::Tick(float deltaTime) +{ + if (!cSharpObjectInstance.IsValid()) + return; + + cSharpObjectInstance.InvokeMethod("OnTick", deltaTime); +} + +} + + diff --git a/Nuake/src/Subsystems/EngineSubsystemScript.h b/Nuake/src/Subsystems/EngineSubsystemScriptable.h similarity index 50% rename from Nuake/src/Subsystems/EngineSubsystemScript.h rename to Nuake/src/Subsystems/EngineSubsystemScriptable.h index ed52970f..69acae01 100644 --- a/Nuake/src/Subsystems/EngineSubsystemScript.h +++ b/Nuake/src/Subsystems/EngineSubsystemScriptable.h @@ -1,20 +1,24 @@ #pragma once #include "EngineSubsystem.h" -#include "Coral/ManagedObject.hpp" + +#include /** * Essentially just a wrapper for C# subsystems */ namespace Nuake { - class EngineSubsystemScript : public EngineSubsystem + class EngineSubsystemScriptable : public EngineSubsystem { public: - EngineSubsystemScript(const Coral::ManagedObject& object); + EngineSubsystemScriptable(const Coral::ManagedObject& object); Coral::ManagedObject& GetManagedObjectInstance(); + virtual void Initialize() override; + virtual void Tick(float deltaTime) override; + private: Coral::ManagedObject cSharpObjectInstance; }; diff --git a/Nuake/src/Subsystems/TickableEngineSubsystem.cpp b/Nuake/src/Subsystems/TickableEngineSubsystem.cpp deleted file mode 100644 index 32fa1396..00000000 --- a/Nuake/src/Subsystems/TickableEngineSubsystem.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "TickableEngineSubsystem.h" diff --git a/Nuake/src/Subsystems/TickableEngineSubsystem.h b/Nuake/src/Subsystems/TickableEngineSubsystem.h deleted file mode 100644 index 4482cf41..00000000 --- a/Nuake/src/Subsystems/TickableEngineSubsystem.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "EngineSubsystem.h" - -namespace Nuake -{ - class TickableEngineSubsystem : public EngineSubsystem - { - public: - virtual void Tick() {} - }; -} - diff --git a/NuakeNet/src/EngineSubsystem.cs b/NuakeNet/src/EngineSubsystem.cs index a1ffaf17..dfb2eb67 100644 --- a/NuakeNet/src/EngineSubsystem.cs +++ b/NuakeNet/src/EngineSubsystem.cs @@ -1,6 +1,25 @@ -namespace Nuake.Net; - -public class EngineSubsystem +namespace Nuake.Net { + public class EngineSubsystem + { + internal static unsafe delegate* SetCanTickIcall; + internal static unsafe delegate* GetCanTickIcall; -} \ No newline at end of file + public int EngineSubsystemID { get; protected set; } + + public bool CanTick + { + set + { + unsafe { SetCanTickIcall(EngineSubsystemID, value); } + } + get + { + unsafe { return GetCanTickIcall(EngineSubsystemID); } + } + } + + public virtual void Initialize() {} + public virtual void OnTick(float deltaTime) {} + } +} diff --git a/NuakeNet/src/EngineTickableSubsystem.cs b/NuakeNet/src/EngineTickableSubsystem.cs deleted file mode 100644 index 6a430c1c..00000000 --- a/NuakeNet/src/EngineTickableSubsystem.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Nuake.Net; - -public class EngineTickableSubsystem -{ - -} \ No newline at end of file