Prechádzať zdrojové kódy

IsPlaying/IsPaused/FrameStep interface exposed to API
Separated elapsed time into "real" and "pausable" for managed code

BearishSun 10 rokov pred
rodič
commit
e92ee3b052

+ 40 - 0
MBansheeEditor/EditorApplication.cs

@@ -90,6 +90,27 @@ namespace BansheeEditor
         /// </summary>
         public static bool IsProjectLoaded { get { return Internal_GetProjectLoaded(); } }
 
+        /// <summary>
+        /// Determines is the game currently running in the editor, or is it stopped or paused. Setting this value to false
+        /// will stop the game, but if you just want to pause it use <see cref="IsPaused"/> property.
+        /// </summary>
+        public static bool IsPlaying
+        {
+            get { return Internal_GetIsPlaying(); }
+            set { Internal_SetIsPlaying(value); }
+        }
+
+        /// <summary>
+        /// Determines if the game is currently running in the editor, but paused. If the game is stopped and not running
+        /// this will return false. If the game is not running and this is enabled, the game will start running but be 
+        /// immediately paused.
+        /// </summary>
+        public static bool IsPaused
+        {
+            get { return Internal_GetIsPaused(); }
+            set { Internal_SetIsPaused(value); }
+        }
+
         /// <summary>
         /// Returns the path where the script compiler is located at.
         /// </summary>
@@ -581,6 +602,14 @@ namespace BansheeEditor
             return sceneDirty;
         }
 
+        /// <summary>
+        /// Runs a single frame of the game and pauses it. If the game is not currently running it will be started.
+        /// </summary>
+        public static void FrameStep()
+        {
+            Internal_FrameStep();
+        }
+
         /// <summary>
         /// Executes any editor-specific unit tests. This should be called after a project is loaded if possible.
         /// </summary>
@@ -736,5 +765,16 @@ namespace BansheeEditor
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_ToggleToolbarItem(string name, bool on);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_GetIsPlaying();
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetIsPlaying(bool value);
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_GetIsPaused();
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetIsPaused(bool value);
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_FrameStep();
     }
 }

+ 7 - 4
MBansheeEditor/GameWindow.cs

@@ -5,7 +5,7 @@ namespace BansheeEditor
     /// <summary>
     /// Displays in-game viewport in the editor.
     /// </summary>
-    public class GameWindow : EditorWindow // TODO - Dummy class, unfinished
+    public class GameWindow : EditorWindow
     {
         /// <summary>
         /// Opens the game window.
@@ -23,7 +23,10 @@ namespace BansheeEditor
         [ToolbarItem("Play", ToolbarIcon.Play, "", 1800, true)]
         private static void Play()
         {
-            // TODO - Not implemented
+            if (EditorApplication.IsPaused)
+                EditorApplication.IsPaused = false;
+            else
+                EditorApplication.IsPlaying = !EditorApplication.IsPlaying;
         }
 
         /// <summary>
@@ -33,7 +36,7 @@ namespace BansheeEditor
         [ToolbarItem("Pause", ToolbarIcon.Pause, "", 1799)]
         private static void Pause()
         {
-            // TODO - Not implemented
+            EditorApplication.IsPaused = !EditorApplication.IsPaused;
         }
 
         /// <summary>
@@ -43,7 +46,7 @@ namespace BansheeEditor
         [ToolbarItem("Step", ToolbarIcon.Step, "", 1798)]
         private static void Step()
         {
-            // TODO - Not implemented
+            EditorApplication.FrameStep();
         }
 
         /// <inheritdoc/>

+ 2 - 2
MBansheeEditor/Library/LibraryGUIEntry.cs

@@ -127,7 +127,7 @@ namespace BansheeEditor
         /// </summary>
         public void Update()
         {
-            if (delayedSelect && Time.Elapsed > delayedSelectTime)
+            if (delayedSelect && Time.RealElapsed > delayedSelectTime)
             {
                 owner.Window.Select(path);
                 delayedSelect = false;
@@ -303,7 +303,7 @@ namespace BansheeEditor
                 // from the folder he is browsing to.
 
                 delayedSelect = true;
-                delayedSelectTime = Time.Elapsed + 0.5f;
+                delayedSelectTime = Time.RealElapsed + 0.5f;
             }
             else
                 owner.Window.Select(path);

+ 14 - 1
MBansheeEngine/Time.cs

@@ -12,7 +12,17 @@ namespace BansheeEngine
     public static class Time
     {
         /// <summary>
-        /// Gets the time elapsed since application start, in seconds. Only gets updated once per frame.
+        /// Gets the time elapsed since application start, in seconds. Only gets updated once per frame and keeps ticking
+        /// even if the game is not running.
+        /// </summary>
+        public static float RealElapsed
+        {
+            get { return Internal_GetRealElapsed(); }
+        }
+
+        /// <summary>
+        /// Gets the time elapsed since game start, in seconds. This value gets reset any time the game is started, and
+        /// will not be updated while the game is paused.
         /// </summary>
         public static float Elapsed
         {
@@ -54,6 +64,9 @@ namespace BansheeEngine
         /// </summary>
         public const float SecondToMicro = 1000000.0f;
 
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern float Internal_GetRealElapsed();
+
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern float Internal_GetElapsed();
 

+ 5 - 0
SBansheeEditor/Include/BsScriptEditorApplication.h

@@ -69,6 +69,11 @@ namespace BansheeEngine
 		static void internal_RunUnitTests();
 		static void internal_Quit();
 		static void internal_ToggleToolbarItem(MonoString* name, bool on);
+		static bool internal_GetIsPlaying();
+		static void internal_SetIsPlaying(bool value);
+		static bool internal_GetIsPaused();
+		static void internal_SetIsPaused(bool value);
+		static void internal_FrameStep();
 
 		typedef void(__stdcall *OnProjectLoadedThunkDef)(MonoException**);
 		typedef void(__stdcall *OnStatusBarClickedThunkDef) (MonoException**);

+ 41 - 0
SBansheeEditor/Source/BsScriptEditorApplication.cpp

@@ -15,6 +15,7 @@
 #include "BsTestOutput.h"
 #include "BsScriptManager.h"
 #include "BsGUIMenuBar.h"
+#include "BsPlayInEditorManager.h"
 
 namespace BansheeEngine
 {
@@ -57,6 +58,11 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_RunUnitTests", &ScriptEditorApplication::internal_RunUnitTests);
 		metaData.scriptClass->addInternalCall("Internal_Quit", &ScriptEditorApplication::internal_Quit);
 		metaData.scriptClass->addInternalCall("Internal_ToggleToolbarItem", &ScriptEditorApplication::internal_ToggleToolbarItem);
+		metaData.scriptClass->addInternalCall("Internal_GetIsPlaying", &ScriptEditorApplication::internal_GetIsPlaying);
+		metaData.scriptClass->addInternalCall("Internal_SetIsPlaying", &ScriptEditorApplication::internal_SetIsPlaying);
+		metaData.scriptClass->addInternalCall("Internal_GetIsPaused", &ScriptEditorApplication::internal_GetIsPaused);
+		metaData.scriptClass->addInternalCall("Internal_SetIsPaused", &ScriptEditorApplication::internal_SetIsPaused);
+		metaData.scriptClass->addInternalCall("Internal_FrameStep", &ScriptEditorApplication::internal_FrameStep);
 
 		onProjectLoadedThunk = (OnProjectLoadedThunkDef)metaData.scriptClass->getMethod("Internal_OnProjectLoaded")->getThunk();
 		onStatusBarClickedThunk = (OnStatusBarClickedThunkDef)metaData.scriptClass->getMethod("Internal_OnStatusBarClicked")->getThunk();
@@ -281,4 +287,39 @@ namespace BansheeEngine
 		MainEditorWindow* editorWindow = EditorWindowManager::instance().getMainWindow();
 		editorWindow->getMenuBar().toggleToolbarButton(nativeName, on);
 	}
+
+	bool ScriptEditorApplication::internal_GetIsPlaying()
+	{
+		return PlayInEditorManager::instance().getState() == PlayInEditorState::Playing;
+	}
+
+	void ScriptEditorApplication::internal_SetIsPlaying(bool value)
+	{
+		if (value)
+			PlayInEditorManager::instance().setState(PlayInEditorState::Playing);
+		else
+			PlayInEditorManager::instance().setState(PlayInEditorState::Stopped);
+	}
+
+	bool ScriptEditorApplication::internal_GetIsPaused()
+	{
+		return PlayInEditorManager::instance().getState() == PlayInEditorState::Paused;
+	}
+
+	void ScriptEditorApplication::internal_SetIsPaused(bool value)
+	{
+		if (value)
+			PlayInEditorManager::instance().setState(PlayInEditorState::Paused);
+		else
+		{
+			bool isPaused = PlayInEditorManager::instance().getState() == PlayInEditorState::Paused;
+			if (isPaused)
+				PlayInEditorManager::instance().setState(PlayInEditorState::Playing);
+		}
+	}
+
+	void ScriptEditorApplication::internal_FrameStep()
+	{
+		PlayInEditorManager::instance().frameStep();
+	}
 }

+ 1 - 0
SBansheeEngine/Include/BsScriptTime.h

@@ -19,6 +19,7 @@ namespace BansheeEngine
 		/************************************************************************/
 		/* 								CLR HOOKS						   		*/
 		/************************************************************************/
+		static float internal_getRealElapsed();
 		static float internal_getElapsed();
 		static float internal_getFrameDelta();
 		static UINT64 internal_getFrameNumber();

+ 8 - 1
SBansheeEngine/Source/BsScriptTime.cpp

@@ -4,6 +4,7 @@
 #include "BsMonoMethod.h"
 #include "BsMonoUtil.h"
 #include "BsTime.h"
+#include "BsPlayInEditorManager.h"
 
 namespace BansheeEngine
 {
@@ -13,17 +14,23 @@ namespace BansheeEngine
 
 	void ScriptTime::initRuntimeData()
 	{
+		metaData.scriptClass->addInternalCall("Internal_GetRealElapsed", &ScriptTime::internal_getRealElapsed);
 		metaData.scriptClass->addInternalCall("Internal_GetElapsed", &ScriptTime::internal_getElapsed);
 		metaData.scriptClass->addInternalCall("Internal_GetFrameDelta", &ScriptTime::internal_getFrameDelta);
 		metaData.scriptClass->addInternalCall("Internal_GetFrameNumber", &ScriptTime::internal_getFrameNumber);
 		metaData.scriptClass->addInternalCall("Internal_GetPrecise", &ScriptTime::internal_getPrecise);
 	}
 
-	float ScriptTime::internal_getElapsed()
+	float ScriptTime::internal_getRealElapsed()
 	{
 		return gTime().getTime();
 	}
 
+	float ScriptTime::internal_getElapsed()
+	{
+		return PlayInEditorManager::instance().getPausableTime();
+	}
+
 	float ScriptTime::internal_getFrameDelta()
 	{
 		return gTime().getFrameDelta();