Skip to content

Commit 510b577

Browse files
committed
First pass scriptable subsystems that has the same lifetime of the engine
1 parent 67d7865 commit 510b577

17 files changed

+219
-6
lines changed

Nuake/Engine.cpp

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#include <imgui/imgui_impl_opengl3.h>
2121
#include <Tracy.hpp>
2222

23+
#include "src/Subsystems/EngineSubsystemScript.h"
24+
#include "src/Subsystems/TickableEngineSubsystem.h"
2325

2426

2527
namespace Nuake
@@ -39,6 +41,8 @@ namespace Nuake
3941

4042
void Engine::Init()
4143
{
44+
ScriptingEngineNet::Get().AddListener<ScriptingEngineNet::GameAssemblyLoadedDelegate>(&Engine::OnScriptingEngineGameAssemblyLoaded);
45+
4246
AudioManager::Get().Initialize();
4347
PhysicsManager::Get().Init();
4448
NavManager::Get().Initialize();
@@ -53,6 +57,8 @@ namespace Nuake
5357
RegisterCoreTypes::RegisterCoreComponents();
5458

5559
Modules::StartupModules();
60+
61+
InitializeCoreSubsystems();
5662
}
5763

5864
void Engine::Tick()
@@ -92,6 +98,15 @@ namespace Nuake
9298
}
9399
}
94100

101+
// Tick all subsystems
102+
for (auto subsystem : tickableSubsystems)
103+
{
104+
if (subsystem != nullptr)
105+
{
106+
subsystem->Tick();
107+
}
108+
}
109+
95110
// Dont update if no scene is loaded.
96111
if (currentWindow->GetScene())
97112
{
@@ -216,6 +231,46 @@ namespace Nuake
216231
return currentProject;
217232
}
218233

234+
Ref<EngineSubsystemScript> Engine::GetScriptedSubsystem(const std::string& subsystemName)
235+
{
236+
if (scriptedSubsystemMap.contains(subsystemName))
237+
{
238+
return scriptedSubsystemMap[subsystemName];
239+
}
240+
return nullptr;
241+
}
242+
243+
void Engine::InitializeCoreSubsystems()
244+
{
245+
}
246+
247+
void Engine::OnScriptingEngineGameAssemblyLoaded()
248+
{
249+
subsystems.clear();
250+
scriptedSubsystemMap.clear();
251+
252+
auto& gameAssembly = ScriptingEngineNet::Get().GetGameAssembly();
253+
254+
auto scriptTypeEngineSubsystem = gameAssembly.GetType("Nuake.Net.EngineSubsystem");
255+
256+
const auto& types = gameAssembly.GetTypes();
257+
for (const auto& type : types)
258+
{
259+
// Initialize all subsystems
260+
if (type->IsSubclassOf(scriptTypeEngineSubsystem))
261+
{
262+
const std::string typeName = std::string(type->GetFullName());
263+
Logger::Log("Creating Scripted Subsystem " + typeName);
264+
265+
Coral::ManagedObject scriptedSubsystem = type->CreateInstance();
266+
Ref<EngineSubsystemScript> subsystemScript = CreateRef<EngineSubsystemScript>(scriptedSubsystem);
267+
subsystems.push_back(subsystemScript);
268+
269+
scriptedSubsystemMap[typeName] = subsystemScript;
270+
}
271+
}
272+
}
273+
219274
bool Engine::LoadProject(Ref<Project> project)
220275
{
221276
currentProject = project;
@@ -236,4 +291,4 @@ namespace Nuake
236291
{
237292
return currentWindow;
238293
}
239-
}
294+
}

Nuake/Engine.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#pragma once
2+
23
#include "src/Core/Core.h"
34
#include "src/Core/Logger.h"
45
#include "src/Window.h"
@@ -8,6 +9,9 @@ namespace Nuake
89
{
910
class Project;
1011
class Scene;
12+
class EngineSubsystem;
13+
class TickableEngineSubsystem;
14+
class EngineSubsystemScript;
1115

1216
enum GameState
1317
{
@@ -50,12 +54,23 @@ namespace Nuake
5054
static bool LoadProject(Ref<Project> project);
5155
static Ref<Project> GetProject();
5256

57+
static Ref<EngineSubsystemScript> GetScriptedSubsystem(const std::string& subsystemName);
58+
59+
protected:
60+
static void InitializeCoreSubsystems();
61+
static void OnScriptingEngineGameAssemblyLoaded();
62+
5363
private:
5464
static Ref<Window> currentWindow;
5565
static Ref<Project> currentProject;
5666
static Ref<Scene> currentScene;
5767
static std::string queuedScene;
5868

69+
static inline std::vector<Ref<EngineSubsystem>> subsystems;
70+
static inline std::vector<Ref<TickableEngineSubsystem>> tickableSubsystems;
71+
72+
static inline std::unordered_map<std::string, Ref<EngineSubsystemScript>> scriptedSubsystemMap;
73+
5974
static GameState gameState;
6075

6176
static float lastFrameTime;

Nuake/src/Scripting/NetModules/EngineNetAPI.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
#include "EngineNetAPI.h"
2-
#include <Coral/String.hpp>
3-
#include <src/Core/Maths.h>
4-
#include <Engine.h>
2+
3+
#include "src/Core/Maths.h"
54
#include "src/Rendering/SceneRenderer.h"
5+
#include "Engine.h"
6+
#include "src/Physics/PhysicsManager.h"
7+
8+
#include <Coral/String.hpp>
9+
#include <Coral/ManagedObject.hpp>
610
#include <Coral/Array.hpp>
7-
#include <src/Physics/PhysicsManager.h>
11+
#include "Coral/Type.hpp"
12+
#include "src/Subsystems/EngineSubsystemScript.h"
813

914
namespace Nuake {
1015

@@ -112,10 +117,22 @@ namespace Nuake {
112117
Engine::QueueSceneSwitch(std::string(path));
113118
}
114119

120+
Coral::ManagedObject GetEngineSubsystemByName(Coral::String subsystemName)
121+
{
122+
const Ref<EngineSubsystemScript> scriptedSubsystem = Engine::GetScriptedSubsystem(subsystemName);
123+
if (scriptedSubsystem == nullptr)
124+
{
125+
return {};
126+
}
127+
128+
return scriptedSubsystem->GetManagedObjectInstance();
129+
}
130+
115131
void EngineNetAPI::RegisterMethods()
116132
{
117133
RegisterMethod("Engine.LoadSceneIcall", &LoadScene);
118134
RegisterMethod("Engine.LoggerLogIcall", (void*)(&Log));
135+
RegisterMethod("Engine.GetSubsystemByNameIcall", &GetEngineSubsystemByName);
119136

120137
// Debug renderer
121138
RegisterMethod("Debug.DrawLineIcall", &DrawLine);

Nuake/src/Scripting/ScriptingEngineNet.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,15 @@ namespace Nuake
324324
return widgetUUIDToManagedObjects[std::make_pair(canvasUUID, uuid)];
325325
}
326326

327+
template<class T>
328+
void ScriptingEngineNet::AddListener(const T& delegate) {}
329+
330+
template <>
331+
void ScriptingEngineNet::AddListener<ScriptingEngineNet::GameAssemblyLoadedDelegate>(const GameAssemblyLoadedDelegate& delegate)
332+
{
333+
listenersGameAssemblyLoaded.push_back(delegate);
334+
}
335+
327336
std::vector<CompilationError> ScriptingEngineNet::BuildProjectAssembly(Ref<Project> project)
328337
{
329338
const std::string sanitizedProjectName = String::Sanitize(project->Name);
@@ -525,6 +534,11 @@ namespace Nuake
525534
}
526535
}
527536
}
537+
538+
for (auto& delegate : listenersGameAssemblyLoaded)
539+
{
540+
delegate();
541+
}
528542
}
529543
}
530544

Nuake/src/Scripting/ScriptingEngineNet.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ namespace Nuake
7373

7474
class ScriptingEngineNet
7575
{
76+
public:
77+
using GameAssemblyLoadedDelegate = std::function<void()>;
78+
7679
public:
7780
static ScriptingEngineNet& Get();
7881

@@ -83,6 +86,7 @@ namespace Nuake
8386
Coral::HostInstance* GetHostInstance() { return hostInstance; }
8487
Coral::AssemblyLoadContext& GetLoadContext() { return loadContext; }
8588
Coral::ManagedAssembly GetNuakeAssembly() const { return nuakeAssembly; }
89+
Coral::ManagedAssembly& GetGameAssembly() { return gameAssembly; }
8690

8791
Coral::ManagedAssembly ReloadEngineAPI(Coral::AssemblyLoadContext & context);
8892

@@ -110,6 +114,9 @@ namespace Nuake
110114
std::unordered_map<std::string, NetGameScriptObject> GetPointEntities() const { return pointEntityTypes; }
111115
std::unordered_map<std::string, UIWidgetObject> GetUIWidgets() const { return uiWidgets; }
112116

117+
template<class T> void AddListener(const T& delegate);
118+
template<> void AddListener(const GameAssemblyLoadedDelegate& delegate);
119+
113120
private:
114121
const std::string m_Scope = "Nuake.Net";
115122
const std::string m_EngineAssemblyName = "NuakeNet.dll";
@@ -140,6 +147,8 @@ namespace Nuake
140147

141148
std::unordered_map<uint32_t, Coral::ManagedObject> entityToManagedObjects;
142149
std::map<std::pair<UUID, UUID>, Coral::ManagedObject> widgetUUIDToManagedObjects;
150+
151+
std::vector<GameAssemblyLoadedDelegate> listenersGameAssemblyLoaded;
143152

144153
ScriptingEngineNet();
145154
~ScriptingEngineNet();
@@ -148,4 +157,4 @@ namespace Nuake
148157
std::string GenerateGUID();
149158
std::vector<CompilationError> ExtractErrors(const std::string& input);
150159
};
151-
}
160+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#include "EngineSubsystem.h"
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#pragma once
2+
3+
/**
4+
* Specific type of subsystem that runs within the context of the engine, being created at the start of the
5+
* engine's lifetime and destroyed just before the engine shuts down.
6+
*/
7+
namespace Nuake
8+
{
9+
class EngineSubsystem
10+
{
11+
public:
12+
13+
};
14+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#include "EngineSubsystemScript.h"
2+
3+
namespace Nuake
4+
{
5+
6+
EngineSubsystemScript::EngineSubsystemScript(const Coral::ManagedObject& object)
7+
: cSharpObjectInstance(object)
8+
{
9+
10+
}
11+
12+
Coral::ManagedObject& EngineSubsystemScript::GetManagedObjectInstance()
13+
{
14+
return cSharpObjectInstance;
15+
}
16+
}
17+
18+
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#pragma once
2+
3+
#include "EngineSubsystem.h"
4+
#include "Coral/ManagedObject.hpp"
5+
6+
/**
7+
* Essentially just a wrapper for C# subsystems
8+
*/
9+
namespace Nuake
10+
{
11+
class EngineSubsystemScript : public EngineSubsystem
12+
{
13+
public:
14+
EngineSubsystemScript(const Coral::ManagedObject& object);
15+
16+
Coral::ManagedObject& GetManagedObjectInstance();
17+
18+
private:
19+
Coral::ManagedObject cSharpObjectInstance;
20+
};
21+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#include "SceneSubsystem.h"

0 commit comments

Comments
 (0)