mirror of
https://github.com/antopilo/Nuake.git
synced 2026-09-15 20:08:54 +03:00
Initial infrastructure for C# scene callbacks in subsystems
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
86
Nuake/src/Core/MulticastDelegate.h
Normal file
86
Nuake/src/Core/MulticastDelegate.h
Normal 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
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "System.h"
|
||||
#include "src/Core/MulticastDelegate.h"
|
||||
|
||||
namespace Nuake {
|
||||
class Scene;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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:
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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) {}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user