Bläddra i källkod

Added a way to transparently load resources from managed code when in editor or standalone
Added C# Resources
Fixed a bug in RenderBeast where renderable IDs were being updated properly
Fixed scene loading so that the original scene root element doesn't persist after load
Changed license to GPL

Marko Pintera 10 år sedan
förälder
incheckning
03cfee9d17
30 ändrade filer med 501 tillägg och 134 borttagningar
  1. 1 1
      BansheeCore/Include/BsResources.h
  2. 22 3
      BansheeEditor/Include/BsProjectLibrary.h
  3. 13 0
      BansheeEditor/Include/BsProjectResourceMeta.h
  4. 7 3
      BansheeEditor/Include/BsProjectResourceMetaRTTI.h
  5. 1 1
      BansheeEditor/Source/BsEditorApplication.cpp
  6. 47 0
      BansheeEditor/Source/BsProjectLibrary.cpp
  7. 2 0
      BansheeEditor/Source/BsProjectResourceMeta.cpp
  8. 1 0
      BansheeEngine/Include/BsPrerequisites.h
  9. 1 1
      BansheeEngine/Source/BsApplication.cpp
  10. 0 35
      License/BansheeLicense.md
  11. 12 0
      MBansheeEditor/ProjectLibrary.cs
  12. 1 0
      MBansheeEngine/MBansheeEngine.csproj
  13. 33 0
      MBansheeEngine/Resources.cs
  14. 4 0
      RenderBeast/Source/BsRenderBeast.cpp
  15. 19 0
      SBansheeEditor/Include/BsEditorResourceLoader.h
  16. 2 0
      SBansheeEditor/Include/BsScriptProjectLibrary.h
  17. 2 0
      SBansheeEditor/SBansheeEditor.vcxproj
  18. 6 0
      SBansheeEditor/SBansheeEditor.vcxproj.filters
  19. 27 0
      SBansheeEditor/Source/BsEditorResourceLoader.cpp
  20. 4 0
      SBansheeEditor/Source/BsEditorScriptManager.cpp
  21. 33 2
      SBansheeEditor/Source/BsScriptProjectLibrary.cpp
  22. 71 0
      SBansheeEngine/Include/BsGameResourceManager.h
  23. 26 0
      SBansheeEngine/Include/BsScriptResources.h
  24. 4 0
      SBansheeEngine/SBansheeEngine.vcxproj
  25. 12 0
      SBansheeEngine/SBansheeEngine.vcxproj.filters
  26. 29 0
      SBansheeEngine/Source/BsGameResourceManager.cpp
  27. 3 0
      SBansheeEngine/Source/BsScriptEnginePlugin.cpp
  28. 47 0
      SBansheeEngine/Source/BsScriptResources.cpp
  29. 16 2
      SBansheeEngine/Source/BsScriptScene.cpp
  30. 55 86
      TODO.txt

+ 1 - 1
BansheeCore/Include/BsResources.h

@@ -44,7 +44,7 @@ namespace BansheeEngine
 		template <class T>
 		template <class T>
 		ResourceHandle<T> load(const Path& filePath, bool loadDependencies = true)
 		ResourceHandle<T> load(const Path& filePath, bool loadDependencies = true)
 		{
 		{
-			return static_resource_cast<T>(load(filePath));
+			return static_resource_cast<T>(load(filePath, loadDependencies));
 		}
 		}
 
 
 		/**
 		/**

+ 22 - 3
BansheeEditor/Include/BsProjectLibrary.h

@@ -108,7 +108,8 @@ namespace BansheeEngine
 		 *
 		 *
 		 * @param	path	Path to the entry, either absolute or relative to resources folder.
 		 * @param	path	Path to the entry, either absolute or relative to resources folder.
 		 *
 		 *
-		 * @return	Found entry, or null if not found.
+		 * @return	Found entry, or null if not found. Value returned by this method is transient,
+		 *			it may be destroyed on any following ProjectLibrary call.
 		 */
 		 */
 		LibraryEntry* findEntry(const Path& path) const;
 		LibraryEntry* findEntry(const Path& path) const;
 
 
@@ -117,7 +118,8 @@ namespace BansheeEngine
 		 *
 		 *
 		 * @param	pattern	Pattern to search for. Use wildcard * to match any character(s).
 		 * @param	pattern	Pattern to search for. Use wildcard * to match any character(s).
 		 *
 		 *
-		 * @return	A list of entries matching the pattern.
+		 * @return	A list of entries matching the pattern. Values returned by this method are transient,
+		 *			they may be destroyed on any following ProjectLibrary call.
 		 */
 		 */
 		Vector<LibraryEntry*> search(const WString& pattern);
 		Vector<LibraryEntry*> search(const WString& pattern);
 
 
@@ -127,7 +129,8 @@ namespace BansheeEngine
 		 * @param	pattern	Pattern to search for. Use wildcard * to match any character(s).
 		 * @param	pattern	Pattern to search for. Use wildcard * to match any character(s).
 		 * @param	typeIds	RTTI type IDs of the resource types we're interested in searching.
 		 * @param	typeIds	RTTI type IDs of the resource types we're interested in searching.
 		 *
 		 *
-		 * @return	A list of entries matching the pattern.
+		 * @return	A list of entries matching the pattern. Values returned by this method are transient, 
+		 *			they may be destroyed on any following ProjectLibrary call.
 		 */
 		 */
 		Vector<LibraryEntry*> search(const WString& pattern, const Vector<UINT32>& typeIds);
 		Vector<LibraryEntry*> search(const WString& pattern, const Vector<UINT32>& typeIds);
 
 
@@ -207,6 +210,22 @@ namespace BansheeEngine
 		 */
 		 */
 		void reimport(const Path& path, const ImportOptionsPtr& importOptions = nullptr, bool forceReimport = false);
 		void reimport(const Path& path, const ImportOptionsPtr& importOptions = nullptr, bool forceReimport = false);
 
 
+		/**
+		 * @brief	Determines if this resource will always be included in the build, regardless if
+		 *			it's being referenced or not.
+		 *
+		 * @param	path	Path to the resource to modify, absolute or relative to resources folder.
+		 * @param	force	True if we want the resource to be included in the build, false otherwise.
+		 */
+		void setIncludeInBuild(const Path& path, bool force);
+
+		/**
+		 * @brief	Finds all resource entries that should be included in a build.
+		 *			Values returned by this method are transient, they may be destroyed
+		 *			on any following ProjectLibrary call.
+		 */
+		Vector<ResourceEntry*> getResourcesForBuild() const;
+
 		/**
 		/**
 		 * @brief	Loads a resource at the specified path, synchronously.
 		 * @brief	Loads a resource at the specified path, synchronously.
 		 *
 		 *

+ 13 - 0
BansheeEditor/Include/BsProjectResourceMeta.h

@@ -50,11 +50,24 @@ namespace BansheeEngine
 		 */
 		 */
 		UINT32 getTypeID() const { return mTypeId; }
 		UINT32 getTypeID() const { return mTypeId; }
 
 
+		/**
+		 * @brief	Checks should this resource always be included in the build, regardless if
+		 *			it's being referenced or not.
+		 */
+		bool getIncludeInBuild() const { return mIncludeInBuild; }
+
+		/**
+		 * @brief	Determines if this resource will always be included in the build, regardless if
+		 *			it's being referenced or not.
+		 */
+		void setIncludeInBuild(bool include) { mIncludeInBuild = include; }
+
 	private:
 	private:
 		String mUUID;
 		String mUUID;
 		ResourceMetaDataPtr mResourceMeta;
 		ResourceMetaDataPtr mResourceMeta;
 		ImportOptionsPtr mImportOptions;
 		ImportOptionsPtr mImportOptions;
 		UINT32 mTypeId;
 		UINT32 mTypeId;
+		bool mIncludeInBuild;
 
 
 		/************************************************************************/
 		/************************************************************************/
 		/* 								RTTI		                     		*/
 		/* 								RTTI		                     		*/

+ 7 - 3
BansheeEditor/Include/BsProjectResourceMetaRTTI.h

@@ -23,6 +23,9 @@ namespace BansheeEngine
 		ImportOptionsPtr getImportOptions(ProjectResourceMeta* obj) { return obj->mImportOptions; }
 		ImportOptionsPtr getImportOptions(ProjectResourceMeta* obj) { return obj->mImportOptions; }
 		void setImportOptions(ProjectResourceMeta* obj, ImportOptionsPtr val) { obj->mImportOptions = val; }
 		void setImportOptions(ProjectResourceMeta* obj, ImportOptionsPtr val) { obj->mImportOptions = val; }
 
 
+		bool& getIncludeInBuild(ProjectResourceMeta* obj) { return obj->mIncludeInBuild; }
+		void setIncludeInBuild(ProjectResourceMeta* obj, bool& val) { obj->mIncludeInBuild = val; }
+
 	public:
 	public:
 		ProjectResourceMetaRTTI()
 		ProjectResourceMetaRTTI()
 		{
 		{
@@ -30,20 +33,21 @@ namespace BansheeEngine
 			addReflectablePtrField("mImportOptions", 1, &ProjectResourceMetaRTTI::getImportOptions, &ProjectResourceMetaRTTI::setImportOptions);
 			addReflectablePtrField("mImportOptions", 1, &ProjectResourceMetaRTTI::getImportOptions, &ProjectResourceMetaRTTI::setImportOptions);
 			addReflectablePtrField("mResourceMeta", 2, &ProjectResourceMetaRTTI::getResourceMeta, &ProjectResourceMetaRTTI::setResourceMeta);
 			addReflectablePtrField("mResourceMeta", 2, &ProjectResourceMetaRTTI::getResourceMeta, &ProjectResourceMetaRTTI::setResourceMeta);
 			addPlainField("mTypeId", 3, &ProjectResourceMetaRTTI::getTypeId, &ProjectResourceMetaRTTI::setTypeId);
 			addPlainField("mTypeId", 3, &ProjectResourceMetaRTTI::getTypeId, &ProjectResourceMetaRTTI::setTypeId);
+			addPlainField("mIncludeInBuild", 4, &ProjectResourceMetaRTTI::getIncludeInBuild, &ProjectResourceMetaRTTI::setIncludeInBuild);
 		}
 		}
 
 
-		virtual const String& getRTTIName()
+		virtual const String& getRTTIName() override
 		{
 		{
 			static String name = "ProjectResourceMeta";
 			static String name = "ProjectResourceMeta";
 			return name;
 			return name;
 		}
 		}
 
 
-		virtual UINT32 getRTTIId()
+		virtual UINT32 getRTTIId() override
 		{
 		{
 			return TID_ProjectResourceMeta;
 			return TID_ProjectResourceMeta;
 		}
 		}
 
 
-		virtual std::shared_ptr<IReflectable> newRTTIObject()
+		virtual std::shared_ptr<IReflectable> newRTTIObject() override
 		{
 		{
 			return ProjectResourceMeta::createEmpty();
 			return ProjectResourceMeta::createEmpty();
 		}
 		}

+ 1 - 1
BansheeEditor/Source/BsEditorApplication.cpp

@@ -18,6 +18,7 @@
 #include "BsShaderIncludeHandler.h"
 #include "BsShaderIncludeHandler.h"
 #include "BsDropDownWindowManager.h"
 #include "BsDropDownWindowManager.h"
 #include "BsPrefabImporter.h"
 #include "BsPrefabImporter.h"
+#include "BsProjectLibrary.h"
 
 
 // DEBUG ONLY
 // DEBUG ONLY
 #include "BsResources.h"
 #include "BsResources.h"
@@ -32,7 +33,6 @@
 #include "BsRenderable.h"
 #include "BsRenderable.h"
 #include "BsVirtualInput.h"
 #include "BsVirtualInput.h"
 #include "BsFolderMonitor.h"
 #include "BsFolderMonitor.h"
-#include "BsProjectLibrary.h"
 #include "BsCamera.h"
 #include "BsCamera.h"
 #include "BsGUIWidget.h"
 #include "BsGUIWidget.h"
 #include "BsGUIButton.h"
 #include "BsGUIButton.h"

+ 47 - 0
BansheeEditor/Source/BsProjectLibrary.cpp

@@ -897,6 +897,53 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
+	void ProjectLibrary::setIncludeInBuild(const Path& path, bool include)
+	{
+		LibraryEntry* entry = findEntry(path);
+
+		if (entry == nullptr || entry->type == LibraryEntryType::Directory)
+			return;
+
+		ResourceEntry* resEntry = static_cast<ResourceEntry*>(entry);
+		resEntry->meta->setIncludeInBuild(include);
+
+		Path metaPath = resEntry->path;
+		metaPath.setFilename(metaPath.getWFilename() + L".meta");
+
+		FileEncoder fs(metaPath);
+		fs.encode(resEntry->meta.get());
+	}
+
+	Vector<ProjectLibrary::ResourceEntry*> ProjectLibrary::getResourcesForBuild() const
+	{
+		Vector<ResourceEntry*> output;
+
+		Stack<DirectoryEntry*> todo;
+		todo.push(mRootEntry);
+
+		while (!todo.empty())
+		{
+			DirectoryEntry* directory = todo.top();
+			todo.pop();
+
+			for (auto& child : directory->mChildren)
+			{
+				if (child->type == LibraryEntryType::File)
+				{
+					ResourceEntry* resEntry = static_cast<ResourceEntry*>(child);
+					if (resEntry->meta != nullptr && resEntry->meta->getIncludeInBuild())
+						output.push_back(resEntry);
+				}
+				else if (child->type == LibraryEntryType::Directory)
+				{
+					todo.push(static_cast<DirectoryEntry*>(child));
+				}
+			}
+		}
+
+		return output;
+	}
+
 	HResource ProjectLibrary::load(const Path& path)
 	HResource ProjectLibrary::load(const Path& path)
 	{
 	{
 		LibraryEntry* entry = findEntry(path);
 		LibraryEntry* entry = findEntry(path);

+ 2 - 0
BansheeEditor/Source/BsProjectResourceMeta.cpp

@@ -4,6 +4,7 @@
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
 	ProjectResourceMeta::ProjectResourceMeta(const ConstructPrivately& dummy)
 	ProjectResourceMeta::ProjectResourceMeta(const ConstructPrivately& dummy)
+		:mIncludeInBuild(false), mTypeId(0)
 	{
 	{
 
 
 	}
 	}
@@ -16,6 +17,7 @@ namespace BansheeEngine
 		meta->mTypeId = typeId;
 		meta->mTypeId = typeId;
 		meta->mResourceMeta = resourceMetaData;
 		meta->mResourceMeta = resourceMetaData;
 		meta->mImportOptions = importOptions;
 		meta->mImportOptions = importOptions;
+		meta->mIncludeInBuild = false;
 
 
 		return meta;
 		return meta;
 	}
 	}

+ 1 - 0
BansheeEngine/Include/BsPrerequisites.h

@@ -135,6 +135,7 @@ namespace BansheeEngine
 	static const char* ENGINE_ASSEMBLY = "MBansheeEngine";
 	static const char* ENGINE_ASSEMBLY = "MBansheeEngine";
 	static const char* SCRIPT_GAME_ASSEMBLY = "MScriptGame";
 	static const char* SCRIPT_GAME_ASSEMBLY = "MScriptGame";
 	static const Path ASSEMBLY_PATH = "..\\..\\Assemblies\\";
 	static const Path ASSEMBLY_PATH = "..\\..\\Assemblies\\";
+	static const Path GAME_RESOURCES_PATH = "..\\..\\..\\Resources\\";
 
 
 	/**
 	/**
 	 * @brief	RTTI types.
 	 * @brief	RTTI types.

+ 1 - 1
BansheeEngine/Source/BsApplication.cpp

@@ -161,7 +161,7 @@ namespace BansheeEngine
 		assemblyFolder.append(ASSEMBLY_PATH);
 		assemblyFolder.append(ASSEMBLY_PATH);
 
 
 		return assemblyFolder;
 		return assemblyFolder;
-	}	
+	}
 
 
 	const String& Application::getLibNameForRenderAPI(RenderAPIPlugin plugin)
 	const String& Application::getLibNameForRenderAPI(RenderAPIPlugin plugin)
 	{
 	{

+ 0 - 35
License/BansheeLicense.md

@@ -1,35 +0,0 @@
-By downloading, using, modifying or distributing Banshee Project as a whole or in part you agree to the terms of this license. This license applies to all Banshee Project distributions (source, binary and others) and as such applies to all files within those distributions. 
-
-You may freely use, modify and redistribute Banshee for personal or commercial use, as long as you acknowledge in your product that you are using the Banshee Project under the terms stated by the license.
-
-Certain Banshee distributions come with a set of third party libraries or tools, either in source or binary form. Those libraries come with their own licenses do not fall under the Banshee license.
-
-This license was inspired by BSD and FreeType licenses.
-
-The Banshee Project is copyright (C) 2014 by Marko Pintera.
-# Banshee License
-## License Grant
-Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the Software and accompanying documentation covered by this license to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software. The License does not grant you any title or ownership in the Licensed Technology.
-## Attribution
-You must acknowledge the use of the Software in any derivative works or if you are redistributing the Software in any form. 
-
-Any redistribution of source code, original or altered must include this license in its original form. Any modifications to the source code must be noted in the derivative works documentation.
-
-Any derivative work or work using any part of Banshee Project in binary form must include a clearly visible Banshee Engine Logo during application start up. Optionally, if displaying the logo is not feasible due to technical constraints a textual credit line may be displayed in another location with a special permission from the Author.
-## Third Party Software
-The Software includes Third Party Software components. Those components may include separate software licenses or requirements. Those components are not covered by this License.
-## Disclaimer
-The Software is provided “as is”, without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for particular purpose, title or non-infringement. In no event shall the copyright holders or anyone distributing the Software be liable for any damages or other liability, whether in contract, tort or otherwise, arising from, out of or in connection with the Software or the use or other dealings in the Software.
-## Definitions
-“Author” means the original creator and copyright holder of the Software, Marko Pintera.
-
-“Banshee Engine Logo” means the image asset provided as Exhibit A.
-
-“Licensed Technology” means the Software source code, machine-executable code, documentation, tools, assets and any other files that are considered part of the “Banshee Project”.
-
-“Software” means the original set of files created and distributed as “Banshee Project” by the Author.
-
-“Third Party Software” means any third party components used by the Software, either in source or machine-executable code format and any assets they might include.
-
-## Exhibits
-Exhibit A - Banshee Engine Logo – Included with this license text as BansheeLogo.png.

+ 12 - 0
MBansheeEditor/ProjectLibrary.cs

@@ -110,6 +110,11 @@ namespace BansheeEditor
             Internal_Copy(source, destination, overwrite);
             Internal_Copy(source, destination, overwrite);
         }
         }
 
 
+        public static void SetIncludeInBuild(string path, bool include)
+        {
+            Internal_SetIncludeInBuild(path, include);
+        }
+
         internal static void Update()
         internal static void Update()
         {
         {
             if (queuedForImport.Count > 0)
             if (queuedForImport.Count > 0)
@@ -220,6 +225,9 @@ namespace BansheeEditor
 
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern string Internal_GetResourceFolder();
         private static extern string Internal_GetResourceFolder();
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetIncludeInBuild(string path, bool force);
     }
     }
 
 
     // Note: Must be the same as C++ enum ProjectLibrary::LibraryEntryType
     // Note: Must be the same as C++ enum ProjectLibrary::LibraryEntryType
@@ -269,6 +277,7 @@ namespace BansheeEditor
         public string UUID { get { return Internal_GetUUID(mCachedPtr); } }
         public string UUID { get { return Internal_GetUUID(mCachedPtr); } }
         public Texture2D Icon { get { return Internal_GetIcon(mCachedPtr); } }
         public Texture2D Icon { get { return Internal_GetIcon(mCachedPtr); } }
         public ResourceType ResType { get { return Internal_GetResourceType(mCachedPtr); } }
         public ResourceType ResType { get { return Internal_GetResourceType(mCachedPtr); } }
+        public bool IncludeInBuild { get { return Internal_GetIncludeInBuild(mCachedPtr); } }
 
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern ImportOptions Internal_GetImportOptions(IntPtr thisPtr);
         private static extern ImportOptions Internal_GetImportOptions(IntPtr thisPtr);
@@ -281,5 +290,8 @@ namespace BansheeEditor
 
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern ResourceType Internal_GetResourceType(IntPtr thisPtr);
         private static extern ResourceType Internal_GetResourceType(IntPtr thisPtr);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_GetIncludeInBuild(IntPtr thisPtr);
     }
     }
 }
 }

+ 1 - 0
MBansheeEngine/MBansheeEngine.csproj

@@ -118,6 +118,7 @@
     <Compile Include="RenderTexture.cs" />
     <Compile Include="RenderTexture.cs" />
     <Compile Include="RenderTexture2D.cs" />
     <Compile Include="RenderTexture2D.cs" />
     <Compile Include="Resource.cs" />
     <Compile Include="Resource.cs" />
+    <Compile Include="Resources.cs" />
     <Compile Include="Scene.cs" />
     <Compile Include="Scene.cs" />
     <Compile Include="SceneObject.cs" />
     <Compile Include="SceneObject.cs" />
     <Compile Include="ScriptCode.cs" />
     <Compile Include="ScriptCode.cs" />

+ 33 - 0
MBansheeEngine/Resources.cs

@@ -0,0 +1,33 @@
+using System;
+using System.Runtime.CompilerServices;
+
+namespace BansheeEngine
+{
+    public static class Resources
+    {
+        public static T Load<T>(string path) where T : Resource
+        {
+            return (T)Internal_Load(path);
+        }
+
+        public static void Unload(Resource resource)
+        {
+            if (resource != null)
+                Internal_Unload(resource.GetCachedPtr());
+        }
+
+        public static void UnloadUnused()
+        {
+            Internal_UnloadUnused();
+        }
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern Resource Internal_Load(string path);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_Unload(IntPtr resourcePtr);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_UnloadUnused();
+    }
+}

+ 4 - 0
RenderBeast/Source/BsRenderBeast.cpp

@@ -178,6 +178,10 @@ namespace BansheeEngine
 			std::swap(mWorldTransforms[renderableId], mWorldTransforms[lastRenderableId]);
 			std::swap(mWorldTransforms[renderableId], mWorldTransforms[lastRenderableId]);
 
 
 			lastRenerable->setRendererId(renderableId);
 			lastRenerable->setRendererId(renderableId);
+
+			Vector<BeastRenderableElement>& lastRenderableElements = mRenderables[renderableId].elements;
+			for (auto& element : elements)
+				element.renderableId = renderableId;
 		}
 		}
 
 
 		// Last element is the one we want to erase
 		// Last element is the one we want to erase

+ 19 - 0
SBansheeEditor/Include/BsEditorResourceLoader.h

@@ -0,0 +1,19 @@
+#pragma once
+
+#include "BsScriptEditorPrerequisites.h"
+#include "BsGameResourceManager.h"
+
+namespace BansheeEngine
+{
+	/**
+	 * @brief	Handles loading of game resources when the editor is running.
+	 */
+	class BS_SCR_BED_EXPORT EditorResourceLoader : public IGameResourceLoader
+	{
+	public:
+		/**
+		 * @copydoc	IGameResourceLoader::load
+		 */
+		HResource load(const Path& path) const override;
+	};
+}

+ 2 - 0
SBansheeEditor/Include/BsScriptProjectLibrary.h

@@ -32,6 +32,7 @@ namespace BansheeEngine
 		static void internal_Move(MonoString* oldPath, MonoString* newPath, bool overwrite);
 		static void internal_Move(MonoString* oldPath, MonoString* newPath, bool overwrite);
 		static void internal_Copy(MonoString* source, MonoString* destination, bool overwrite);
 		static void internal_Copy(MonoString* source, MonoString* destination, bool overwrite);
 		static MonoString* internal_GetResourceFolder();
 		static MonoString* internal_GetResourceFolder();
+		static void internal_SetIncludeInBuild(MonoString* path, bool include);
 
 
 		static void onEntryAdded(const Path& path);
 		static void onEntryAdded(const Path& path);
 		static void onEntryRemoved(const Path& path);
 		static void onEntryRemoved(const Path& path);
@@ -98,5 +99,6 @@ namespace BansheeEngine
 		static MonoString* internal_GetUUID(ScriptFileEntry* thisPtr);
 		static MonoString* internal_GetUUID(ScriptFileEntry* thisPtr);
 		static MonoObject* internal_GetIcon(ScriptFileEntry* thisPtr);
 		static MonoObject* internal_GetIcon(ScriptFileEntry* thisPtr);
 		static ScriptResourceType internal_GetResourceType(ScriptFileEntry* thisPtr);
 		static ScriptResourceType internal_GetResourceType(ScriptFileEntry* thisPtr);
+		static bool internal_GetIncludeInBuild(ScriptFileEntry* thisPtr);
 	};
 	};
 }
 }

+ 2 - 0
SBansheeEditor/SBansheeEditor.vcxproj

@@ -232,6 +232,7 @@
     </Link>
     </Link>
   </ItemDefinitionGroup>
   </ItemDefinitionGroup>
   <ItemGroup>
   <ItemGroup>
+    <ClInclude Include="Include\BsEditorResourceLoader.h" />
     <ClInclude Include="Include\BsEditorScriptManager.h" />
     <ClInclude Include="Include\BsEditorScriptManager.h" />
     <ClInclude Include="Include\BsGUIGameObjectField.h" />
     <ClInclude Include="Include\BsGUIGameObjectField.h" />
     <ClInclude Include="Include\BsGUIResourceField.h" />
     <ClInclude Include="Include\BsGUIResourceField.h" />
@@ -285,6 +286,7 @@
     <ClInclude Include="Include\BsScriptUnitTests.h" />
     <ClInclude Include="Include\BsScriptUnitTests.h" />
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
+    <ClCompile Include="Source\BsEditorResourceLoader.cpp" />
     <ClCompile Include="Source\BsGUITextureField.cpp" />
     <ClCompile Include="Source\BsGUITextureField.cpp" />
     <ClCompile Include="Source\BsMenuItemManager.cpp" />
     <ClCompile Include="Source\BsMenuItemManager.cpp" />
     <ClCompile Include="Source\BsScriptBuildManager.cpp" />
     <ClCompile Include="Source\BsScriptBuildManager.cpp" />

+ 6 - 0
SBansheeEditor/SBansheeEditor.vcxproj.filters

@@ -168,6 +168,9 @@
     <ClInclude Include="Include\BsScriptUndoRedo.h">
     <ClInclude Include="Include\BsScriptUndoRedo.h">
       <Filter>Header Files</Filter>
       <Filter>Header Files</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="Include\BsEditorResourceLoader.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsScriptEditorPlugin.cpp">
     <ClCompile Include="Source\BsScriptEditorPlugin.cpp">
@@ -323,5 +326,8 @@
     <ClCompile Include="Source\BsScriptUndoRedo.cpp">
     <ClCompile Include="Source\BsScriptUndoRedo.cpp">
       <Filter>Source Files</Filter>
       <Filter>Source Files</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="Source\BsEditorResourceLoader.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
 </Project>
 </Project>

+ 27 - 0
SBansheeEditor/Source/BsEditorResourceLoader.cpp

@@ -0,0 +1,27 @@
+#include "BsEditorResourceLoader.h"
+#include "BsProjectLibrary.h"
+#include "BsResources.h"
+#include "BsProjectResourceMeta.h"
+#include "BsDebug.h"
+
+namespace BansheeEngine
+{
+	HResource EditorResourceLoader::load(const Path& path) const
+	{
+		ProjectLibrary::LibraryEntry* entry = ProjectLibrary::instance().findEntry(path);
+
+		if (entry == nullptr || entry->type == ProjectLibrary::LibraryEntryType::Directory)
+			return HResource();
+
+		ProjectLibrary::ResourceEntry* resEntry = static_cast<ProjectLibrary::ResourceEntry*>(entry);
+		String resUUID = resEntry->meta->getUUID();
+
+		if (resEntry->meta->getIncludeInBuild())
+		{
+			LOGWRN("Dynamically loading a resource at path: \"" + path.toString() + "\" but the resource \
+					isn't flagged to be included in the build. It may not be available outside of the editor.");
+		}
+
+		return Resources::instance().loadFromUUID(resUUID);
+	}
+}

+ 4 - 0
SBansheeEditor/Source/BsEditorScriptManager.cpp

@@ -18,6 +18,7 @@
 #include "BsEditorApplication.h"
 #include "BsEditorApplication.h"
 #include "BsScriptSelection.h"
 #include "BsScriptSelection.h"
 #include "BsTestOutput.h"
 #include "BsTestOutput.h"
+#include "BsEditorResourceLoader.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
@@ -27,6 +28,9 @@ namespace BansheeEngine
 	EditorScriptManager::EditorScriptManager()
 	EditorScriptManager::EditorScriptManager()
 		:mEditorAssembly(nullptr), mProgramEdClass(nullptr), mUpdateMethod(nullptr)
 		:mEditorAssembly(nullptr), mProgramEdClass(nullptr), mUpdateMethod(nullptr)
 	{
 	{
+		SPtr<EditorResourceLoader> resourceLoader = bs_shared_ptr_new<EditorResourceLoader>();
+		GameResourceManager::instance().setLoader(resourceLoader);
+
 		loadMonoTypes();
 		loadMonoTypes();
 		ScriptAssemblyManager::instance().loadAssemblyInfo(EDITOR_ASSEMBLY);
 		ScriptAssemblyManager::instance().loadAssemblyInfo(EDITOR_ASSEMBLY);
 
 

+ 33 - 2
SBansheeEditor/Source/BsScriptProjectLibrary.cpp

@@ -49,6 +49,7 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_Move", &ScriptProjectLibrary::internal_Move);
 		metaData.scriptClass->addInternalCall("Internal_Move", &ScriptProjectLibrary::internal_Move);
 		metaData.scriptClass->addInternalCall("Internal_Copy", &ScriptProjectLibrary::internal_Copy);
 		metaData.scriptClass->addInternalCall("Internal_Copy", &ScriptProjectLibrary::internal_Copy);
 		metaData.scriptClass->addInternalCall("Internal_GetResourceFolder", &ScriptProjectLibrary::internal_GetResourceFolder);
 		metaData.scriptClass->addInternalCall("Internal_GetResourceFolder", &ScriptProjectLibrary::internal_GetResourceFolder);
+		metaData.scriptClass->addInternalCall("Internal_SetIncludeInBuild", &ScriptProjectLibrary::internal_SetIncludeInBuild);
 
 
 		OnEntryAddedThunk = (OnEntryChangedThunkDef)metaData.scriptClass->getMethod("Internal_DoOnEntryAdded", 1)->getThunk();
 		OnEntryAddedThunk = (OnEntryChangedThunkDef)metaData.scriptClass->getMethod("Internal_DoOnEntryAdded", 1)->getThunk();
 		OnEntryRemovedThunk = (OnEntryChangedThunkDef)metaData.scriptClass->getMethod("Internal_DoOnEntryRemoved", 1)->getThunk();
 		OnEntryRemovedThunk = (OnEntryChangedThunkDef)metaData.scriptClass->getMethod("Internal_DoOnEntryRemoved", 1)->getThunk();
@@ -239,6 +240,13 @@ namespace BansheeEngine
 		return MonoUtil::wstringToMono(MonoManager::instance().getDomain(), ProjectLibrary::instance().getResourcesFolder().toWString());
 		return MonoUtil::wstringToMono(MonoManager::instance().getDomain(), ProjectLibrary::instance().getResourcesFolder().toWString());
 	}
 	}
 
 
+	void ScriptProjectLibrary::internal_SetIncludeInBuild(MonoString* path, bool include)
+	{
+		Path pathNative = MonoUtil::monoToWString(path);
+
+		ProjectLibrary::instance().setIncludeInBuild(pathNative, include);
+	}
+
 	void ScriptProjectLibrary::startUp()
 	void ScriptProjectLibrary::startUp()
 	{
 	{
 		mOnEntryAddedConn = ProjectLibrary::instance().onEntryAdded.connect(std::bind(&ScriptProjectLibrary::onEntryAdded, _1));
 		mOnEntryAddedConn = ProjectLibrary::instance().onEntryAdded.connect(std::bind(&ScriptProjectLibrary::onEntryAdded, _1));
@@ -377,6 +385,7 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_GetUUID", &ScriptFileEntry::internal_GetUUID);
 		metaData.scriptClass->addInternalCall("Internal_GetUUID", &ScriptFileEntry::internal_GetUUID);
 		metaData.scriptClass->addInternalCall("Internal_GetIcon", &ScriptFileEntry::internal_GetIcon);
 		metaData.scriptClass->addInternalCall("Internal_GetIcon", &ScriptFileEntry::internal_GetIcon);
 		metaData.scriptClass->addInternalCall("Internal_GetResourceType", &ScriptFileEntry::internal_GetResourceType);
 		metaData.scriptClass->addInternalCall("Internal_GetResourceType", &ScriptFileEntry::internal_GetResourceType);
+		metaData.scriptClass->addInternalCall("Internal_GetIncludeInBuild", &ScriptFileEntry::internal_GetIncludeInBuild);
 	}
 	}
 
 
 	MonoObject* ScriptFileEntry::internal_GetImportOptions(ScriptFileEntry* thisPtr)
 	MonoObject* ScriptFileEntry::internal_GetImportOptions(ScriptFileEntry* thisPtr)
@@ -386,7 +395,11 @@ namespace BansheeEngine
 			return nullptr;
 			return nullptr;
 
 
 		ProjectLibrary::ResourceEntry* fileEntry = static_cast<ProjectLibrary::ResourceEntry*>(entry);
 		ProjectLibrary::ResourceEntry* fileEntry = static_cast<ProjectLibrary::ResourceEntry*>(entry);
-		return ScriptImportOptions::create(fileEntry->meta->getImportOptions());
+
+		if (fileEntry->meta != nullptr)
+			return ScriptImportOptions::create(fileEntry->meta->getImportOptions());
+		else
+			return nullptr;
 	}
 	}
 
 
 	MonoString* ScriptFileEntry::internal_GetUUID(ScriptFileEntry* thisPtr)
 	MonoString* ScriptFileEntry::internal_GetUUID(ScriptFileEntry* thisPtr)
@@ -396,7 +409,11 @@ namespace BansheeEngine
 			return nullptr;
 			return nullptr;
 
 
 		ProjectLibrary::ResourceEntry* fileEntry = static_cast<ProjectLibrary::ResourceEntry*>(entry);
 		ProjectLibrary::ResourceEntry* fileEntry = static_cast<ProjectLibrary::ResourceEntry*>(entry);
-		return MonoUtil::stringToMono(MonoManager::instance().getDomain(), fileEntry->meta->getUUID());
+
+		if (fileEntry->meta != nullptr)
+			return MonoUtil::stringToMono(MonoManager::instance().getDomain(), fileEntry->meta->getUUID());
+		else
+			return nullptr;
 	}
 	}
 
 
 	MonoObject* ScriptFileEntry::internal_GetIcon(ScriptFileEntry* thisPtr)
 	MonoObject* ScriptFileEntry::internal_GetIcon(ScriptFileEntry* thisPtr)
@@ -418,4 +435,18 @@ namespace BansheeEngine
 
 
 		return ScriptResourceType::Undefined;
 		return ScriptResourceType::Undefined;
 	}
 	}
+
+	bool ScriptFileEntry::internal_GetIncludeInBuild(ScriptFileEntry* thisPtr)
+	{
+		ProjectLibrary::LibraryEntry* entry = ProjectLibrary::instance().findEntry(thisPtr->getAssetPath());
+		if (entry == nullptr || entry->type != ProjectLibrary::LibraryEntryType::File)
+			return false;
+
+		ProjectLibrary::ResourceEntry* fileEntry = static_cast<ProjectLibrary::ResourceEntry*>(entry);
+
+		if (fileEntry->meta != nullptr)
+			return fileEntry->meta->getIncludeInBuild();
+
+		return false;
+	}
 }
 }

+ 71 - 0
SBansheeEngine/Include/BsGameResourceManager.h

@@ -0,0 +1,71 @@
+#pragma once
+
+#include "BsScriptEnginePrerequisites.h"
+#include "BsModule.h"
+
+namespace BansheeEngine
+{
+	/**
+	 * @brief	Interface that can be implemented by the resource loaders required
+	 *			by GameResources.
+	 */
+	class BS_SCR_BE_EXPORT IGameResourceLoader
+	{
+	public:
+		virtual ~IGameResourceLoader() { }
+
+		/**
+		 * @brief	Loads the resource at the specified path.
+		 */
+		virtual HResource load(const Path& path) const = 0;
+	};
+
+	/**
+	 * @brief	Handles loading of game resources when the standalone game is running.
+	 */
+	class BS_SCR_BE_EXPORT StandaloneResourceLoader : public IGameResourceLoader
+	{
+	public:
+		/**
+		 * @copydoc	IGameResourceLoader::load
+		 */
+		HResource load(const Path& path) const override;
+	};
+
+	/**
+	 * @brief	Keeps track of resources that can be dynamically loaded
+	 *			during runtime. These resources will be packed with the game
+	 *			build so that they're available on demand.
+	 *
+	 *			Internal resource handle can be overridden so that editor or other
+	 *			systems can handle resource loading more directly.
+	 */
+	class BS_SCR_BE_EXPORT GameResourceManager : public Module<GameResourceManager>
+	{
+	public:
+		GameResourceManager();
+
+		/**
+		 * @brief	Loads the resource at the specified path.
+		 */
+		HResource load(const Path& path) const;	
+
+		/**
+		 * @copydoc	load
+		 */
+		template <class T>
+		ResourceHandle<T> load(const Path& filePath)
+		{
+			return static_resource_cast<T>(load(filePath));
+		}
+
+		/**
+		 * @brief	Sets the resource loader implementation that determines how are the
+		 *			paths provided to ::load loaded.
+		 */
+		void setLoader(const SPtr<IGameResourceLoader>& loader);
+
+	private:
+		SPtr<IGameResourceLoader> mLoader;
+	};
+}

+ 26 - 0
SBansheeEngine/Include/BsScriptResources.h

@@ -0,0 +1,26 @@
+#pragma once
+
+#include "BsScriptEnginePrerequisites.h"
+#include "BsScriptObject.h"
+
+namespace BansheeEngine
+{
+	/**
+	 * @brief	Interop class between C++ & CLR for Resources & GameResourceManager.
+	 */
+	class BS_SCR_BE_EXPORT ScriptResources : public ScriptObject<ScriptResources>
+	{
+	public:
+		SCRIPT_OBJ(ENGINE_ASSEMBLY, "BansheeEngine", "Resources")
+
+	private:
+		ScriptResources(MonoObject* instance);
+
+		/************************************************************************/
+		/* 								CLR HOOKS						   		*/
+		/************************************************************************/
+		static MonoObject* internal_Load(MonoString* path);
+		static void internal_Unload(ScriptResourceBase* resourcePtr);
+		static void internal_UnloadUnused();
+	};
+}

+ 4 - 0
SBansheeEngine/SBansheeEngine.vcxproj

@@ -232,6 +232,7 @@
     </Link>
     </Link>
   </ItemDefinitionGroup>
   </ItemDefinitionGroup>
   <ItemGroup>
   <ItemGroup>
+    <ClInclude Include="Include\BsGameResourceManager.h" />
     <ClInclude Include="Include\BsManagedComponent.h" />
     <ClInclude Include="Include\BsManagedComponent.h" />
     <ClInclude Include="Include\BsManagedComponentRTTI.h" />
     <ClInclude Include="Include\BsManagedComponentRTTI.h" />
     <ClInclude Include="Include\BsManagedDiff.h" />
     <ClInclude Include="Include\BsManagedDiff.h" />
@@ -306,6 +307,7 @@
     <ClInclude Include="Include\BsScriptRenderTexture2D.h" />
     <ClInclude Include="Include\BsScriptRenderTexture2D.h" />
     <ClInclude Include="Include\BsScriptResource.h" />
     <ClInclude Include="Include\BsScriptResource.h" />
     <ClInclude Include="Include\BsScriptResourceManager.h" />
     <ClInclude Include="Include\BsScriptResourceManager.h" />
+    <ClInclude Include="Include\BsScriptResources.h" />
     <ClInclude Include="Include\BsScriptScene.h" />
     <ClInclude Include="Include\BsScriptScene.h" />
     <ClInclude Include="Include\BsScriptSceneObject.h" />
     <ClInclude Include="Include\BsScriptSceneObject.h" />
     <ClInclude Include="Include\BsManagedSerializableObjectInfoRTTI.h" />
     <ClInclude Include="Include\BsManagedSerializableObjectInfoRTTI.h" />
@@ -334,6 +336,7 @@
     <ClInclude Include="Include\BsScriptVirtualInput.h" />
     <ClInclude Include="Include\BsScriptVirtualInput.h" />
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
+    <ClCompile Include="Source\BsGameResourceManager.cpp" />
     <ClCompile Include="Source\BsManagedComponent.cpp" />
     <ClCompile Include="Source\BsManagedComponent.cpp" />
     <ClCompile Include="Source\BsManagedDiff.cpp" />
     <ClCompile Include="Source\BsManagedDiff.cpp" />
     <ClCompile Include="Source\BsManagedResource.cpp" />
     <ClCompile Include="Source\BsManagedResource.cpp" />
@@ -395,6 +398,7 @@
     <ClCompile Include="Source\BsScriptRenderTexture2D.cpp" />
     <ClCompile Include="Source\BsScriptRenderTexture2D.cpp" />
     <ClCompile Include="Source\BsScriptResource.cpp" />
     <ClCompile Include="Source\BsScriptResource.cpp" />
     <ClCompile Include="Source\BsScriptResourceManager.cpp" />
     <ClCompile Include="Source\BsScriptResourceManager.cpp" />
+    <ClCompile Include="Source\BsScriptResources.cpp" />
     <ClCompile Include="Source\BsScriptScene.cpp" />
     <ClCompile Include="Source\BsScriptScene.cpp" />
     <ClCompile Include="Source\BsScriptSceneObject.cpp" />
     <ClCompile Include="Source\BsScriptSceneObject.cpp" />
     <ClCompile Include="Source\BsManagedSerializableArray.cpp" />
     <ClCompile Include="Source\BsManagedSerializableArray.cpp" />

+ 12 - 0
SBansheeEngine/SBansheeEngine.vcxproj.filters

@@ -333,6 +333,12 @@
     <ClInclude Include="Include\BsScriptGUISkin.h">
     <ClInclude Include="Include\BsScriptGUISkin.h">
       <Filter>Header Files\GUI</Filter>
       <Filter>Header Files\GUI</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="Include\BsGameResourceManager.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsScriptResources.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsScriptTexture2D.cpp">
     <ClCompile Include="Source\BsScriptTexture2D.cpp">
@@ -605,5 +611,11 @@
     <ClCompile Include="Source\BsScriptGUISkin.cpp">
     <ClCompile Include="Source\BsScriptGUISkin.cpp">
       <Filter>Source Files\GUI</Filter>
       <Filter>Source Files\GUI</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="Source\BsGameResourceManager.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsScriptResources.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
 </Project>
 </Project>

+ 29 - 0
SBansheeEngine/Source/BsGameResourceManager.cpp

@@ -0,0 +1,29 @@
+#include "BsGameResourceManager.h"
+#include "BsResources.h"
+
+namespace BansheeEngine
+{
+	HResource StandaloneResourceLoader::load(const Path& path) const
+	{
+		return gResources().load(path);
+	}
+
+	GameResourceManager::GameResourceManager()
+		:mLoader(bs_shared_ptr_new<StandaloneResourceLoader>())
+	{
+		
+	}
+
+	HResource GameResourceManager::load(const Path& path) const
+	{
+		return mLoader->load(path);
+	}
+
+	void GameResourceManager::setLoader(const SPtr<IGameResourceLoader>& loader)
+	{
+		mLoader = loader;
+
+		if (mLoader == nullptr)
+			mLoader = bs_shared_ptr_new<StandaloneResourceLoader>();
+	}
+}

+ 3 - 0
SBansheeEngine/Source/BsScriptEnginePlugin.cpp

@@ -9,6 +9,7 @@
 #include "BsScriptInput.h"
 #include "BsScriptInput.h"
 #include "BsScriptVirtualInput.h"
 #include "BsScriptVirtualInput.h"
 #include "BsScriptObjectManager.h"
 #include "BsScriptObjectManager.h"
+#include "BsGameResourceManager.h"
 #include "BsApplication.h"
 #include "BsApplication.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
@@ -28,6 +29,7 @@ namespace BansheeEngine
 
 
 		// TODO - Load Game assembly (gApplication().getGameAssemblyPath())
 		// TODO - Load Game assembly (gApplication().getGameAssemblyPath())
 
 
+		GameResourceManager::startUp();
 		ScriptObjectManager::startUp();
 		ScriptObjectManager::startUp();
 		ManagedResourceManager::startUp();
 		ManagedResourceManager::startUp();
 		ScriptAssemblyManager::startUp();
 		ScriptAssemblyManager::startUp();
@@ -60,5 +62,6 @@ namespace BansheeEngine
 		ScriptResourceManager::shutDown();
 		ScriptResourceManager::shutDown();
 		ScriptAssemblyManager::shutDown();
 		ScriptAssemblyManager::shutDown();
 		ScriptObjectManager::shutDown();
 		ScriptObjectManager::shutDown();
+		GameResourceManager::shutDown();
 	}
 	}
 }
 }

+ 47 - 0
SBansheeEngine/Source/BsScriptResources.cpp

@@ -0,0 +1,47 @@
+#include "BsScriptResources.h"
+#include "BsMonoManager.h"
+#include "BsMonoClass.h"
+#include "BsMonoMethod.h"
+#include "BsMonoUtil.h"
+#include "BsResources.h"
+#include "BsGameResourceManager.h"
+#include "BsScriptResourceManager.h"
+#include "BsScriptResource.h"
+
+namespace BansheeEngine
+{
+	ScriptResources::ScriptResources(MonoObject* instance)
+		:ScriptObject(instance)
+	{ }
+
+	void ScriptResources::initRuntimeData()
+	{
+		metaData.scriptClass->addInternalCall("Internal_Load", &ScriptResources::internal_Load);
+		metaData.scriptClass->addInternalCall("Internal_Unload", &ScriptResources::internal_Unload);
+		metaData.scriptClass->addInternalCall("Internal_UnloadUnused", &ScriptResources::internal_UnloadUnused);
+	}
+
+	MonoObject* ScriptResources::internal_Load(MonoString* path)
+	{
+		Path nativePath = MonoUtil::monoToWString(path);
+
+		HResource resource = GameResourceManager::instance().load(nativePath);
+		if (resource == nullptr)
+			return nullptr;
+
+		ScriptResourceBase* scriptResource;
+		ScriptResourceManager::instance().getScriptResource(resource, &scriptResource, true);
+
+		return scriptResource->getManagedInstance();
+	}
+
+	void ScriptResources::internal_Unload(ScriptResourceBase* resourcePtr)
+	{
+		gResources().unload(resourcePtr->getNativeHandle());
+	}
+
+	void ScriptResources::internal_UnloadUnused()
+	{
+		gResources().unloadAllUnused();
+	}
+}

+ 16 - 2
SBansheeEngine/Source/BsScriptScene.cpp

@@ -6,7 +6,9 @@
 #include "BsSceneManager.h"
 #include "BsSceneManager.h"
 #include "BsResources.h"
 #include "BsResources.h"
 #include "BsPrefab.h"
 #include "BsPrefab.h"
+#include "BsApplication.h"
 #include "BsSceneObject.h"
 #include "BsSceneObject.h"
+#include "BsGameResourceManager.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
@@ -24,8 +26,20 @@ namespace BansheeEngine
 	{
 	{
 		Path nativePath = MonoUtil::monoToWString(path);
 		Path nativePath = MonoUtil::monoToWString(path);
 
 
-		HPrefab prefab = gResources().load<Prefab>(nativePath);
-		HSceneObject root = prefab->instantiate();
+		HPrefab prefab = GameResourceManager::instance().load<Prefab>(nativePath);
+		if (prefab.isLoaded(false))
+		{
+			HSceneObject root = prefab->instantiate();
+
+			UINT32 numChildren = root->getNumChildren();
+			for (UINT32 i = 0; i < numChildren; i++)
+			{
+				HSceneObject child = root->getChild(0);
+				child->setParent(gSceneManager().getRootNode());
+			}
+
+			root->destroy();
+		}
 
 
 		MonoString* uuid = MonoUtil::stringToMono(MonoManager::instance().getDomain(), prefab.getUUID());
 		MonoString* uuid = MonoUtil::stringToMono(MonoManager::instance().getDomain(), prefab.getUUID());
 
 

+ 55 - 86
TODO.txt

@@ -40,8 +40,6 @@ Add "dirty object" system to C#. Each ScriptResource and ScriptGameObject should
     to use those some points for undo/redo
     to use those some points for undo/redo
 
 
  Test (likely later once I have more editor functionality working):
  Test (likely later once I have more editor functionality working):
-  - If level save/load works
-  - If drag and drop works, both ways, plus double-click to load level
   - Game object handle compare
   - Game object handle compare
   - ID restore systems 
   - ID restore systems 
   - Native+Managed diff (only the link between the two)
   - Native+Managed diff (only the link between the two)
@@ -56,13 +54,16 @@ Polish
 
 
 Test:
 Test:
  - If level load works by doing main menu -> Load
  - If level load works by doing main menu -> Load
-  - This should clear existing level
-  - Internal scene objects should remain
  - If level prefab instantiation works by dragging it from project to scene
  - If level prefab instantiation works by dragging it from project to scene
- - When starting drag from hierarchy tree view it tends to select another object (can't repro)
+ - Loaded scene doesn't display the mesh
+   - Presumably this is because we construct that mesh manually without persisting its resources (it should work if level is saved and loaded during the same run)
+ - Loaded scene test component has empty values
+ - Finish up ScriptScene.Load - it doesn't work when given relative paths
 
 
 Ribek use:
 Ribek use:
  - Hook up color picker to guicolor field
  - Hook up color picker to guicolor field
+ - Move forward in scene view doesn't work because the W tool handle shortcut messes with it
+ - When starting drag from hierarchy tree view it tends to select another object (can't repro)
  - Camera, Renderable, Material, Texture inspector
  - Camera, Renderable, Material, Texture inspector
  - Project create/open window
  - Project create/open window
  - Load default layout on initial start
  - Load default layout on initial start
@@ -82,8 +83,6 @@ First screenshot:
  - (Optionally) Console window
  - (Optionally) Console window
 
 
 Other polish:
 Other polish:
- - CmdRecordSO records an SO and all its children but it should only record a single SO
-   - Also it doesn't record a diff, but instead the whole object
  - Crash on shutdown in mono_gchandle_free
  - Crash on shutdown in mono_gchandle_free
  - C# inspectors for Point/Spot/Directional light
  - C# inspectors for Point/Spot/Directional light
  - C# interface for Font
  - C# interface for Font
@@ -95,7 +94,6 @@ Other polish:
    - This has to work not only when I come back to the object, but whenever inspector rebuilds (e.g. after removing element from array)
    - This has to work not only when I come back to the object, but whenever inspector rebuilds (e.g. after removing element from array)
    - Consider saving this information with the serialized object
    - Consider saving this information with the serialized object
  - Make sure to persist EditorSettings
  - Make sure to persist EditorSettings
- - Doubleclick on a prefab in Project should open that level
  - Import option inspectors for Texture, Mesh, Font
  - Import option inspectors for Texture, Mesh, Font
  - Update GUISlider so it works with the new style (and to have min/max limits, plus step size)
  - Update GUISlider so it works with the new style (and to have min/max limits, plus step size)
  - Add "focus on object" key (F) - animate it: rotate camera towards then speed towards while zooming in
  - Add "focus on object" key (F) - animate it: rotate camera towards then speed towards while zooming in
@@ -115,18 +113,11 @@ Stage 2 polish:
  - C# script compiling in editor
  - C# script compiling in editor
  - VS integration
  - VS integration
  - When managed exception happens log an error and continue execution
  - When managed exception happens log an error and continue execution
- - Game publishing (Build window, collect resources, output exe, default viewport)
+ - Game publishing (Build window, collect resources, output exe, default viewport) (described below)
 
 
 Finalizing:
 Finalizing:
  - Add copyright notices in all files & change license to GPL
  - Add copyright notices in all files & change license to GPL
  - UseCustomInspector isn't implemented
  - UseCustomInspector isn't implemented
- - I could record undo/redo per-property using the new diff system
- - When building game make sure to go over texture resources and ensure they are saved in the valid format
-   as we don't want to do format conversion at runtime (Not cruical, but it should be done eventually)
-   - This should something similar to Unity where when changing the platform all resources get reimported
- - When building level for release make sure to clear all prefab diffs (possibly store them elsewhere in the first place)
-   - And all prefab instances should have updateFromPrefab called on them.
- - Undo/Redo when breaking or reverting a scene object (and in general test & finalize undo/redo system)
  - Move all the code files into subfolders so their hierarchy is similar to VS filters
  - Move all the code files into subfolders so their hierarchy is similar to VS filters
  - Splash screen
  - Splash screen
  - Settings/Preferences window
  - Settings/Preferences window
@@ -134,73 +125,27 @@ Finalizing:
  - Need to generate a proper merge of dev and preview branches
  - Need to generate a proper merge of dev and preview branches
  - Save/Load project menu item does nothing at the moment
  - Save/Load project menu item does nothing at the moment
  - (Optionally) GUI tabbing to switch between elements
  - (Optionally) GUI tabbing to switch between elements
+ - Undo/Redo
+  - CmdRecordSO records an SO and all its children but it should only record a single SO
+  - CmdRecordSO should instead of recording the entire object record a diff
+  - There should be a CmdRecordSO equivalent for resources (probably)
+  - Add commands for breaking or reverting a scene object 
+  - Test & finalize undo/redo system
 
 
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
-Resources
- - Load/Unload/UnloadUnused
- - Uses same paths as ProjectLibrary
- - It uses different logic depending on Application.isEditor
-   - If not in editor then a different path is used
-   - That path is ..\..\Data (relative to the executable)
-   - When in editor it also does special ProjectLibrary check to ensure that resource is included in final project
- - Internally just calls Resources (C++) Load/Unload/UnloadUnused
- - Need a flag in ProjectLibrary to include a resource in the final build
-   - Need to be able to set that flag from C# (Likely through ProjectLibrary) interface
- - The final build procedure for the game would then be:
+Build system
+ - Test Resources (if loading works and if they're properly packaged in build)
+ - The final build procedure for the game should be:
    - Copy all the prebuilt binaries (Banshee libraries, Banshee assemblies, 3rd party libraries and prebuilt executable) from Editor install folder to output folder
    - Copy all the prebuilt binaries (Banshee libraries, Banshee assemblies, 3rd party libraries and prebuilt executable) from Editor install folder to output folder
     - Which set of binaries is used depends on selected platform (e.g. win/mac/linux or 32/64bit)
     - Which set of binaries is used depends on selected platform (e.g. win/mac/linux or 32/64bit)
    - Recompile script assemblies if needed and copy them from project Internal folder to output folder
    - Recompile script assemblies if needed and copy them from project Internal folder to output folder
    - Copy the Builtin resources for engine from Editor install folder to output folder
    - Copy the Builtin resources for engine from Editor install folder to output folder
    - Copy all the resources marked with the flag mentioned above to \Data subfolder in the output folder, preserving the same asset structure
    - Copy all the resources marked with the flag mentioned above to \Data subfolder in the output folder, preserving the same asset structure
-
-----------------------------------------------------------------------
-Project window
-
-Later:
- - Might need to improve search (need to test). Do multiple search keywords work properly?
- - Consider delaying search until user stops pressing keys (so not to have thousands of search results in the initial stages)
- - Save & restore scroll position when Refresh happens
-
-----------------------------------------------------------------------
-Handles
-
-Ideally free scale handle indicator should always render and be interactable and never be hidden by axis scale indicators (Not high priority)
-
-Later:
- - Raycast snapping Ribek suggested
-
-----------------------------------------------------------------------
-Include files:
-
-Test:
- - Test if default values work
- - Test project library dependant resources (e.g. changing an include and seeing if shader is reimported)
-
-----------------------------------------------------------------------
-Scene View
-
-Test:
- - Custom handles from C#
- - Handle snapping
- - Multi-select Move/Rotate/scale
-
-----------------------------------------------------------------------
-Undo/Redo C#
-
-UndoRedo class
- - RegisterCommand(cmd, operationName)
- - pushGroup
- - popGroup
- - undo
- - redo
- - clear
-
-RecordObjectCommand
- - Saves the entire object and at the end of the frame performs a diff of the object to actually generate the undo operation
- - Must work for scene objects, components and resources
-SetParentCommand - For reparenting scene objects
-AddComponentCommand
-DestroyCommand - for destroying scene objects or components
+   - Make sure to go over texture resources and ensure they are saved in the valid format
+     as we don't want to do format conversion at runtime (Not cruical, but it should be done eventually)
+     - This should something similar to Unity where when changing the platform all resources get reimported
+   - Make sure to clear all prefab diffs (possibly store them elsewhere in the first place)
+	 - And all prefab instances should have updateFromPrefab called on them.
 
 
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 Other
 Other
@@ -236,25 +181,49 @@ Mono cannot marshal structures? Taken from their documentation:
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 MenuItem
 MenuItem
 
 
-LATER: Add keyboard controls to GUIMenuBar (left/right arrows should move between entries if user is not browsing a sub-menu)
- - esc should cancel out of the menu bar
- - alt should focus the menu bar
+ - Add keyboard controls to GUIMenuBar (left/right arrows should move between entries if user is not browsing a sub-menu)
+  - esc should cancel out of the menu bar
+  - alt should focus the menu bar
 
 
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 VisualStudio integration
 VisualStudio integration
 
 
-VS integration will likely not work with VSExpress or Community edition
- - VSExpress doesn't support EnvDTE so the only option is to open it using a shell command which doesn't seem to offer precise parameters
- - Community edition should work similarily to Pro, but might have a different executable and/or registry paths
-
-For later:
+ - VS integration will likely not work with VSExpress or Community edition
+  - VSExpress doesn't support EnvDTE so the only option is to open it using a shell command which doesn't seem to offer precise parameters
+  - Community edition should work similarily to Pro, but might have a different executable and/or registry paths
  - Make sure that 3rd party assemblies can be imported in the project, and that they are properly referenced in VS project generation and compilation
  - Make sure that 3rd party assemblies can be imported in the project, and that they are properly referenced in VS project generation and compilation
 
 
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 Script compilation
 Script compilation
 
 
-For later:
  - I need to hook up script compilation with assembly refresh, and the build system.
  - I need to hook up script compilation with assembly refresh, and the build system.
    - e.g. when recompiling inside the editor it should automatically start compiling when changes are detected,
    - e.g. when recompiling inside the editor it should automatically start compiling when changes are detected,
      show some kind of visual indicator and refresh assemblies when its done. When publishing it should recompile
      show some kind of visual indicator and refresh assemblies when its done. When publishing it should recompile
-	 assemblies for release. Also hook up console to compiler output?
+	 assemblies for release. Also hook up console to compiler output?
+
+----------------------------------------------------------------------
+Project window
+
+ - Might need to improve search (need to test). Do multiple search keywords work properly?
+ - Consider delaying search until user stops pressing keys (so not to have thousands of search results in the initial stages)
+ - Save & restore scroll position when Refresh happens
+
+----------------------------------------------------------------------
+Handles
+
+ - Ideally free scale handle indicator should always render and be interactable and never be hidden by axis scale indicators (Not high priority)
+ - Raycast snapping Ribek suggested
+
+----------------------------------------------------------------------
+Include files:
+
+ - Test if default values work
+ - Test project library dependant resources (e.g. changing an include and seeing if shader is reimported)
+
+----------------------------------------------------------------------
+Scene View
+
+Test:
+ - Custom handles from C#
+ - Handle snapping
+ - Multi-select Move/Rotate/scale