Explorar o código

Added a way to load resources from C# ProjectLibrary

Marko Pintera %!s(int64=11) %!d(string=hai) anos
pai
achega
a4e65a67d8

+ 2 - 3
BansheeEditor/Source/BsProjectLibrary.cpp

@@ -501,10 +501,9 @@ namespace BansheeEngine
 		if (resource == nullptr)
 			return;
 
-		if (!mResourcesFolder.includes(path))
-			BS_EXCEPT(InvalidParametersException, "Provided path is not within the project library directory: " + path.toString());
+		Path assetPath = mResourcesFolder;
+		assetPath.append(path);
 
-		Path assetPath = path;
 		assetPath.setExtension(assetPath.getWExtension() + L"." + ResourceImporter::DEFAULT_EXTENSION);
 
 		LibraryEntry* existingEntry = findEntry(assetPath);

+ 1 - 1
MBansheeEditor/Program.cs

@@ -23,7 +23,7 @@ namespace BansheeEditor
             gizmoDbgObject.AddComponent<DbgGizmoComponent>();
 
             DbgResource testResource = new DbgResource();
-            //ProjectLibrary.Create(testResource, @"D:\DummyBansheeProject\Resources\testResource");
+            //ProjectLibrary.Create(testResource, @"testResource");
 
 
 

+ 15 - 4
MBansheeEditor/ProjectLibrary.cs

@@ -1,9 +1,6 @@
 using System;
-using System.Collections.Generic;
-using System.Linq;
+using System.IO;
 using System.Runtime.CompilerServices;
-using System.Text;
-using System.Threading.Tasks;
 using BansheeEngine;
 
 namespace BansheeEditor
@@ -12,9 +9,20 @@ namespace BansheeEditor
     {
         public static void Create(Resource resource, string path)
         {
+            if (Path.IsPathRooted(path))
+                throw new ArgumentException("Provided path must be relative.", "path");
+
             Internal_Create(resource, path);
         }
 
+        public static T Load<T>(string path) where T : Resource
+        {
+            if (Path.IsPathRooted(path))
+                throw new ArgumentException("Provided path must be relative.", "path");
+
+            return (T) Internal_Load(path);
+        }
+
         // TODO - Will also need (at least):
         // - GetPath
         // - Reimport
@@ -27,5 +35,8 @@ namespace BansheeEditor
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_Create(Resource resource, string path);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern Resource Internal_Load(string path);
     }
 }

+ 1 - 0
SBansheeEditor/Include/BsScriptProjectLibrary.h

@@ -13,6 +13,7 @@ namespace BansheeEngine
 
 	private:
 		static void internal_Create(MonoObject* resource, MonoString* path);
+		static MonoObject* internal_Load(MonoString* path);
 
 		ScriptProjectLibrary(MonoObject* instance);
 	};

+ 31 - 0
SBansheeEditor/Source/BsScriptProjectLibrary.cpp

@@ -6,6 +6,13 @@
 #include "BsMonoUtil.h"
 #include "BsProjectLibrary.h"
 #include "BsScriptResource.h"
+#include "BsResources.h"
+#include "BsResource.h"
+#include "BsProjectResourceMeta.h"
+#include "BsScriptResourceManager.h"
+#include "BsScriptTexture2D.h"
+#include "BsScriptSpriteTexture.h"
+#include "BsScriptFont.h"
 
 namespace BansheeEngine
 {
@@ -16,6 +23,7 @@ namespace BansheeEngine
 	void ScriptProjectLibrary::initRuntimeData()
 	{
 		metaData.scriptClass->addInternalCall("Internal_Create", &ScriptProjectLibrary::internal_Create);
+		metaData.scriptClass->addInternalCall("Internal_Load", &ScriptProjectLibrary::internal_Load);
 	}
 
 	void ScriptProjectLibrary::internal_Create(MonoObject* resource, MonoString* path)
@@ -25,4 +33,27 @@ namespace BansheeEngine
 
 		ProjectLibrary::instance().createEntry(scrResource->getNativeHandle(), resourcePath);
 	}
+
+	MonoObject* ScriptProjectLibrary::internal_Load(MonoString* path)
+	{
+		Path resourcePath = MonoUtil::monoToWString(path);
+
+		ProjectLibrary::LibraryEntry* entry = ProjectLibrary::instance().findEntry(resourcePath);
+
+		if (entry == nullptr || entry->type == ProjectLibrary::LibraryEntryType::Directory)
+			return nullptr;
+
+		ProjectLibrary::ResourceEntry* resEntry = static_cast<ProjectLibrary::ResourceEntry*>(entry);
+		String resUUID = resEntry->meta->getUUID();
+
+		HResource resource = Resources::instance().loadFromUUID(resUUID);
+		if (!resource)
+			return nullptr;
+
+		ScriptResourceBase* scriptResource = ScriptResourceManager::instance().getScriptResource(resUUID);
+		if (scriptResource == nullptr)
+			scriptResource = ScriptResourceManager::instance().createScriptResource(resource);
+
+		return scriptResource->getManagedInstance();
+	}
 }

+ 8 - 4
SBansheeEngine/Include/BsScriptFont.h

@@ -1,24 +1,28 @@
 #pragma once
 
 #include "BsScriptEnginePrerequisites.h"
+#include "BsScriptResource.h"
 #include "BsScriptObject.h"
 #include "BsFont.h"
 
 namespace BansheeEngine
 {
-	class BS_SCR_BE_EXPORT ScriptFont : public ScriptObject<ScriptFont>
+	class BS_SCR_BE_EXPORT ScriptFont : public ScriptObject<ScriptFont, ScriptResourceBase>
 	{
 	public:
 		SCRIPT_OBJ(BansheeEngineAssemblyName, "BansheeEngine", "Font")
 
-		void* getNativeRaw() const;
-		const HFont& getInternalValue() const { return mFont; }
+		void* getNativeRaw() const { return mFont.get(); }
 
+		HResource getNativeHandle() const { return mFont; }
+		void setNativeHandle(const HResource& resource);
 	private:
-		static void internal_createInstanceExternal(MonoObject* instance, const HFont& font);
+		friend class ScriptResourceManager;
 
 		ScriptFont(MonoObject* instance, const HFont& font);
 
+		void _onManagedInstanceDeleted();
+
 		HFont mFont;
 	};
 }

+ 2 - 1
SBansheeEngine/Include/BsScriptGUIElementStyle.h

@@ -32,7 +32,8 @@ namespace BansheeEngine
 		static void internal_createInstanceExternal(MonoObject* instance, MonoString* name, GUIElementStyle* externalStyle);
 		static void internal_addSubStyle(ScriptGUIElementStyle* nativeInstance, MonoString* guiType, MonoString* styleName);
 
-		BS_SCRIPT_GETSET_OBJECT_SHRDPTR(ScriptGUIElementStyle, ScriptFont, Font, mElementStyle->font, mFont);
+		static void internal_GetFont(ScriptGUIElementStyle* nativeInstance, MonoObject** value);
+		static void internal_SetFont(ScriptGUIElementStyle* nativeInstance, MonoObject* value);
 
 		BS_SCRIPT_GETSET_VALUE(ScriptGUIElementStyle, UINT32, FontSize, mElementStyle->fontSize);
 		BS_SCRIPT_GETSET_VALUE(ScriptGUIElementStyle, TextHorzAlign, TextHorzAlign, mElementStyle->textHorzAlign);

+ 18 - 0
SBansheeEngine/Include/BsScriptResourceManager.h

@@ -35,6 +35,18 @@ namespace BansheeEngine
 		 */
 		ScriptSpriteTexture* createScriptSpriteTexture(MonoObject* existingInstance, const HSpriteTexture& resourceHandle);
 
+		/**
+		 * @note Throws an exception if resource for the handle already exists.
+		 * 		 Creates a new managed instance of the object.
+		 */
+		ScriptFont* createScriptFont(const HFont& resourceHandle);
+
+		/**
+		 * @note Throws an exception if resource for the handle already exists.
+		 * 		 Initializes the ScriptResource with an existing managed instance.
+		 */
+		ScriptFont* createScriptFont(MonoObject* existingInstance, const HFont& resourceHandle);
+
 		/**
 		* @note  Throws an exception if resource for the handle already exists.
 		* 		 Initializes the ScriptResource with an existing managed instance.
@@ -61,12 +73,18 @@ namespace BansheeEngine
 		 */
 		ScriptResourceBase* getScriptResource(const String& UUID);
 
+		/**
+		 * @note Returns nullptr if script resource doesn't exist.
+		 */
+		ScriptResourceBase* createScriptResource(const HResource& resource);
+
 		void destroyScriptResource(ScriptResourceBase* resource);
 
 	private:
 		UnorderedMap<String, ScriptResourceBase*> mScriptResources;
 		MonoClass* mTextureClass;
 		MonoClass* mSpriteTextureClass;
+		MonoClass* mFontClass;
 
 		void throwExceptionIfInvalidOrDuplicate(const String& uuid) const;
 	};

+ 8 - 6
SBansheeEngine/Source/BsScriptFont.cpp

@@ -4,6 +4,7 @@
 #include "BsMonoClass.h"
 #include "BsMonoManager.h"
 #include "BsSpriteTexture.h"
+#include "BsScriptResourceManager.h"
 
 namespace BansheeEngine
 {
@@ -13,18 +14,19 @@ namespace BansheeEngine
 
 	}
 
-	void* ScriptFont::getNativeRaw() const
+	void ScriptFont::initRuntimeData()
 	{
-		return (void*)mFont.get();
+
 	}
 
-	void ScriptFont::initRuntimeData()
+	void ScriptFont::_onManagedInstanceDeleted()
 	{
-
+		mManagedInstance = nullptr;
+		ScriptResourceManager::instance().destroyScriptResource(this);
 	}
 
-	void ScriptFont::internal_createInstanceExternal(MonoObject* instance, const HFont& font)
+	void ScriptFont::setNativeHandle(const HResource& resource)
 	{
-		ScriptFont* nativeInstance = new (bs_alloc<ScriptFont>()) ScriptFont(instance, font);
+		mFont = static_resource_cast<Font>(resource);
 	}
 }

+ 22 - 1
SBansheeEngine/Source/BsScriptGUIElementStyle.cpp

@@ -36,7 +36,8 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_CreateInstance", &ScriptGUIElementStyle::internal_createInstance);
 		metaData.scriptClass->addInternalCall("Internal_AddSubStyle", &ScriptGUIElementStyle::internal_addSubStyle);
 
-		BS_SCRIPT_SETGET_META(ScriptGUIElementStyle, Font);
+		metaData.scriptClass->addInternalCall("Internal_GetFont", &ScriptGUIElementStyle::internal_GetFont);
+		metaData.scriptClass->addInternalCall("Internal_SetFont", &ScriptGUIElementStyle::internal_SetFont);
 
 		BS_SCRIPT_SETGET_META(ScriptGUIElementStyle, FontSize);
 		BS_SCRIPT_SETGET_META(ScriptGUIElementStyle, TextHorzAlign);
@@ -93,4 +94,24 @@ namespace BansheeEngine
 
 		nativeInstance->getInternalValue()->subStyles[guiTypeStr] = styleNameStr;
 	}
+
+	void ScriptGUIElementStyle::internal_GetFont(ScriptGUIElementStyle* nativeInstance, MonoObject** value)
+	{
+		throwIfInstancesDontMatch(nativeInstance->mFont, nativeInstance->mElementStyle->font.get());
+
+		if (nativeInstance->mFont != nullptr)
+		{
+			*value = nativeInstance->mFont->getManagedInstance();
+			return;
+		}
+
+		*value = nullptr;
+	}
+
+	void ScriptGUIElementStyle::internal_SetFont(ScriptGUIElementStyle* nativeInstance, MonoObject* value)
+	{
+		ScriptFont* nativeValue = ScriptFont::toNative(value);
+		nativeInstance->mElementStyle->font = nativeValue->getNativeHandle();
+		nativeInstance->mFont = nativeValue;
+	}
 }

+ 54 - 0
SBansheeEngine/Source/BsScriptResourceManager.cpp

@@ -4,6 +4,7 @@
 #include "BsMonoClass.h"
 #include "BsScriptTexture2D.h"
 #include "BsScriptSpriteTexture.h"
+#include "BsScriptFont.h"
 #include "BsScriptManagedResource.h"
 
 namespace BansheeEngine
@@ -17,12 +18,16 @@ namespace BansheeEngine
 
 		mTextureClass = assembly->getClass("BansheeEngine", "Texture2D");
 		mSpriteTextureClass = assembly->getClass("BansheeEngine", "SpriteTexture");
+		mFontClass = assembly->getClass("BansheeEngine", "Font");
 
 		if(mTextureClass == nullptr)
 			BS_EXCEPT(InternalErrorException, "Cannot find managed Texture2D class.");
 
 		if(mSpriteTextureClass == nullptr)
 			BS_EXCEPT(InternalErrorException, "Cannot find managed SpriteTexture class.");
+
+		if (mFontClass == nullptr)
+			BS_EXCEPT(InternalErrorException, "Cannot find managed Font class.");
 	}
 
 	ScriptTexture2D* ScriptResourceManager::createScriptTexture(const HTexture& resourceHandle)
@@ -35,7 +40,9 @@ namespace BansheeEngine
 	ScriptTexture2D* ScriptResourceManager::createScriptTexture(MonoObject* instance, const HTexture& resourceHandle)
 	{
 		const String& uuid = resourceHandle.getUUID();
+#if BS_DEBUG_MODE
 		throwExceptionIfInvalidOrDuplicate(uuid);
+#endif
 
 		ScriptTexture2D* scriptResource = new (bs_alloc<ScriptTexture2D>()) ScriptTexture2D(instance, resourceHandle);
 		mScriptResources[uuid] = scriptResource;
@@ -53,7 +60,9 @@ namespace BansheeEngine
 	ScriptSpriteTexture* ScriptResourceManager::createScriptSpriteTexture(MonoObject* instance, const HSpriteTexture& resourceHandle)
 	{
 		const String& uuid = resourceHandle.getUUID();
+#if BS_DEBUG_MODE
 		throwExceptionIfInvalidOrDuplicate(uuid);
+#endif
 
 		ScriptSpriteTexture* scriptResource = new (bs_alloc<ScriptSpriteTexture>()) ScriptSpriteTexture(instance, resourceHandle);
 		mScriptResources[uuid] = scriptResource;
@@ -61,6 +70,26 @@ namespace BansheeEngine
 		return scriptResource;
 	}
 
+	ScriptFont* ScriptResourceManager::createScriptFont(const HFont& resourceHandle)
+	{
+		MonoObject* monoInstance = mFontClass->createInstance();
+
+		return createScriptFont(monoInstance, resourceHandle);
+	}
+
+	ScriptFont* ScriptResourceManager::createScriptFont(MonoObject* instance, const HFont& resourceHandle)
+	{
+		const String& uuid = resourceHandle.getUUID();
+#if BS_DEBUG_MODE
+		throwExceptionIfInvalidOrDuplicate(uuid);
+#endif
+
+		ScriptFont* scriptResource = new (bs_alloc<ScriptFont>()) ScriptFont(instance, resourceHandle);
+		mScriptResources[uuid] = scriptResource;
+
+		return scriptResource;
+	}
+
 	ScriptManagedResource* ScriptResourceManager::createManagedResource(MonoObject* existingInstance, const HManagedResource& resourceHandle)
 	{
 		const String& uuid = resourceHandle.getUUID();
@@ -99,6 +128,31 @@ namespace BansheeEngine
 		return nullptr;
 	}
 
+	ScriptResourceBase* ScriptResourceManager::createScriptResource(const HResource& resource)
+	{
+#if BS_DEBUG_MODE
+		throwExceptionIfInvalidOrDuplicate(resource.getUUID());
+#endif
+
+		UINT32 resTypeID = resource->getTypeId();
+
+		switch (resTypeID)
+		{
+		case TID_Texture:
+			return createScriptTexture(static_resource_cast<Texture>(resource));
+		case TID_SpriteTexture:
+			return createScriptSpriteTexture(static_resource_cast<SpriteTexture>(resource));
+		case TID_Font:
+			return createScriptFont(static_resource_cast<Font>(resource));
+		case TID_ManagedResource:
+			BS_EXCEPT(InternalErrorException, "Managed resources must have a managed instance by default, this call is invalid.")
+				break;
+		default:
+			BS_EXCEPT(NotImplementedException, "Attempting to load a resource type that is not supported. Type ID: " + toString(resTypeID));
+			break;
+		}
+	}
+
 	void ScriptResourceManager::destroyScriptResource(ScriptResourceBase* resource)
 	{
 		HResource resourceHandle = resource->getNativeHandle();

+ 1 - 1
SBansheeEngine/Source/BsScriptSpriteTexture.cpp

@@ -32,6 +32,6 @@ namespace BansheeEngine
 
 	void ScriptSpriteTexture::setNativeHandle(const HResource& resource) 
 	{ 
-		mTexture = static_resource_cast<Resource>(mTexture); 
+		mTexture = static_resource_cast<SpriteTexture>(resource);
 	}
 }

+ 1 - 1
SBansheeEngine/Source/BsScriptTexture2D.cpp

@@ -53,6 +53,6 @@ namespace BansheeEngine
 
 	void ScriptTexture2D::setNativeHandle(const HResource& resource) 
 	{ 
-		mTexture = static_resource_cast<Resource>(mTexture); 
+		mTexture = static_resource_cast<Texture>(resource);
 	}
 }

+ 2 - 2
SceneView.txt

@@ -5,17 +5,16 @@
 	- Then make a Component wrapper around the non-component types, and also a C# wrapper around the same types
 
 TESTING:
- - Depth rendering in scene view on OpenGL is all screwed up
  - Test picking on an object with alpha
  - Ensure that selecting an item in scene properly marks it in scene view
  - Ensure that selecting an item in scene or resource tree view properly updates Selection
 
 Test gizmos
  - Test rendering of icon gizmos
+   - Need a way to load a texture from C# (Extend ProjectLibrary?)
  - HOOK UP GIZMO SELECTION and test it
 
 Test handles
- - Handle rendering might require similar refactor to GizmoManager
  - Test basic move handle
  - Test a custom handle from C#
  - FINISH HANDLE IMPLEMENTATION AND GLUE EVERYTHING TOGHETHER
@@ -24,6 +23,7 @@ IMPLEMENT SELECTION RENDERING
 
 IMPROVE SceneGrid LOOK
  - LIKELY USE PIXEL SceneGrid WITH AA
+ - OR (better) instead of drawing rows and columns of lines, just draw a plane with procedural texture
 
 Need a way to drag and drop items from Scene tree view to Scene view