Add script runtime lifecycle skeleton
This commit is contained in:
52
engine/include/XCEngine/Scripting/IScriptRuntime.h
Normal file
52
engine/include/XCEngine/Scripting/IScriptRuntime.h
Normal file
@@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace XCEngine {
|
||||
|
||||
namespace Components {
|
||||
class GameObject;
|
||||
class Scene;
|
||||
}
|
||||
|
||||
namespace Scripting {
|
||||
|
||||
class ScriptComponent;
|
||||
|
||||
enum class ScriptLifecycleMethod {
|
||||
Awake = 0,
|
||||
OnEnable,
|
||||
Start,
|
||||
FixedUpdate,
|
||||
Update,
|
||||
LateUpdate,
|
||||
OnDisable,
|
||||
OnDestroy
|
||||
};
|
||||
|
||||
struct ScriptRuntimeContext {
|
||||
Components::Scene* scene = nullptr;
|
||||
Components::GameObject* gameObject = nullptr;
|
||||
ScriptComponent* component = nullptr;
|
||||
uint64_t gameObjectUUID = 0;
|
||||
uint64_t scriptComponentUUID = 0;
|
||||
};
|
||||
|
||||
class IScriptRuntime {
|
||||
public:
|
||||
virtual ~IScriptRuntime() = default;
|
||||
|
||||
virtual void OnRuntimeStart(Components::Scene* scene) = 0;
|
||||
virtual void OnRuntimeStop(Components::Scene* scene) = 0;
|
||||
|
||||
virtual bool CreateScriptInstance(const ScriptRuntimeContext& context) = 0;
|
||||
virtual void DestroyScriptInstance(const ScriptRuntimeContext& context) = 0;
|
||||
|
||||
virtual void InvokeMethod(
|
||||
const ScriptRuntimeContext& context,
|
||||
ScriptLifecycleMethod method,
|
||||
float deltaTime) = 0;
|
||||
};
|
||||
|
||||
} // namespace Scripting
|
||||
} // namespace XCEngine
|
||||
23
engine/include/XCEngine/Scripting/NullScriptRuntime.h
Normal file
23
engine/include/XCEngine/Scripting/NullScriptRuntime.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Scripting/IScriptRuntime.h>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Scripting {
|
||||
|
||||
class NullScriptRuntime : public IScriptRuntime {
|
||||
public:
|
||||
void OnRuntimeStart(Components::Scene* scene) override;
|
||||
void OnRuntimeStop(Components::Scene* scene) override;
|
||||
|
||||
bool CreateScriptInstance(const ScriptRuntimeContext& context) override;
|
||||
void DestroyScriptInstance(const ScriptRuntimeContext& context) override;
|
||||
|
||||
void InvokeMethod(
|
||||
const ScriptRuntimeContext& context,
|
||||
ScriptLifecycleMethod method,
|
||||
float deltaTime) override;
|
||||
};
|
||||
|
||||
} // namespace Scripting
|
||||
} // namespace XCEngine
|
||||
@@ -36,6 +36,10 @@ public:
|
||||
const ScriptFieldStorage& GetFieldStorage() const { return m_fieldStorage; }
|
||||
void SetFieldStorage(const ScriptFieldStorage& fieldStorage) { m_fieldStorage = fieldStorage; }
|
||||
|
||||
void OnEnable() override;
|
||||
void OnDisable() override;
|
||||
void OnDestroy() override;
|
||||
|
||||
void Serialize(std::ostream& os) const override;
|
||||
void Deserialize(std::istream& is) override;
|
||||
|
||||
|
||||
88
engine/include/XCEngine/Scripting/ScriptEngine.h
Normal file
88
engine/include/XCEngine/Scripting/ScriptEngine.h
Normal file
@@ -0,0 +1,88 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Scripting/IScriptRuntime.h>
|
||||
#include <XCEngine/Scripting/NullScriptRuntime.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Scripting {
|
||||
|
||||
class ScriptComponent;
|
||||
|
||||
class ScriptEngine {
|
||||
public:
|
||||
static ScriptEngine& Get();
|
||||
|
||||
void SetRuntime(IScriptRuntime* runtime);
|
||||
IScriptRuntime* GetRuntime() const { return m_runtime; }
|
||||
|
||||
void OnRuntimeStart(Components::Scene* scene);
|
||||
void OnRuntimeStop();
|
||||
|
||||
void OnFixedUpdate(float fixedDeltaTime);
|
||||
void OnUpdate(float deltaTime);
|
||||
void OnLateUpdate(float deltaTime);
|
||||
|
||||
void OnScriptComponentEnabled(ScriptComponent* component);
|
||||
void OnScriptComponentDisabled(ScriptComponent* component);
|
||||
void OnScriptComponentDestroyed(ScriptComponent* component);
|
||||
|
||||
bool IsRuntimeRunning() const { return m_runtimeRunning; }
|
||||
Components::Scene* GetRuntimeScene() const { return m_runtimeScene; }
|
||||
|
||||
bool HasTrackedScriptComponent(const ScriptComponent* component) const;
|
||||
bool HasRuntimeInstance(const ScriptComponent* component) const;
|
||||
size_t GetTrackedScriptCount() const { return m_scriptOrder.size(); }
|
||||
|
||||
private:
|
||||
struct ScriptInstanceKey {
|
||||
uint64_t gameObjectUUID = 0;
|
||||
uint64_t scriptComponentUUID = 0;
|
||||
|
||||
bool operator==(const ScriptInstanceKey& other) const {
|
||||
return gameObjectUUID == other.gameObjectUUID
|
||||
&& scriptComponentUUID == other.scriptComponentUUID;
|
||||
}
|
||||
};
|
||||
|
||||
struct ScriptInstanceKeyHasher {
|
||||
size_t operator()(const ScriptInstanceKey& key) const;
|
||||
};
|
||||
|
||||
struct ScriptInstanceState {
|
||||
ScriptRuntimeContext context;
|
||||
bool instanceCreated = false;
|
||||
bool awakeCalled = false;
|
||||
bool enabled = false;
|
||||
bool startCalled = false;
|
||||
bool startPending = false;
|
||||
};
|
||||
|
||||
ScriptEngine() = default;
|
||||
|
||||
void CollectScriptComponents(Components::GameObject* gameObject);
|
||||
ScriptInstanceState* TrackScriptComponent(ScriptComponent* component);
|
||||
ScriptInstanceState* FindState(const ScriptComponent* component);
|
||||
const ScriptInstanceState* FindState(const ScriptComponent* component) const;
|
||||
void RemoveTrackedScriptComponent(const ScriptComponent* component);
|
||||
|
||||
bool ShouldScriptRun(const ScriptInstanceState& state) const;
|
||||
bool EnsureScriptReady(ScriptInstanceState& state, bool invokeEnableIfNeeded);
|
||||
void InvokeLifecycleMethod(ScriptInstanceState& state, ScriptLifecycleMethod method, float deltaTime = 0.0f);
|
||||
void StopTrackingScript(ScriptInstanceState& state, bool runtimeStopping);
|
||||
|
||||
NullScriptRuntime m_nullRuntime;
|
||||
IScriptRuntime* m_runtime = &m_nullRuntime;
|
||||
Components::Scene* m_runtimeScene = nullptr;
|
||||
bool m_runtimeRunning = false;
|
||||
|
||||
std::unordered_map<ScriptInstanceKey, ScriptInstanceState, ScriptInstanceKeyHasher> m_scriptStates;
|
||||
std::vector<ScriptInstanceKey> m_scriptOrder;
|
||||
};
|
||||
|
||||
} // namespace Scripting
|
||||
} // namespace XCEngine
|
||||
Reference in New Issue
Block a user