Initial infrastructure for C# scene callbacks in subsystems

This commit is contained in:
WiggleWizard
2024-09-19 17:52:01 +01:00
parent 98797e15f8
commit d0c5ef1a1d
14 changed files with 190 additions and 4 deletions

View File

@@ -40,6 +40,8 @@ namespace Nuake
void Engine::Init()
{
Window::Get()->OnWindowSetScene().AddStatic(&Engine::OnWindowSetScene);
ScriptingEngineNet::Get().AddListener<ScriptingEngineNet::GameAssemblyLoadedDelegate>(&Engine::OnScriptingEngineGameAssemblyLoaded);
AudioManager::Get().Initialize();
@@ -257,6 +259,15 @@ namespace Nuake
return std::reinterpret_pointer_cast<EngineSubsystemScriptable>(subsystems[subsystemId]);
}
void Engine::OnWindowSetScene(Ref<Scene> scene)
{
if (scene != nullptr)
{
scene->OnPreInitialize().AddStatic(&Engine::OnScenePreInitialize, scene);
scene->OnPostInitialize().AddStatic(&Engine::OnScenePostInitialize, scene);
}
}
void Engine::InitializeCoreSubsystems()
{
}
@@ -296,6 +307,28 @@ namespace Nuake
}
}
void Engine::OnScenePreInitialize(Ref<Scene> scene)
{
for (auto subsystem : subsystems)
{
if (subsystem == nullptr)
continue;
subsystem->OnScenePreInitialize(scene);
}
}
void Engine::OnScenePostInitialize(Ref<Scene> scene)
{
for (auto subsystem : subsystems)
{
if (subsystem == nullptr)
continue;
subsystem->OnScenePostInitialize(scene);
}
}
bool Engine::LoadProject(Ref<Project> project)
{
currentProject = project;

View File

@@ -58,9 +58,13 @@ namespace Nuake
static Ref<EngineSubsystemScriptable> GetScriptedSubsystem(const int subsystemId);
protected:
static void OnWindowSetScene(Ref<Scene> scene);
static void InitializeCoreSubsystems();
static void OnScriptingEngineGameAssemblyLoaded();
static void OnScenePreInitialize(Ref<Scene> scene);
static void OnScenePostInitialize(Ref<Scene> scene);
private:
static Ref<Window> currentWindow;
static Ref<Project> currentProject;

View File

@@ -0,0 +1,86 @@
#pragma once
#include <functional>
#include <vector>
#include <algorithm>
#define DECLARE_MULTICAST_DELEGATE(multicastDelegateName, ...) typedef MulticastDelegate<__VA_ARGS__> multicastDelegateName;
template<typename... Args>
class MulticastDelegate
{
public:
using DelegateID = size_t;
// Add a callable with bound variables (supports no arguments as well)
template<typename Callable, typename... BoundArgs>
DelegateID AddStatic(Callable&& func, BoundArgs&&... boundArgs)
{
DelegateID id = nextID++;
auto boundFunction = [=](Args... args) {
if constexpr (sizeof...(Args) > 0)
{
func(boundArgs..., std::forward<Args>(args)...);
}
else
{
func(boundArgs...);
}
};
delegates.push_back({id, boundFunction});
return id;
}
template<typename Callable, typename Obj, typename... BoundArgs>
DelegateID AddObject(Callable&& func, Obj* object, BoundArgs&&... boundArgs)
{
DelegateID id = nextID++;
auto boundFunction = [=](Args... args) {
if constexpr (sizeof...(Args) > 0)
{
(object->*func)(boundArgs..., std::forward<Args>(args)...);
}
else
{
(object->*func)(boundArgs...);
}
};
delegates.push_back({id, boundFunction});
return id;
}
// Remove a callable using the token returned by Add()
void Remove(DelegateID id)
{
auto it = std::remove_if(delegates.begin(), delegates.end(), [id](const auto& pair)
{
return pair.first == id;
});
if (it != delegates.end())
{
delegates.erase(it, delegates.end());
}
}
// Clear all delegates
void Clear()
{
delegates.clear();
}
// Invoke all callables
void Broadcast(Args... args)
{
for (auto& [id, delegate] : delegates)
{
delegate(std::forward<Args>(args)...);
}
}
private:
using DelegatePair = std::pair<DelegateID, std::function<void(Args...)>>;
std::vector<DelegatePair> delegates; // Vector of (ID, callable) pairs
DelegateID nextID = 0; // Unique ID generator
};

View File

@@ -243,6 +243,8 @@ namespace Nuake
bool Scene::OnInit()
{
preInitializeDelegate.Broadcast();
for (auto& system : m_Systems)
{
if (!system->Init())
@@ -250,6 +252,8 @@ namespace Nuake
return false;
}
}
postInitializeDelegate.Broadcast();
return true;
}

View File

@@ -19,6 +19,9 @@ namespace Nuake
class Entity;
class SceneRenderer;
DECLARE_MULTICAST_DELEGATE(PreInitializeDelegate)
DECLARE_MULTICAST_DELEGATE(PostInitializeDelegate)
class Scene : public ISerializable
{
friend Entity;
@@ -92,6 +95,13 @@ namespace Nuake
// Component specific utilies
void CreateSkeleton(Entity& entity);
PreInitializeDelegate& OnPreInitialize() { return preInitializeDelegate; }
PostInitializeDelegate& OnPostInitialize() { return postInitializeDelegate; }
protected:
PreInitializeDelegate preInitializeDelegate;
PostInitializeDelegate postInitializeDelegate;
private:
void CreateSkeletonTraverse(Entity& entity, SkeletonNode& skeletonNode);
};

View File

@@ -18,6 +18,8 @@ namespace Nuake
{
Logger::Log("Initializing ScriptingSystem");
preInitDelegate.Broadcast();
auto& scriptingEngineNet = ScriptingEngineNet::Get();
scriptingEngineNet.Uninitialize();
scriptingEngineNet.Initialize();
@@ -70,6 +72,8 @@ namespace Nuake
}
}
postInitDelegate.Broadcast();
return true;
}

View File

@@ -1,5 +1,6 @@
#pragma once
#include "System.h"
#include "src/Core/MulticastDelegate.h"
namespace Nuake {
class Scene;

View File

@@ -1,6 +1,8 @@
#pragma once
#include "src/Core/Timestep.h"
#include "src/Core/Core.h"
#include "src/Core/MulticastDelegate.h"
namespace Nuake
{
@@ -17,5 +19,12 @@ namespace Nuake
virtual void FixedUpdate(Timestep ts) = 0;
virtual void EditorUpdate() {}
virtual void Exit() = 0;
MulticastDelegate<>& OnPreInit() { return preInitDelegate; }
MulticastDelegate<>& OnPostInit() { return postInitDelegate; }
protected:
MulticastDelegate<> preInitDelegate;
MulticastDelegate<> postInitDelegate;
};
}

View File

@@ -1,11 +1,15 @@
#pragma once
#include "src/Core/Core.h"
/**
* Specific type of subsystem that runs within the context of the engine, being created at the start of the
* engine's lifetime and destroyed just before the engine shuts down.
*/
namespace Nuake
{
class Scene;
class EngineSubsystem
{
public:
@@ -15,6 +19,9 @@ namespace Nuake
virtual void Initialize() {}
virtual void Tick(float deltaTime) {}
virtual void OnScenePreInitialize(Ref<Scene> scene) {}
virtual void OnScenePostInitialize(Ref<Scene> scene) {}
private:
bool canEverTick = false;
};

View File

@@ -29,6 +29,18 @@ void EngineSubsystemScriptable::Tick(float deltaTime)
cSharpObjectInstance.InvokeMethod("OnTick", deltaTime);
}
void EngineSubsystemScriptable::OnScenePreInitialize(Ref<Scene> scene)
{
}
void EngineSubsystemScriptable::OnScenePostInitialize(Ref<Scene> scene)
{
if (!cSharpObjectInstance.IsValid())
return;
cSharpObjectInstance.InvokeMethod("OnScenePostInitialize", scene);
}
}

View File

@@ -19,6 +19,9 @@ namespace Nuake
virtual void Initialize() override;
virtual void Tick(float deltaTime) override;
virtual void OnScenePreInitialize(Ref<Scene> scene) override;
virtual void OnScenePostInitialize(Ref<Scene> scene) override;
private:
Coral::ManagedObject cSharpObjectInstance;
};

View File

@@ -303,9 +303,12 @@ Ref<Scene> Window::GetScene()
return this->scene;
}
bool Window::SetScene(Ref<Scene> scene)
bool Window::SetScene(Ref<Scene> newScene)
{
this->scene = scene;
scene = newScene;
windowSetSceneDelegate.Broadcast(newScene);
return true;
}

View File

@@ -1,11 +1,12 @@
#pragma once
#include "Core/Core.h"
#include "Core/Maths.h"
#include "Core/MulticastDelegate.h"
#include "Core/Timestep.h"
#include <functional>
struct GLFWwindow;
namespace Nuake
@@ -13,6 +14,8 @@ namespace Nuake
class Scene;
class FrameBuffer;
DECLARE_MULTICAST_DELEGATE(OnWindowSetSceneDelegate, Ref<Scene>)
class Window
{
public:
@@ -44,7 +47,7 @@ namespace Nuake
void Center();
Ref<Scene> GetScene();
bool SetScene(Ref<Scene> scene);
bool SetScene(Ref<Scene> newScene);
void SetTitle(const std::string& title);
std::string GetTitle();
@@ -63,6 +66,8 @@ namespace Nuake
void SetOnWindowClosedCallback(std::function<void(Window& window)> callback);
void SetOnDragNDropCallback(std::function<void(Window&, const std::vector<std::string>& paths)> callback);
OnWindowSetSceneDelegate& OnWindowSetScene() { return windowSetSceneDelegate; }
private:
const std::string DEFAULT_TITLE = "Untitled Window";
const uint32_t DEFAULT_WIDTH = 1280;
@@ -85,6 +90,8 @@ namespace Nuake
void InitImgui();
OnWindowSetSceneDelegate windowSetSceneDelegate;
private:
};
}

View File

@@ -20,6 +20,9 @@
}
public virtual void Initialize() {}
public virtual void OnScenePreInit(Scene scene) {}
public virtual void OnScenePostInit(Scene scene) {}
public virtual void OnSceneUnloaded(Scene scene) {}
public virtual void OnTick(float deltaTime) {}
}
}