Forráskód Böngészése

Resource handles will now be null only if they have no UUID, regardless if their resource is loaded or not
- Since there is an .isLoaded method that can check for loaded resource specifically
Standalone builds will now properly always be in play-mode
Fixed an issue with GameSettings load that was calling Resources module which wasn't initialized at standalone startup
Fixed an issue with going fullscreen and incorrect resolution
Standalone builds will now properly load game script assembly
Properly show progress bar when building or opening a file in external code editor

BearishSun 10 éve
szülő
commit
95a7c4063f

+ 10 - 1
BansheeCore/Include/BsResourceHandle.h

@@ -227,7 +227,7 @@ namespace BansheeEngine
 		 */
 		 */
 		operator int Bool_struct<T>::*() const
 		operator int Bool_struct<T>::*() const
 		{
 		{
-			return ((mData != nullptr && mData->mPtr != nullptr) ? &Bool_struct<T>::_Member : 0);
+			return ((mData != nullptr && !mData->mUUID.empty()) ? &Bool_struct<T>::_Member : 0);
 		}
 		}
 
 
 		/**
 		/**
@@ -366,6 +366,15 @@ namespace BansheeEngine
 		return _Left.getHandleData() == _Right.getHandleData();
 		return _Left.getHandleData() == _Right.getHandleData();
 	}
 	}
 
 
+	/**
+	 * @brief	Checks if a handle is null.
+	 */
+	template<class _Ty1, bool _Weak1, class _Ty2, bool _Weak2>
+	bool operator==(const TResourceHandle<_Ty1, _Weak1>& _Left, std::nullptr_t  _Right)
+	{	
+		return _Left.getHandleData() == nullptr || _Left.setHandleData().UUID.empty();
+	}
+
 	template<class _Ty1, bool _Weak1, class _Ty2, bool _Weak2>
 	template<class _Ty1, bool _Weak1, class _Ty2, bool _Weak2>
 	bool operator!=(const TResourceHandle<_Ty1, _Weak1>& _Left, const TResourceHandle<_Ty2, _Weak2>& _Right)
 	bool operator!=(const TResourceHandle<_Ty1, _Weak1>& _Left, const TResourceHandle<_Ty2, _Weak2>& _Right)
 	{	
 	{	

+ 1 - 1
BansheeCore/Source/BsMaterialRTTI.cpp

@@ -43,7 +43,7 @@ namespace BansheeEngine
 		std::shared_ptr<MaterialParams> params = bs_shared_ptr_new<MaterialParams>();
 		std::shared_ptr<MaterialParams> params = bs_shared_ptr_new<MaterialParams>();
 
 
 		HShader shader = material->getShader();
 		HShader shader = material->getShader();
-		if(shader != nullptr)
+		if(shader.isLoaded())
 		{
 		{
 			const Map<String, String>& validParamNames = material->getValidParamNames();
 			const Map<String, String>& validParamNames = material->getValidParamNames();
 
 

+ 1 - 1
BansheeCore/Source/BsResourceHandle.cpp

@@ -87,7 +87,7 @@ namespace BansheeEngine
 	void ResourceHandleBase::throwIfNotLoaded() const
 	void ResourceHandleBase::throwIfNotLoaded() const
 	{
 	{
 #if BS_DEBUG_MODE
 #if BS_DEBUG_MODE
-		if (!isLoaded())
+		if (!isLoaded(false))
 		{
 		{
 			BS_EXCEPT(InternalErrorException, "Trying to access a resource that hasn't been loaded yet.");
 			BS_EXCEPT(InternalErrorException, "Trying to access a resource that hasn't been loaded yet.");
 		}
 		}

+ 30 - 4
BansheeCore/Source/BsResources.cpp

@@ -313,8 +313,21 @@ namespace BansheeEngine
 		if (resource == nullptr)
 		if (resource == nullptr)
 			return;
 			return;
 
 
-		if (!resource.isLoaded()) // If it's still loading wait until that finishes
-			resource.blockUntilLoaded();
+		if (!resource.isLoaded(false))
+		{
+			bool loadInProgress = false;
+			{
+				BS_LOCK_MUTEX(mInProgressResourcesMutex);
+				auto iterFind2 = mInProgressResources.find(resource.getUUID());
+				if (iterFind2 != mInProgressResources.end())
+					loadInProgress = true;
+			}
+
+			if (loadInProgress) // If it's still loading wait until that finishes
+				resource.blockUntilLoaded();
+			else
+				return; // Already unloaded
+		}
 
 
 		Vector<ResourceDependency> dependencies = Utility::findResourceDependencies(*resource.get());
 		Vector<ResourceDependency> dependencies = Utility::findResourceDependencies(*resource.get());
 
 
@@ -380,8 +393,21 @@ namespace BansheeEngine
 		if (resource == nullptr)
 		if (resource == nullptr)
 			return;
 			return;
 
 
-		if(!resource.isLoaded())
-			resource.blockUntilLoaded();
+		if (!resource.isLoaded(false))
+		{
+			bool loadInProgress = false;
+			{
+				BS_LOCK_MUTEX(mInProgressResourcesMutex);
+				auto iterFind2 = mInProgressResources.find(resource.getUUID());
+				if (iterFind2 != mInProgressResources.end())
+					loadInProgress = true;
+			}
+
+			if (loadInProgress) // If it's still loading wait until that finishes
+				resource.blockUntilLoaded();
+			else
+				return; // Nothing to save
+		}
 
 
 		bool fileExists = FileSystem::isFile(filePath);
 		bool fileExists = FileSystem::isFile(filePath);
 		if(fileExists)
 		if(fileExists)

+ 14 - 4
BansheeD3D11RenderAPI/Source/BsD3D11RenderWindow.cpp

@@ -512,12 +512,22 @@ namespace BansheeEngine
 		if (!mWindow)
 		if (!mWindow)
 			return;
 			return;
 
 
+		mWindow->_windowMovedOrResized();
+
 		D3D11RenderWindowProperties& props = mProperties;
 		D3D11RenderWindowProperties& props = mProperties;
 
 
-		resizeSwapChainBuffers(mWindow->getWidth(), mWindow->getHeight());
-		mWindow->_windowMovedOrResized();
-		props.mTop = mWindow->getTop();
-		props.mLeft = mWindow->getLeft();
+		if (props.isFullScreen()) // Fullscreen is handled directly by this object
+		{
+			resizeSwapChainBuffers(props.getWidth(), props.getHeight());
+		}
+		else
+		{
+			resizeSwapChainBuffers(mWindow->getWidth(), mWindow->getHeight());
+			props.mWidth = mWindow->getWidth();
+			props.mHeight = mWindow->getHeight();
+			props.mTop = mWindow->getTop();
+			props.mLeft = mWindow->getLeft();
+		}
 
 
 		RenderWindowCore::_windowMovedOrResized();
 		RenderWindowCore::_windowMovedOrResized();
 	}
 	}

+ 7 - 4
BansheeD3D9RenderAPI/Source/BsD3D9RenderWindow.cpp

@@ -370,10 +370,13 @@ namespace BansheeEngine
 		mWindow->_windowMovedOrResized();
 		mWindow->_windowMovedOrResized();
 
 
 		D3D9RenderWindowProperties& props = mProperties;
 		D3D9RenderWindowProperties& props = mProperties;
-		props.mTop = mWindow->getTop();
-		props.mLeft = mWindow->getLeft();
-		props.mWidth = mWindow->getWidth();
-		props.mHeight = mWindow->getHeight();
+		if (!props.isFullScreen()) // Fullscreen is handled directly by this object
+		{
+			props.mTop = mWindow->getTop();
+			props.mLeft = mWindow->getLeft();
+			props.mWidth = mWindow->getWidth();
+			props.mHeight = mWindow->getHeight();
+		}
 
 
 		RenderWindowCore::_windowMovedOrResized();
 		RenderWindowCore::_windowMovedOrResized();
 	}
 	}

+ 5 - 0
BansheeEditor/Include/BsEditorApplication.h

@@ -113,6 +113,11 @@ namespace BansheeEngine
 		 * @param	path	Absolute path to the root project folder.
 		 * @param	path	Absolute path to the root project folder.
 		 */
 		 */
 		bool isValidProjectPath(const Path& path);
 		bool isValidProjectPath(const Path& path);
+
+		/**
+		 * @copydoc	Application::isEditor
+		 */
+		bool isEditor() const override { return true; }
 	private:
 	private:
 		/**
 		/**
 		 * @copydoc	Module::onStartUp
 		 * @copydoc	Module::onStartUp

+ 5 - 0
BansheeEngine/Include/BsApplication.h

@@ -59,6 +59,11 @@ namespace BansheeEngine
 		 */
 		 */
 		virtual Path getScriptAssemblyFolder() const;
 		virtual Path getScriptAssemblyFolder() const;
 
 
+		/**
+		 * @brief	Returns true if the application is running in an editor, false if standalone.
+		 */
+		virtual bool isEditor() const { return false; }
+
 	protected:
 	protected:
 		/**
 		/**
 		 * @copydoc	Module::onStartUp
 		 * @copydoc	Module::onStartUp

+ 1 - 1
BansheeEngine/Include/BsGameSettings.h

@@ -12,7 +12,7 @@ namespace BansheeEngine
 	class BS_EXPORT GameSettings : public IReflectable
 	class BS_EXPORT GameSettings : public IReflectable
 	{
 	{
 	public:
 	public:
-		WeakResourceHandle<Prefab> mainScene; /**< Resource UUID of the default scene that is loaded when the application is started. */
+		String mainSceneUUID; /**< Resource UUID of the default scene that is loaded when the application is started. */
 		bool fullscreen = true; /**< If true the application will be started in fullscreen using user's desktop resolution. */
 		bool fullscreen = true; /**< If true the application will be started in fullscreen using user's desktop resolution. */
 		bool useDesktopResolution = true; /**< If running in fullscreen should the user's desktop resolution be used instead of the specified resolution. */
 		bool useDesktopResolution = true; /**< If running in fullscreen should the user's desktop resolution be used instead of the specified resolution. */
 		UINT32 resolutionWidth = 1280; /**< Width of the window. */
 		UINT32 resolutionWidth = 1280; /**< Width of the window. */

+ 3 - 3
BansheeEngine/Include/BsGameSettingsRTTI.h

@@ -9,8 +9,8 @@ namespace BansheeEngine
 	class BS_EXPORT GameSettingsRTTI : public RTTIType <GameSettings, IReflectable, GameSettingsRTTI>
 	class BS_EXPORT GameSettingsRTTI : public RTTIType <GameSettings, IReflectable, GameSettingsRTTI>
 	{
 	{
 	private:
 	private:
-		WeakResourceHandle<Prefab>& getMainScene(GameSettings* obj) { return obj->mainScene; }
-		void setMainScene(GameSettings* obj, WeakResourceHandle<Prefab>& val) { obj->mainScene = val; }
+		String& getMainSceneUUID(GameSettings* obj) { return obj->mainSceneUUID; }
+		void setMainSceneUUID(GameSettings* obj, String& val) { obj->mainSceneUUID = val; }
 
 
 		bool& getFullscreen(GameSettings* obj) { return obj->fullscreen; }
 		bool& getFullscreen(GameSettings* obj) { return obj->fullscreen; }
 		void setFullscreen(GameSettings* obj, bool& val) { obj->fullscreen = val; }
 		void setFullscreen(GameSettings* obj, bool& val) { obj->fullscreen = val; }
@@ -30,7 +30,7 @@ namespace BansheeEngine
 	public:
 	public:
 		GameSettingsRTTI()
 		GameSettingsRTTI()
 		{
 		{
-			addReflectableField("mainScene", 0, &GameSettingsRTTI::getMainScene, &GameSettingsRTTI::setMainScene);
+			addPlainField("mainSceneUUID", 0, &GameSettingsRTTI::getMainSceneUUID, &GameSettingsRTTI::setMainSceneUUID);
 			addPlainField("fullscreen", 1, &GameSettingsRTTI::getFullscreen, &GameSettingsRTTI::setFullscreen);
 			addPlainField("fullscreen", 1, &GameSettingsRTTI::getFullscreen, &GameSettingsRTTI::setFullscreen);
 			addPlainField("useDesktopResolution", 2, &GameSettingsRTTI::getUseDesktopResolution, &GameSettingsRTTI::setUseDesktopResolution);
 			addPlainField("useDesktopResolution", 2, &GameSettingsRTTI::getUseDesktopResolution, &GameSettingsRTTI::setUseDesktopResolution);
 			addPlainField("resolutionWidth", 3, &GameSettingsRTTI::getResolutionWidth, &GameSettingsRTTI::setResolutionWidth);
 			addPlainField("resolutionWidth", 3, &GameSettingsRTTI::getResolutionWidth, &GameSettingsRTTI::setResolutionWidth);

+ 7 - 4
BansheeGLRenderAPI/Source/BsWin32RenderWindow.cpp

@@ -486,10 +486,13 @@ namespace BansheeEngine
 		mWindow->_windowMovedOrResized();
 		mWindow->_windowMovedOrResized();
 
 
 		Win32RenderWindowProperties& props = mProperties;
 		Win32RenderWindowProperties& props = mProperties;
-		props.mTop = mWindow->getTop();
-		props.mLeft = mWindow->getLeft();
-		props.mWidth = mWindow->getWidth();
-		props.mHeight = mWindow->getHeight();
+		if (!props.mIsFullScreen) // Fullscreen is handled directly by this object
+		{
+			props.mTop = mWindow->getTop();
+			props.mLeft = mWindow->getLeft();
+			props.mWidth = mWindow->getWidth();
+			props.mHeight = mWindow->getHeight();
+		}
 
 
 		RenderWindowCore::_windowMovedOrResized();
 		RenderWindowCore::_windowMovedOrResized();
 	}
 	}

+ 1 - 1
Game/Source/Main.cpp

@@ -121,7 +121,7 @@ void runApplication()
 		gResources().registerResourceManifest(manifest);
 		gResources().registerResourceManifest(manifest);
 	}
 	}
 
 
-	HPrefab mainScene = gResources().load<Prefab>(gameSettings->mainScene);
+	HPrefab mainScene = static_resource_cast<Prefab>(gResources().loadFromUUID(gameSettings->mainSceneUUID));
 	if (mainScene != nullptr)
 	if (mainScene != nullptr)
 	{
 	{
 		HSceneObject root = mainScene->instantiate();
 		HSceneObject root = mainScene->instantiate();

+ 3 - 4
MBansheeEditor/BuildWindow.cs

@@ -14,7 +14,7 @@ namespace BansheeEditor
 
 
         private PlatformType selectedPlatform;
         private PlatformType selectedPlatform;
         private GUIScrollArea optionsScrollArea;
         private GUIScrollArea optionsScrollArea;
-        private bool buildScheduled;
+        private ulong buildScheduledFrame = ulong.MaxValue;
 
 
         private GUIToggle[] platformButtons;
         private GUIToggle[] platformButtons;
 
 
@@ -99,14 +99,13 @@ namespace BansheeEditor
 
 
         private void OnEditorUpdate()
         private void OnEditorUpdate()
         {
         {
-            if (buildScheduled)
+            if (buildScheduledFrame == Time.FrameIdx)
             {
             {
                 BuildManager.Build();
                 BuildManager.Build();
                 ProgressBar.Hide();
                 ProgressBar.Hide();
 
 
                 EditorApplication.OpenExternally(BuildManager.OutputFolder);
                 EditorApplication.OpenExternally(BuildManager.OutputFolder);
                 DialogBox.Open(new LocEdString("Build complete"), new LocEdString("Build complete"), DialogBox.Type.OK);
                 DialogBox.Open(new LocEdString("Build complete"), new LocEdString("Build complete"), DialogBox.Type.OK);
-                buildScheduled = false;
             }
             }
         }
         }
 
 
@@ -238,7 +237,7 @@ namespace BansheeEditor
 
 
             EditorApplication.SaveProject();
             EditorApplication.SaveProject();
             // HACK - Delay build one frame so that progress bar has a chance to show. Use coroutines here once implemented.
             // HACK - Delay build one frame so that progress bar has a chance to show. Use coroutines here once implemented.
-            buildScheduled = true;
+            buildScheduledFrame = Time.FrameIdx + 1;
         }
         }
 
 
         /// <summary>
         /// <summary>

+ 15 - 2
MBansheeEditor/Library/LibraryGUIEntry.cs

@@ -42,6 +42,7 @@ namespace BansheeEditor
 
 
         private bool delayedSelect;
         private bool delayedSelect;
         private float delayedSelectTime;
         private float delayedSelectTime;
+        private ulong delayedOpenCodeEditorFrame = ulong.MaxValue;
 
 
         /// <summary>
         /// <summary>
         /// Bounds of the entry relative to part content area.
         /// Bounds of the entry relative to part content area.
@@ -132,6 +133,18 @@ namespace BansheeEditor
                 owner.Window.Select(path);
                 owner.Window.Select(path);
                 delayedSelect = false;
                 delayedSelect = false;
             }
             }
+
+            if (delayedOpenCodeEditorFrame == Time.FrameIdx)
+            {
+                LibraryEntry entry = ProjectLibrary.GetEntry(path);
+                if (entry != null && entry.Type == LibraryEntryType.File)
+                {
+                    FileEntry resEntry = (FileEntry) entry;
+                    CodeEditor.OpenFile(resEntry.Path, 0);
+                }
+
+                ProgressBar.Hide();
+            }
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -332,8 +345,8 @@ namespace BansheeEditor
                     else if (resEntry.ResType == ResourceType.ScriptCode)
                     else if (resEntry.ResType == ResourceType.ScriptCode)
                     {
                     {
                         ProgressBar.Show("Opening external code editor...", 1.0f);
                         ProgressBar.Show("Opening external code editor...", 1.0f);
-                        CodeEditor.OpenFile(resEntry.Path, 0);
-                        ProgressBar.Hide();
+
+                        delayedOpenCodeEditorFrame = Time.FrameIdx + 1;
                     }
                     }
                 }
                 }
             }
             }

+ 1 - 1
SBansheeEditor/Source/BsScriptBuildManager.cpp

@@ -391,7 +391,7 @@ namespace BansheeEngine
 		if (platformInfo != nullptr)
 		if (platformInfo != nullptr)
 		{
 		{
 			gameSettings = bs_shared_ptr_new<GameSettings>();
 			gameSettings = bs_shared_ptr_new<GameSettings>();
-			gameSettings->mainScene = platformInfo->mainScene;
+			gameSettings->mainSceneUUID = platformInfo->mainScene.getUUID();
 			gameSettings->fullscreen = platformInfo->fullscreen;
 			gameSettings->fullscreen = platformInfo->fullscreen;
 			gameSettings->resolutionWidth = platformInfo->windowedWidth;
 			gameSettings->resolutionWidth = platformInfo->windowedWidth;
 			gameSettings->resolutionWidth = platformInfo->windowedHeight;
 			gameSettings->resolutionWidth = platformInfo->windowedHeight;

+ 8 - 0
SBansheeEngine/Source/BsEngineScriptLibrary.cpp

@@ -41,6 +41,14 @@ namespace BansheeEngine
 		ScriptVirtualInput::startUp();
 		ScriptVirtualInput::startUp();
 
 
 		ScriptAssemblyManager::instance().loadAssemblyInfo(ENGINE_ASSEMBLY);
 		ScriptAssemblyManager::instance().loadAssemblyInfo(ENGINE_ASSEMBLY);
+
+		Path gameAssemblyPath = gApplication().getGameAssemblyPath();
+		if (FileSystem::exists(gameAssemblyPath))
+		{
+			MonoManager::instance().loadAssembly(gameAssemblyPath.toString(), SCRIPT_GAME_ASSEMBLY);
+			ScriptAssemblyManager::instance().loadAssemblyInfo(SCRIPT_GAME_ASSEMBLY);
+		}
+
 		bansheeEngineAssembly.invoke(ASSEMBLY_ENTRY_POINT);
 		bansheeEngineAssembly.invoke(ASSEMBLY_ENTRY_POINT);
 	}
 	}
 
 

+ 11 - 1
SBansheeEngine/Source/BsPlayInEditorManager.cpp

@@ -3,16 +3,23 @@
 #include "BsTime.h"
 #include "BsTime.h"
 #include "BsSceneManager.h"
 #include "BsSceneManager.h"
 #include "BsSceneObject.h"
 #include "BsSceneObject.h"
+#include "BsApplication.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
 	PlayInEditorManager::PlayInEditorManager()
 	PlayInEditorManager::PlayInEditorManager()
 		:mState(PlayInEditorState::Stopped), mNextState(PlayInEditorState::Stopped), 
 		:mState(PlayInEditorState::Stopped), mNextState(PlayInEditorState::Stopped), 
 		mFrameStepActive(false), mScheduledStateChange(false), mPausableTime(0.0f)
 		mFrameStepActive(false), mScheduledStateChange(false), mPausableTime(0.0f)
-	{ }
+	{
+		if (!gApplication().isEditor())
+			mState = PlayInEditorState::Playing;
+	}
 
 
 	void PlayInEditorManager::setState(PlayInEditorState state)
 	void PlayInEditorManager::setState(PlayInEditorState state)
 	{
 	{
+		if (!gApplication().isEditor())
+			return;
+
 		// Delay state change to next frame as this method could be called in middle of object update, in which case
 		// Delay state change to next frame as this method could be called in middle of object update, in which case
 		// part of the objects before this call would receive different state than other objects.
 		// part of the objects before this call would receive different state than other objects.
 		mScheduledStateChange = true;
 		mScheduledStateChange = true;
@@ -69,6 +76,9 @@ namespace BansheeEngine
 
 
 	void PlayInEditorManager::frameStep()
 	void PlayInEditorManager::frameStep()
 	{
 	{
+		if (!gApplication().isEditor())
+			return;
+
 		switch (mState)
 		switch (mState)
 		{
 		{
 		case PlayInEditorState::Stopped:
 		case PlayInEditorState::Stopped:

+ 1 - 0
TODO.txt

@@ -40,6 +40,7 @@ Optional:
  - Test VS 2015 Community as code editor (possibly also move the code to VS 2015)
  - Test VS 2015 Community as code editor (possibly also move the code to VS 2015)
 
 
  More optional:
  More optional:
+ - Add a way to use GUI elements in game window (Default GUI available to all, plus GUIWidget component for custom ones. Make sure skin can be changed for both.)
  - Clearing the console should also clear the status bar
  - Clearing the console should also clear the status bar
  - When starting drag from hierarchy tree view it tends to select another object (can't repro)
  - When starting drag from hierarchy tree view it tends to select another object (can't repro)
  - Handle seems to lag behind the selected mesh
  - Handle seems to lag behind the selected mesh