mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 21:01:52 +00:00
Start and Stop script runtime for editor scene
This commit is contained in:
@@ -864,6 +864,8 @@ namespace GlitchyEditor
|
|||||||
/// Starts the play mode for the current scene
|
/// Starts the play mode for the current scene
|
||||||
private void OnScenePlay()
|
private void OnScenePlay()
|
||||||
{
|
{
|
||||||
|
// TODO: Dictionary<UUID, ScriptData> scriptData = _editorScene.SerializeScripts();
|
||||||
|
|
||||||
_editor.SceneViewportWindow.EditorMode = false;
|
_editor.SceneViewportWindow.EditorMode = false;
|
||||||
_sceneState = .Play;
|
_sceneState = .Play;
|
||||||
|
|
||||||
@@ -871,9 +873,9 @@ namespace GlitchyEditor
|
|||||||
{
|
{
|
||||||
_editorScene.CopyTo(runtimeScene, true);
|
_editorScene.CopyTo(runtimeScene, true);
|
||||||
|
|
||||||
runtimeScene.OnRuntimeStart();
|
SetActiveScene(runtimeScene, startRuntime: true, startSimulation: true);
|
||||||
|
|
||||||
SetReference!(_activeScene, runtimeScene);
|
// TODO: runtimeScene.DeserializeScripts(scriptData);
|
||||||
}
|
}
|
||||||
|
|
||||||
_editor.CurrentScene = _activeScene;
|
_editor.CurrentScene = _activeScene;
|
||||||
@@ -882,6 +884,27 @@ namespace GlitchyEditor
|
|||||||
SwitchToPlayWindow();
|
SwitchToPlayWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Activates the given scene.
|
||||||
|
/// @param scene The scene to be activated.
|
||||||
|
/// @param startRuntime If set to true, the script runtime will be initialized for the given scene.
|
||||||
|
/// @param startSimulation If set to true, the physics simulation will be initialized for the given scene.
|
||||||
|
private void SetActiveScene(Scene scene, bool startRuntime, bool startSimulation)
|
||||||
|
{
|
||||||
|
_activeScene?.StopRuntime();
|
||||||
|
_activeScene?.StopSimulation();
|
||||||
|
|
||||||
|
if (scene != null)
|
||||||
|
{
|
||||||
|
if (startRuntime)
|
||||||
|
scene.StartRuntime();
|
||||||
|
|
||||||
|
if (startSimulation)
|
||||||
|
scene.StartSimulation();
|
||||||
|
}
|
||||||
|
|
||||||
|
SetReference!(_activeScene, scene);
|
||||||
|
}
|
||||||
|
|
||||||
/// Starts the physics simulation mode for the current scene
|
/// Starts the physics simulation mode for the current scene
|
||||||
private void OnSceneSimulate()
|
private void OnSceneSimulate()
|
||||||
{
|
{
|
||||||
@@ -892,9 +915,7 @@ namespace GlitchyEditor
|
|||||||
{
|
{
|
||||||
_editorScene.CopyTo(simulationScene, false);
|
_editorScene.CopyTo(simulationScene, false);
|
||||||
|
|
||||||
simulationScene.OnSimulationStart();
|
SetActiveScene(simulationScene, startRuntime: false, startSimulation: true);
|
||||||
|
|
||||||
SetReference!(_activeScene, simulationScene);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_editor.CurrentScene = _activeScene;
|
_editor.CurrentScene = _activeScene;
|
||||||
@@ -930,12 +951,9 @@ namespace GlitchyEditor
|
|||||||
/// Stops the simulation or game and returns to edit mode.
|
/// Stops the simulation or game and returns to edit mode.
|
||||||
private void OnSceneStop()
|
private void OnSceneStop()
|
||||||
{
|
{
|
||||||
if (_sceneState == .Play)
|
SetActiveScene(_editorScene, startRuntime: true, startSimulation: false);
|
||||||
_activeScene.OnRuntimeStop();
|
|
||||||
else if (_sceneState == .Simulate)
|
|
||||||
_activeScene.OnSimulationStop();
|
|
||||||
|
|
||||||
SetReference!(_activeScene, _editorScene);
|
// TODO: _editorScene.DeserializeScripts(scriptData);
|
||||||
|
|
||||||
_editor.SceneViewportWindow.EditorMode = true;
|
_editor.SceneViewportWindow.EditorMode = true;
|
||||||
_sceneState = .Edit;
|
_sceneState = .Edit;
|
||||||
@@ -985,9 +1003,19 @@ namespace GlitchyEditor
|
|||||||
/// Sets the current editor scene
|
/// Sets the current editor scene
|
||||||
private void SetEditorScene(Scene scene)
|
private void SetEditorScene(Scene scene)
|
||||||
{
|
{
|
||||||
|
if (_editorScene != null)
|
||||||
|
{
|
||||||
|
_editorScene.StopRuntime();
|
||||||
|
}
|
||||||
|
|
||||||
SetReference!(_editorScene, scene);
|
SetReference!(_editorScene, scene);
|
||||||
_editor.CurrentScene = _editorScene;
|
_editor.CurrentScene = _editorScene;
|
||||||
SetReference!(_activeScene, _editorScene);
|
SetReference!(_activeScene, _editorScene);
|
||||||
|
|
||||||
|
if (_editorScene != null)
|
||||||
|
{
|
||||||
|
_editorScene.StartRuntime();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new default scene.
|
/// Creates a new default scene.
|
||||||
|
|||||||
@@ -83,7 +83,12 @@ static class ScriptEngine
|
|||||||
public static Dictionary<StringView, ScriptClass> EntityClasses => _entityScripts;
|
public static Dictionary<StringView, ScriptClass> EntityClasses => _entityScripts;
|
||||||
public static Dictionary<StringView, ScriptClass> ComponentClasses => _componentClasses;
|
public static Dictionary<StringView, ScriptClass> ComponentClasses => _componentClasses;
|
||||||
|
|
||||||
public static Scene Context => s_Context;
|
/// Gets or sets the current scene context for the runtime.
|
||||||
|
public static Scene Context
|
||||||
|
{
|
||||||
|
get => s_Context;
|
||||||
|
private set => SetReference!(s_Context, value);
|
||||||
|
}
|
||||||
|
|
||||||
private static Dictionary<UUID, ScriptFieldMap> _entityFields = new .() ~
|
private static Dictionary<UUID, ScriptFieldMap> _entityFields = new .() ~
|
||||||
{
|
{
|
||||||
@@ -246,20 +251,38 @@ static class ScriptEngine
|
|||||||
InitAssemblyWatcher();
|
InitAssemblyWatcher();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SetContext(Scene scene)
|
/// Starts the script runtime and sets the context scene.
|
||||||
|
public static void StartRuntime(Scene context)
|
||||||
{
|
{
|
||||||
SetReference!(s_Context, scene);
|
/// At the moment only set the context.
|
||||||
|
|
||||||
|
Debug.Assert(s_Context == null, "StartRuntime was called twice without StopRuntime in between!");
|
||||||
|
Context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void OnRuntimeStop()
|
/// Stopts the script runtime and disposes of all script instances.
|
||||||
|
public static void StopRuntime()
|
||||||
{
|
{
|
||||||
for (var entry in _entityScriptInstances)
|
if (Context == null)
|
||||||
{
|
{
|
||||||
entry.value?.ReleaseRef();
|
// There should be nothing to do, if we have no context
|
||||||
|
Debug.Assert(_entityScriptInstances.Count == 0, "There are script instances but no context scene.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let (id, instance) in _entityScriptInstances)
|
||||||
|
{
|
||||||
|
instance?.ReleaseRef();
|
||||||
|
|
||||||
|
Entity entity = Context.GetEntityByID(id);
|
||||||
|
|
||||||
|
// Remove Instance from script
|
||||||
|
ScriptComponent* script = entity.GetComponent<ScriptComponent>();
|
||||||
|
script.Instance = null;
|
||||||
}
|
}
|
||||||
_entityScriptInstances.Clear();
|
_entityScriptInstances.Clear();
|
||||||
|
|
||||||
SetContext(null);
|
Context = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool InitializeInstance(Entity entity, ScriptComponent* script)
|
public static bool InitializeInstance(Entity entity, ScriptComponent* script)
|
||||||
|
|||||||
@@ -104,8 +104,11 @@ namespace GlitchyEngine.World
|
|||||||
|
|
||||||
/// Copies all entities with their components to the given target-scene.
|
/// Copies all entities with their components to the given target-scene.
|
||||||
/// @param target The scene that the entities are copied to.
|
/// @param target The scene that the entities are copied to.
|
||||||
/// @param initializeScripts If true script instances will be initialized.
|
/// @param copyScripts If true script components will be copied.
|
||||||
public void CopyTo(Scene target, bool initializeScripts)
|
/// This is for simulation mode, where the script-components won't be executing, thus we don't copy them.
|
||||||
|
/// TODO: But in reality we still might want to have scripts, because the user might want to run some code, just not OnCreate/OnUpdate?
|
||||||
|
/// TODO: Honestly, I'm not quite sure what simulation mode is actually good for. Maybe we better just remove it?
|
||||||
|
public void CopyTo(Scene target, bool copyScripts)
|
||||||
{
|
{
|
||||||
// Copy entities
|
// Copy entities
|
||||||
for (let sourceHandle in _ecsWorld.Enumerate())
|
for (let sourceHandle in _ecsWorld.Enumerate())
|
||||||
@@ -125,43 +128,21 @@ namespace GlitchyEngine.World
|
|||||||
CopyComponents<CameraComponent>(this, target);
|
CopyComponents<CameraComponent>(this, target);
|
||||||
CopyComponents<LightComponent>(this, target);
|
CopyComponents<LightComponent>(this, target);
|
||||||
|
|
||||||
|
|
||||||
CopyComponents<Rigidbody2DComponent>(this, target);
|
CopyComponents<Rigidbody2DComponent>(this, target);
|
||||||
CopyComponents<BoxCollider2DComponent>(this, target);
|
CopyComponents<BoxCollider2DComponent>(this, target);
|
||||||
CopyComponents<CircleCollider2DComponent>(this, target);
|
CopyComponents<CircleCollider2DComponent>(this, target);
|
||||||
CopyComponents<PolygonCollider2DComponent>(this, target);
|
CopyComponents<PolygonCollider2DComponent>(this, target);
|
||||||
|
|
||||||
if (initializeScripts)
|
if (copyScripts)
|
||||||
{
|
{
|
||||||
// Set context, so that constructors can correctly reference the scene
|
for (let (sourceHandle, sourceScript) in _ecsWorld.Enumerate<ScriptComponent>())
|
||||||
ScriptEngine.SetContext(target);
|
|
||||||
|
|
||||||
//CopyComponents<NativeScriptComponent>(this, target);
|
|
||||||
|
|
||||||
// Copy ScriptComponents... needs extra handling for the script instances
|
|
||||||
for (let (sourceHandle, sourceComponent) in _ecsWorld.Enumerate<ScriptComponent>())
|
|
||||||
{
|
{
|
||||||
Entity sourceEntity = .(sourceHandle, this);
|
Entity sourceEntity = .(sourceHandle, target);
|
||||||
|
|
||||||
Entity targetEntity = target.GetEntityByID(sourceEntity.UUID);
|
Entity targetEntity = target.GetEntityByID(sourceEntity.UUID);
|
||||||
ScriptComponent* targetComponent = targetEntity.AddComponent<ScriptComponent>();
|
ScriptComponent* targetScript = targetEntity.AddComponent<ScriptComponent>();
|
||||||
|
|
||||||
targetComponent.ScriptClassName = sourceComponent.ScriptClassName;
|
targetScript.ScriptClassName = sourceScript.ScriptClassName;
|
||||||
|
|
||||||
// Initializes the created instance
|
|
||||||
// TODO: this returns false, if no script with ScriptClassName exists, we have to handle this case correctly I think.
|
|
||||||
ScriptEngine.InitializeInstance(targetEntity, targetComponent);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy values to entities.
|
|
||||||
// We do this in a separate loop because we might reference other entities.
|
|
||||||
// If we did it in a single loop these entities might not exist yet.
|
|
||||||
for (let (handle, script) in target._ecsWorld.Enumerate<ScriptComponent>())
|
|
||||||
{
|
|
||||||
Entity entity = .(handle, this);
|
|
||||||
|
|
||||||
if (script.Instance != null)
|
|
||||||
ScriptEngine.CopyEditorFieldsToInstance(entity, script);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,21 +202,36 @@ namespace GlitchyEngine.World
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnRuntimeStart()
|
public void Start(bool simulation, bool runtime)
|
||||||
{
|
{
|
||||||
OnSimulationStart();
|
if (simulation)
|
||||||
SetupPhysicsCallbacks();
|
StartSimulation();
|
||||||
ScriptEngine.SetContext(this);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnRuntimeStop()
|
public void StartRuntime()
|
||||||
{
|
{
|
||||||
OnSimulationStop();
|
ScriptEngine.StartRuntime(this);
|
||||||
ScriptEngine.OnRuntimeStop();
|
|
||||||
|
// Initialize ScriptComponents
|
||||||
|
for (let (handle, scriptComponent) in _ecsWorld.Enumerate<ScriptComponent>())
|
||||||
|
{
|
||||||
|
Entity entity = .(handle, this);
|
||||||
|
// TODO: this returns false, if no script with ScriptClassName exists, we have to handle this case correctly
|
||||||
|
ScriptEngine.InitializeInstance(entity, scriptComponent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnSimulationStart()
|
public void StopRuntime()
|
||||||
{
|
{
|
||||||
|
ScriptEngine.StopRuntime();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StartSimulation()
|
||||||
|
{
|
||||||
|
// TODO: Add Setting for the user to define whether Physics will be initialized or not?
|
||||||
|
|
||||||
_physicsWorld2D = World.Create(_gravity2D);
|
_physicsWorld2D = World.Create(_gravity2D);
|
||||||
|
|
||||||
draw.drawPolygonCallback = (vertices, vertexCount, color, userData) =>
|
draw.drawPolygonCallback = (vertices, vertexCount, color, userData) =>
|
||||||
@@ -289,6 +285,8 @@ namespace GlitchyEngine.World
|
|||||||
World.SetDebugDrawFlags(_physicsWorld2D, .e_shapeBit);
|
World.SetDebugDrawFlags(_physicsWorld2D, .e_shapeBit);
|
||||||
|
|
||||||
InitPhysics2D();
|
InitPhysics2D();
|
||||||
|
|
||||||
|
SetupPhysicsCallbacks();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetupPhysicsCallbacks()
|
private void SetupPhysicsCallbacks()
|
||||||
@@ -590,10 +588,15 @@ namespace GlitchyEngine.World
|
|||||||
polygonCollider.RuntimeFixture = fixture;
|
polygonCollider.RuntimeFixture = fixture;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnSimulationStop()
|
public void StopSimulation()
|
||||||
{
|
{
|
||||||
|
if (_physicsWorld2D == null)
|
||||||
|
return;
|
||||||
|
|
||||||
Box2D.World.Delete(_physicsWorld2D);
|
Box2D.World.Delete(_physicsWorld2D);
|
||||||
_physicsWorld2D = null;
|
_physicsWorld2D = null;
|
||||||
|
|
||||||
|
// TODO: Get rid of all references to colliders, etc. in physics components.
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum UpdateMode
|
public enum UpdateMode
|
||||||
|
|||||||
Reference in New Issue
Block a user