Browse Source

Project Load/Unload (not tested)

Marko Pintera 10 years ago
parent
commit
fb10aa71f2

+ 5 - 0
BansheeCore/Include/BsResources.h

@@ -148,6 +148,11 @@ namespace BansheeEngine
 		 */
 		void registerResourceManifest(const ResourceManifestPtr& manifest);
 
+		/**
+		 * @brief	Unregisters a resource manifest previously registered with ::registerResourceManifest.
+		 */
+		void unregisterResourceManifest(const ResourceManifestPtr& manifest);
+
 		/**
 		 * @brief	Allows you to retrieve resource manifest containing UUID <-> file path mapping that is
 		 * 			used when resolving resource references.

+ 10 - 0
BansheeCore/Source/BsResources.cpp

@@ -314,6 +314,16 @@ namespace BansheeEngine
 			*findIter = manifest;
 	}
 
+	void Resources::unregisterResourceManifest(const ResourceManifestPtr& manifest)
+	{
+		if (manifest->getName() == "Default")
+			return;
+
+		auto findIter = std::find(mResourceManifests.begin(), mResourceManifests.end(), manifest);
+		if (findIter != mResourceManifests.end())
+			mResourceManifests.erase(findIter);
+	}
+
 	ResourceManifestPtr Resources::getResourceManifest(const String& name) const
 	{
 		for(auto iter = mResourceManifests.rbegin(); iter != mResourceManifests.rend(); ++iter) 

+ 5 - 0
BansheeEditor/Include/BsBuildManager.h

@@ -87,6 +87,11 @@ namespace BansheeEngine
 		 */
 		void load(const Path& inFile);
 
+		/**
+		 * @brief	Clears currently active build settings.
+		 */
+		void clear();
+
 	private:
 		SPtr<BuildData> mBuildData;
 	};

+ 23 - 0
BansheeEditor/Include/BsDockManagerLayoutRTTI.h

@@ -18,6 +18,29 @@ namespace BansheeEngine
 			addPlainField("mRootEntry", 0, &DockManagerLayoutRTTI::getRootEntry, &DockManagerLayoutRTTI::setRootEntry);
 		}
 
+		void onDeserializationEnded(IReflectable* obj) override
+		{
+			DockManagerLayout* layout = static_cast<DockManagerLayout*>(obj);
+
+			Stack<DockManagerLayout::Entry*> todo;
+			todo.push(&layout->mRootEntry);
+
+			while (!todo.empty())
+			{
+				DockManagerLayout::Entry* current = todo.top();
+				todo.pop();
+
+				if (!current->isLeaf)
+				{
+					current->children[0]->parent = current;
+					current->children[1]->parent = current;
+
+					todo.push(current->children[0]);
+					todo.push(current->children[1]);
+				}
+			}
+		}
+
 		virtual const String& getRTTIName() override
 		{
 			static String name = "DockManagerLayout";

+ 43 - 4
BansheeEditor/Include/BsEditorApplication.h

@@ -15,24 +15,24 @@ namespace BansheeEngine
 		virtual ~EditorApplication();
 
 		/**
-		 * @brief	Starts the editorn with the specified render system.
+		 * @brief	Starts the editor with the specified render system.
 		 */
 		static void startUp(RenderAPIPlugin renderAPI);
 
 		/**
 		 * @brief	Checks whether the editor currently has a project loaded.
 		 */
-		bool isProjectLoaded() const;
+		bool isProjectLoaded() const { return mIsProjectLoaded; }
 
 		/**
 		 * @brief	Returns the path to the currently loaded project.
 		 */
-		const Path& getProjectPath() const;
+		const Path& getProjectPath() const { return mProjectPath; }
 
 		/**
 		 * @brief	Returns the name of the currently loaded project.
 		 */
-		const WString& getProjectName() const;
+		const WString& getProjectName() const { return mProjectName; }
 
 		/**
 		 * @brief	Returns the absolute path to the built-in managed editor assembly file.
@@ -72,10 +72,45 @@ namespace BansheeEngine
 		 */
 		void saveProjectSettings();
 
+		/**
+		 * @brief	Unloads the currently loaded project, if any.
+		 */
+		void unloadProject();
+
+		/**
+		 * @brief	Loads a new project, unloading the current one. 
+		 *
+		 * @param	path	Absolute path to the root project folder. Must be pointing
+		 *					to a valid project.
+		 */
+		void loadProject(const Path& path);
+
+		/**
+		 * @brief	Checks is the provided folder a valid project.
+		 *
+		 * @param	path	Absolute path to the root project folder.
+		 */
+		bool isValidProjectPath(const Path& path);
+
 	private:
+		/**
+		 * @copydoc	Module::onStartUp
+		 */
 		virtual void onStartUp() override;
+
+		/**
+		 * @copydoc	Module::onShutDown
+		 */
 		virtual void onShutDown() override;
+
+		/**
+		 * @copydoc	Module::preUpdate
+		 */
 		virtual void preUpdate() override;
+
+		/**
+		 * @copydoc	Module::postUpdate
+		 */
 		virtual void postUpdate() override;
 
 		/**
@@ -117,6 +152,10 @@ namespace BansheeEngine
 		EditorSettingsPtr mEditorSettings;
 		ProjectSettingsPtr mProjectSettings;
 
+		bool mIsProjectLoaded;
+		Path mProjectPath;
+		WString mProjectName;
+
 		DynLib* mSBansheeEditorPlugin;
 
 		// DEBUG ONLY

+ 15 - 8
BansheeEditor/Include/BsProjectLibrary.h

@@ -68,7 +68,7 @@ namespace BansheeEngine
 		};
 
 	public:
-		ProjectLibrary(const Path& projectFolder);
+		ProjectLibrary();
 		~ProjectLibrary();
 
 		/**
@@ -241,22 +241,28 @@ namespace BansheeEngine
 		 */
 		const Path& getResourcesFolder() const { return mResourcesFolder; }
 
-		Event<void(const Path&)> onEntryRemoved; /**< Triggered whenever an entry is removed from the library. Path provided is absolute. */
-		Event<void(const Path&)> onEntryAdded; /**< Triggered whenever an entry is added to the library. Path provided is absolute. */
-	private:
 		/**
 		 * @brief	Saves all the project library data so it may be restored later,
-		 *			at the default save location in the project folder.
+		 *			at the default save location in the project folder. Project
+		 *			must be loaded when calling this.
 		 */
-		void save();
+		void saveLibrary();
 
 		/**
 		 * @brief	Loads previously saved project library data from the default save 
 		 *			location in the project folder. Nothing is loaded if it doesn't
-		 *			exist.
+		 *			exist.Project must be loaded when calling this.
 		 */
-		void load();
+		void loadLibrary();
 
+		/**
+		 * @brief	Clears all library data.
+		 */
+		void unloadLibrary();
+
+		Event<void(const Path&)> onEntryRemoved; /**< Triggered whenever an entry is removed from the library. Path provided is absolute. */
+		Event<void(const Path&)> onEntryAdded; /**< Triggered whenever an entry is added to the library. Path provided is absolute. */
+	private:
 		/**
 		 * @brief	Common code for adding a new resource entry to the library.
 		 *
@@ -379,6 +385,7 @@ namespace BansheeEngine
 		DirectoryEntry* mRootEntry;
 		Path mProjectFolder;
 		Path mResourcesFolder;
+		bool mIsLoaded;
 
 		UnorderedMap<Path, Vector<Path>> mDependencies;
 		UnorderedSet<Path> mReimportQueue;

+ 5 - 0
BansheeEditor/Include/BsUndoRedo.h

@@ -60,6 +60,11 @@ namespace BansheeEngine
 		 */
 		void registerCommand(EditorCommand* command);
 
+		/**
+		 * @brief	Resets the undo/redo stacks.
+		 */
+		void clear();
+
 	private:
 		/**
 		 * @brief	Removes the last undo command from the undo stack, and returns it.

+ 5 - 0
BansheeEditor/Source/BsBuildManager.cpp

@@ -91,6 +91,11 @@ namespace BansheeEngine
 		return getPlatformInfo(type)->defines;
 	}
 
+	void BuildManager::clear()
+	{
+		mBuildData = nullptr;
+	}
+
 	void BuildManager::save(const Path& outFile)
 	{
 		FileEncoder fe(outFile);

+ 52 - 31
BansheeEditor/Source/BsEditorApplication.cpp

@@ -66,7 +66,7 @@ namespace BansheeEngine
 
 	EditorApplication::EditorApplication(RenderAPIPlugin renderAPIPlugin)
 		:Application(createRenderWindowDesc(), renderAPIPlugin, RendererPlugin::Default), 
-		mActiveRAPIPlugin(renderAPIPlugin), mSBansheeEditorPlugin(nullptr)
+		mActiveRAPIPlugin(renderAPIPlugin), mSBansheeEditorPlugin(nullptr), mIsProjectLoaded(false)
 	{
 
 	}
@@ -102,7 +102,7 @@ namespace BansheeEngine
 		Application::onStartUp();
 
 		loadEditorSettings();
-		loadProjectSettings();
+		mProjectSettings = bs_shared_ptr_new<ProjectSettings>();
 
 		BuiltinEditorResources::startUp();
 
@@ -128,7 +128,7 @@ namespace BansheeEngine
 		PrefabImporter* prefabImporter = bs_new<PrefabImporter>();
 		Importer::instance()._registerAssetImporter(prefabImporter);
 
-		ProjectLibrary::startUp(getProjectPath());
+		ProjectLibrary::startUp();
 
 		UndoRedo::startUp();
 		EditorWindowManager::startUp();
@@ -144,12 +144,6 @@ namespace BansheeEngine
 		MainEditorWindow* mainWindow = MainEditorWindow::create(getPrimaryWindow());
 		loadPlugin("SBansheeEditor", &mSBansheeEditorPlugin); // Managed part of the editor
 
-		EditorWidgetLayoutPtr layout = loadWidgetLayout();
-		if (layout != nullptr)
-			EditorWidgetManager::instance().setLayout(layout);
-
-		BuildManager::instance().load(BUILD_DATA_PATH);
-
 		/************************************************************************/
 		/* 								DEBUG CODE                      		*/
 		/************************************************************************/
@@ -212,7 +206,7 @@ namespace BansheeEngine
 
 	void EditorApplication::onShutDown()
 	{
-		BuildManager::instance().save(BUILD_DATA_PATH);
+		unloadProject();
 
 		CodeEditorManager::shutDown();
 		BuildManager::shutDown();
@@ -220,9 +214,7 @@ namespace BansheeEngine
 		Selection::shutDown();
 		ScenePicking::shutDown();
 
-		saveWidgetLayout(EditorWidgetManager::instance().getLayout());
 		saveEditorSettings();
-		saveProjectSettings();
 
 		DropDownWindowManager::shutDown();
 		EditorWidgetManager::shutDown();
@@ -253,25 +245,6 @@ namespace BansheeEngine
 		EditorWindowManager::instance().update();	
 	}
 
-	bool EditorApplication::isProjectLoaded() const
-	{
-		return true; // TODO - DEBUG ONLY
-	}
-
-	const Path& EditorApplication::getProjectPath() const
-	{
-		static Path dummyProjectPath = L"D:\\DummyBansheeProject\\";
-
-		return dummyProjectPath;
-	}
-
-	const WString& EditorApplication::getProjectName() const
-	{
-		static WString dummyProjectName = L"DummyBansheeProject";
-
-		return dummyProjectName;
-	}
-
 	Path EditorApplication::getEditorAssemblyPath() const
 	{
 		Path assemblyPath = getBuiltinAssemblyFolder();
@@ -296,6 +269,54 @@ namespace BansheeEngine
 		return assemblyFolder;
 	}
 
+	void EditorApplication::unloadProject()
+	{
+		if (!isProjectLoaded())
+			return;
+
+		BuildManager::instance().save(BUILD_DATA_PATH);
+		saveWidgetLayout(EditorWidgetManager::instance().getLayout());
+		saveEditorSettings();
+		saveProjectSettings();
+
+		mProjectSettings = bs_shared_ptr_new<ProjectSettings>();
+		BuildManager::instance().clear();
+		UndoRedo::instance().clear();
+
+		ProjectLibrary::instance().saveLibrary();
+		ProjectLibrary::instance().unloadLibrary();
+
+		Resources::instance().unloadAllUnused();
+	}
+
+	void EditorApplication::loadProject(const Path& projectPath)
+	{
+		unloadProject();
+
+		mProjectPath = projectPath;
+		mProjectName = projectPath.getWTail();
+		mIsProjectLoaded = true;
+
+		loadProjectSettings();
+		BuildManager::instance().load(BUILD_DATA_PATH);
+		ProjectLibrary::instance().loadLibrary();
+
+		EditorWidgetLayoutPtr layout = loadWidgetLayout();
+		if (layout != nullptr)
+			EditorWidgetManager::instance().setLayout(layout);
+	}
+
+	bool EditorApplication::isValidProjectPath(const Path& path)
+	{
+		if (!path.isAbsolute())
+			return false;
+
+		if (!FileSystem::isDirectory(path))
+			return false;
+
+		return true;
+	}
+
 	EditorWidgetLayoutPtr EditorApplication::loadWidgetLayout()
 	{
 		Path layoutPath = getProjectPath();

+ 41 - 22
BansheeEditor/Source/BsProjectLibrary.cpp

@@ -12,6 +12,7 @@
 #include "BsDebug.h"
 #include "BsProjectLibraryEntries.h"
 #include "BsResource.h"
+#include "BsEditorApplication.h"
 #include "BsResourceImporter.h"
 #include "BsShader.h"
 #include <regex>
@@ -48,24 +49,14 @@ namespace BansheeEngine
 		:LibraryEntry(path, name, parent, LibraryEntryType::Directory)
 	{ }
 
-	ProjectLibrary::ProjectLibrary(const Path& projectFolder)
-		:mRootEntry(nullptr), mProjectFolder(projectFolder)
+	ProjectLibrary::ProjectLibrary()
+		: mRootEntry(nullptr), mIsLoaded(false)
 	{
-		mResourcesFolder = mProjectFolder;
-		mResourcesFolder.append(RESOURCES_DIR);
-
-		load();
-
-		if(mResourceManifest == nullptr)
-			mResourceManifest = ResourceManifest::create("ProjectLibrary");
-
-		gResources().registerResourceManifest(mResourceManifest);
+		mRootEntry = bs_new<DirectoryEntry>(mResourcesFolder, mResourcesFolder.getWTail(), nullptr);
 	}
 
 	ProjectLibrary::~ProjectLibrary()
 	{
-		save();
-
 		if(mRootEntry != nullptr)
 			deleteDirectoryInternal(mRootEntry);
 	}
@@ -1014,8 +1005,32 @@ namespace BansheeEngine
 		return fullPath.getWExtension() == L".meta";
 	}
 
-	void ProjectLibrary::save()
+	void ProjectLibrary::unloadLibrary()
 	{
+		if (!mIsLoaded)
+			return;
+
+		mProjectFolder = Path::BLANK;
+		mResourcesFolder = Path::BLANK;
+
+		if (mRootEntry != nullptr)
+		{
+			deleteDirectoryInternal(mRootEntry);
+			mRootEntry = bs_new<DirectoryEntry>(mResourcesFolder, mResourcesFolder.getWTail(), nullptr);
+		}
+
+		mReimportQueue.clear();
+		mDependencies.clear();
+		gResources().unregisterResourceManifest(mResourceManifest);
+		mResourceManifest = nullptr;
+		mIsLoaded = false;
+	}
+
+	void ProjectLibrary::saveLibrary()
+	{
+		if (!mIsLoaded)
+			return;
+
 		std::shared_ptr<ProjectLibraryEntries> libEntries = ProjectLibraryEntries::create(*mRootEntry);
 
 		Path libraryEntriesPath = mProjectFolder;
@@ -1032,13 +1047,13 @@ namespace BansheeEngine
 		ResourceManifest::save(mResourceManifest, resourceManifestPath, mProjectFolder);
 	}
 
-	void ProjectLibrary::load()
+	void ProjectLibrary::loadLibrary()
 	{
-		if(mRootEntry != nullptr)
-		{
-			deleteDirectoryInternal(mRootEntry);
-			mRootEntry = nullptr;
-		}
+		unloadLibrary();
+
+		mProjectFolder = gEditorApplication().getProjectPath();
+		mResourcesFolder = mProjectFolder;
+		mResourcesFolder.append(RESOURCES_DIR);
 
 		mRootEntry = bs_new<DirectoryEntry>(mResourcesFolder, mResourcesFolder.getWTail(), nullptr);
 
@@ -1064,9 +1079,11 @@ namespace BansheeEngine
 		resourceManifestPath.append(RESOURCE_MANIFEST_FILENAME);
 
 		if (FileSystem::exists(resourceManifestPath))
-		{
 			mResourceManifest = ResourceManifest::load(resourceManifestPath, mProjectFolder);
-		}
+		else
+			mResourceManifest = ResourceManifest::create("ProjectLibrary");
+
+		gResources().registerResourceManifest(mResourceManifest);
 
 		// Load all meta files
 		Stack<DirectoryEntry*> todo;
@@ -1120,6 +1137,8 @@ namespace BansheeEngine
 				}
 			}
 		}
+
+		mIsLoaded = true;
 	}
 
 	void ProjectLibrary::doOnEntryRemoved(const LibraryEntry* entry)

+ 7 - 2
BansheeEditor/Source/BsUndoRedo.cpp

@@ -16,8 +16,7 @@ namespace BansheeEngine
 
 	UndoRedo::~UndoRedo()
 	{
-		clearUndoStack();
-		clearRedoStack();
+		clear();
 
 		bs_deleteN(mUndoStack, MAX_STACK_ELEMENTS);
 		bs_deleteN(mRedoStack, MAX_STACK_ELEMENTS);
@@ -91,6 +90,12 @@ namespace BansheeEngine
 		clearRedoStack();
 	}
 
+	void UndoRedo::clear()
+	{
+		clearUndoStack();
+		clearRedoStack();
+	}
+
 	EditorCommand* UndoRedo::removeLastFromUndoStack()
 	{
 		EditorCommand* command = mUndoStack[mUndoStackPtr];

+ 1 - 1
BansheeUtility/Source/BsPath.cpp

@@ -425,7 +425,7 @@ namespace BansheeEngine
 		else if (mDirectories.size() > 0)
 			return mDirectories.back();
 		else
-			return toWString(type);
+			return StringUtil::WBLANK;
 	}
 
 	String Path::getTail(PathType type) const

+ 96 - 10
MBansheeEditor/EditorApplication.cs

@@ -62,6 +62,7 @@ namespace BansheeEditor
 
         public static string ProjectPath { get { return Internal_GetProjectPath(); } }
         public static string ProjectName { get { return Internal_GetProjectName(); } }
+        public static bool IsProjectLoaded { get { return Internal_GetProjectLoaded(); } }
         internal static string CompilerPath { get { return Internal_GetCompilerPath(); } }
         internal static string BuiltinAssemblyPath { get { return Internal_GetBuiltinAssemblyPath(); } }
         internal static string ScriptAssemblyPath { get { return Internal_GetScriptAssemblyPath(); } }
@@ -73,7 +74,7 @@ namespace BansheeEditor
 
         private static EditorApplication instance;
 
-        private FolderMonitor monitor;
+        private static FolderMonitor monitor;
 
         internal EditorApplication()
         {
@@ -102,14 +103,18 @@ namespace BansheeEditor
             inputConfig.RegisterButton(SceneWindow.ScaleToolBinding, ButtonCode.R);
             inputConfig.RegisterButton(SceneWindow.DuplicateBinding, ButtonCode.D, ButtonModifier.Ctrl);
 
-            ProjectLibrary.Refresh();
-            monitor = new FolderMonitor(ProjectLibrary.ResourceFolder);
-            monitor.OnAdded += OnAssetModified;
-            monitor.OnRemoved += OnAssetModified;
-            monitor.OnModified += OnAssetModified;
+            if (EditorSettings.AutoLoadLastProject)
+            {
+                string projectPath = EditorSettings.LastOpenProject;
+                if (Internal_IsValidProject(projectPath))
+                    LoadProject(projectPath);
+            }
+
+            if (!IsProjectLoaded)
+                ProjectWindow.Show();
         }
 
-        private void OnAssetModified(string path)
+        private static void OnAssetModified(string path)
         {
             ProjectLibrary.Refresh(path);
         }
@@ -163,16 +168,25 @@ namespace BansheeEditor
 
         public static void LoadScene(string path)
         {
+            Action<string> continueLoad =
+                (scenePath) =>
+                {
+                    Scene.Load(path);
+
+                    ProjectSettings.LastOpenScene = scenePath;
+                    ProjectSettings.Save();
+                };
+
             Action<DialogBox.ResultType> dialogCallback =
             (result) =>
             {
                 if (result == DialogBox.ResultType.Yes)
                 {
                     SaveScene();
-                    Scene.Load(path);
+                    continueLoad(path);
                 }
                 else if (result == DialogBox.ResultType.No)
-                    Scene.Load(path);
+                    continueLoad(path);
             };
 
             if (Scene.IsModified())
@@ -181,7 +195,67 @@ namespace BansheeEditor
                     DialogBox.Type.YesNoCancel, dialogCallback);
             }
             else
-                Scene.Load(path);
+                continueLoad(path);
+        }
+
+        public static void LoadProject(string path)
+        {
+            if (Internal_IsValidProject(path))
+            {
+                Debug.LogWarning("Provided path: \"" + path + "\" is not a valid project.");
+                return;
+            }
+
+            Internal_LoadProject(path);
+
+            ProjectLibrary.Refresh();
+            monitor = new FolderMonitor(ProjectLibrary.ResourceFolder);
+            monitor.OnAdded += OnAssetModified;
+            monitor.OnRemoved += OnAssetModified;
+            monitor.OnModified += OnAssetModified;
+
+            if(!string.IsNullOrWhiteSpace(ProjectSettings.LastOpenScene))
+                Scene.Load(ProjectSettings.LastOpenScene);
+        }
+
+        public static void UnloadProject()
+        {
+            // TODO - Save dirty assets
+
+            Action continueUnload =
+                () =>
+                {
+                    Scene.Clear();
+
+                    if (monitor != null)
+                    {
+                        monitor.Destroy();
+                        monitor = null;
+                    }
+
+                    LibraryWindow window = EditorWindow.GetWindow<LibraryWindow>();
+                    if(window != null)
+                        window.Reset();
+
+                    Internal_UnloadProject();
+                };
+
+            Action<DialogBox.ResultType> dialogCallback =
+            (result) =>
+            {
+                if (result == DialogBox.ResultType.Yes)
+                    SaveScene();
+
+                continueUnload();
+            };
+
+            if (Scene.IsModified())
+            {
+                DialogBox.Open("Warning", "You current scene has modifications. Do you wish to save them first?",
+                    DialogBox.Type.YesNoCancel, dialogCallback);
+            }
+            else
+                continueUnload();
         }
 
         [MenuItem("Components/Camera")]
@@ -296,6 +370,9 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern string Internal_GetProjectName();
 
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_GetProjectLoaded();
+
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern string Internal_GetCompilerPath();
 
@@ -322,5 +399,14 @@ namespace BansheeEditor
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern string Internal_SaveScene(string path);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_IsValidProject(string path);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_LoadProject(string path);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_UnloadProject();
     }
 }

+ 13 - 13
MBansheeEditor/LibraryWindow.cs

@@ -75,7 +75,7 @@ namespace BansheeEditor
             set { viewType = value; Refresh(); }
         }
 
-        [MenuItem("Windows/Library", ButtonModifier.CtrlAlt, ButtonCode.P)]
+        [MenuItem("Windows/Library", ButtonModifier.CtrlAlt, ButtonCode.L)]
         private static void OpenLibraryWindow()
         {
             OpenWindow<LibraryWindow>();
@@ -396,6 +396,18 @@ namespace BansheeEditor
             }
         }
 
+        public void Reset()
+        {
+            currentDirectory = ProjectLibrary.Root.Path;
+            selectionAnchorStart = -1;
+            selectionAnchorEnd = -1;
+            selectionPaths.Clear();
+            pingPath = "";
+            hoverHighlightPath = "";
+
+            Refresh();
+        }
+
         private void DeselectAll(bool onlyInternal = false)
         {
             SetSelection(new List<string>(), onlyInternal);
@@ -1347,18 +1359,6 @@ namespace BansheeEditor
             dropDown.SetParent(this);
         }
 
-        private void Reset()
-        {
-            currentDirectory = ProjectLibrary.Root.Path;
-            selectionAnchorStart = -1;
-            selectionAnchorEnd = -1;
-            selectionPaths.Clear();
-            pingPath = "";
-            hoverHighlightPath = "";
-
-            Refresh();
-        }
-
         private Rect2I GetScrollAreaBounds()
         {
             Rect2I bounds = GUI.Bounds;

+ 4 - 0
SBansheeEditor/Include/BsScriptEditorApplication.h

@@ -21,6 +21,7 @@ namespace BansheeEngine
 		/************************************************************************/
 		static MonoString* internal_GetProjectPath();
 		static MonoString* internal_GetProjectName();
+		static bool internal_GetProjectLoaded();
 		static MonoString* internal_GetCompilerPath();
 		static MonoString* internal_GetBuiltinAssemblyPath();
 		static MonoString* internal_GetScriptAssemblyPath();
@@ -30,5 +31,8 @@ namespace BansheeEngine
 		static MonoString* internal_GetScriptGameAssemblyName();
 		static MonoString* internal_GetScriptEditorAssemblyName();
 		static MonoString* internal_SaveScene(MonoString* path);
+		static bool internal_IsValidProject(MonoString* path);
+		static void internal_LoadProject(MonoString* path);
+		static void internal_UnloadProject();
 	};
 }

+ 26 - 0
SBansheeEditor/Source/BsScriptEditorApplication.cpp

@@ -27,6 +27,7 @@ namespace BansheeEngine
 	{
 		metaData.scriptClass->addInternalCall("Internal_GetProjectPath", &ScriptEditorApplication::internal_GetProjectPath);
 		metaData.scriptClass->addInternalCall("Internal_GetProjectName", &ScriptEditorApplication::internal_GetProjectName);
+		metaData.scriptClass->addInternalCall("Internal_GetProjectLoaded", &ScriptEditorApplication::internal_GetProjectLoaded);
 		metaData.scriptClass->addInternalCall("Internal_GetCompilerPath", &ScriptEditorApplication::internal_GetCompilerPath);
 		metaData.scriptClass->addInternalCall("Internal_GetBuiltinAssemblyPath", &ScriptEditorApplication::internal_GetBuiltinAssemblyPath);
 		metaData.scriptClass->addInternalCall("Internal_GetScriptAssemblyPath", &ScriptEditorApplication::internal_GetScriptAssemblyPath);
@@ -36,6 +37,9 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_GetScriptGameAssemblyName", &ScriptEditorApplication::internal_GetScriptGameAssemblyName);
 		metaData.scriptClass->addInternalCall("Internal_GetScriptEditorAssemblyName", &ScriptEditorApplication::internal_GetScriptEditorAssemblyName);
 		metaData.scriptClass->addInternalCall("Internal_SaveScene", &ScriptEditorApplication::internal_SaveScene);
+		metaData.scriptClass->addInternalCall("Internal_IsValidProject", &ScriptEditorApplication::internal_IsValidProject);
+		metaData.scriptClass->addInternalCall("Internal_LoadProject", &ScriptEditorApplication::internal_LoadProject);
+		metaData.scriptClass->addInternalCall("Internal_UnloadProject", &ScriptEditorApplication::internal_UnloadProject);
 	}
 
 	MonoString* ScriptEditorApplication::internal_GetProjectPath()
@@ -52,6 +56,11 @@ namespace BansheeEngine
 		return MonoUtil::wstringToMono(MonoManager::instance().getDomain(), projectName);
 	}
 
+	bool ScriptEditorApplication::internal_GetProjectLoaded()
+	{
+		return gEditorApplication().isProjectLoaded();
+	}
+
 	MonoString* ScriptEditorApplication::internal_GetCompilerPath()
 	{
 		Path compilerPath = MonoManager::instance().getCompilerPath();
@@ -131,4 +140,21 @@ namespace BansheeEngine
 
 		return MonoUtil::stringToMono(MonoManager::instance().getDomain(), scene.getUUID());
 	}
+
+	bool ScriptEditorApplication::internal_IsValidProject(MonoString* path)
+	{
+		Path nativePath = MonoUtil::monoToWString(path);
+		return gEditorApplication().isValidProjectPath(nativePath);
+	}
+
+	void ScriptEditorApplication::internal_LoadProject(MonoString* path)
+	{
+		Path nativePath = MonoUtil::monoToWString(path);
+		gEditorApplication().loadProject(nativePath);
+	}
+
+	void ScriptEditorApplication::internal_UnloadProject()
+	{
+		gEditorApplication().unloadProject();
+	}
 }

+ 3 - 3
SBansheeEngine/Source/BsScriptGUIContent.cpp

@@ -20,9 +20,9 @@ namespace BansheeEngine
 
 	void ScriptGUIContent::initRuntimeData()
 	{
-		mTextField = metaData.scriptClass->getField("_text");
-		mTooltipField = metaData.scriptClass->getField("_tooltip");
-		mImageField = metaData.scriptClass->getField("_image");
+		mTextField = metaData.scriptClass->getField("text");
+		mTooltipField = metaData.scriptClass->getField("tooltip");
+		mImageField = metaData.scriptClass->getField("image");
 	}
 
 	const HString& ScriptGUIContent::getText(MonoObject* instance)

+ 4 - 6
TODO.txt

@@ -57,7 +57,6 @@ Move data folder within current repo
  - Store data generated by editor runtime at Data/Runtime
 
 Add Create Project & Open Project entries in main menu
-Rename ProjectWindow to LibraryWindow
 Store last open project location, should the last project be loaded by default, and a list of all known projects (listed by last opened date)
 (Store last open level too in ProjectSettings)
 ProjectWindow
@@ -79,14 +78,14 @@ When creating a new project:
  - Unload the current project (clear scene, clear project library)
  - Refresh project library so it points to new location
 
+TODO - On project unload and load I need to trigger assembly reload
+TODO - Test if project loading/unloading/reloading works
+
 Ribek use:
  - Hook up color picker to guicolor field
  - When starting drag from hierarchy tree view it tends to select another object (can't repro)
+ - UseCustomInspector isn't implemented
  - Camera, Renderable, Material, Texture inspector
- - Project create/open window
- - Load default layout on initial start
- - When opening editor load last open scene
- - Make sure to persist EditorSettings
  - Test release mode
  - Ability to create assets in Project view (At least Material)
  - (Optionally, needed for GUI editing) GUISkin resource inspector & a way to inspect and save the default editor skin
@@ -128,7 +127,6 @@ Stage 2 polish:
 
 Finalizing:
  - Add copyright notices in all files & change license to GPL
- - UseCustomInspector isn't implemented
  - Move all the code files into subfolders so their hierarchy is similar to VS filters
  - Splash screen
  - Settings/Preferences window