Kaynağa Gözat

In-editor compilation
Hooked up existing VS integration code with the rest of the editor

BearishSun 10 yıl önce
ebeveyn
işleme
d3b00942e8
31 değiştirilmiş dosya ile 452 ekleme ve 18 silme
  1. 6 0
      BansheeEditor/Include/BsGUIStatusBar.h
  2. 1 1
      BansheeEditor/Include/BsProjectLibrary.h
  3. 9 0
      BansheeEditor/Source/BsGUIStatusBar.cpp
  4. 5 3
      BansheeEditor/Source/BsProjectLibrary.cpp
  5. 34 1
      MBansheeEditor/CodeEditor.cs
  6. 31 4
      MBansheeEditor/EditorApplication.cs
  7. 6 0
      MBansheeEditor/Library/LibraryGUIEntry.cs
  8. 1 0
      MBansheeEditor/MBansheeEditor.csproj
  9. 18 1
      MBansheeEditor/ProjectLibrary.cs
  10. 161 0
      MBansheeEditor/ScriptCodeManager.cs
  11. 6 6
      MBansheeEditor/ScriptCompiler.cs
  12. 1 0
      MBansheeEngine/MBansheeEngine.csproj
  13. 16 0
      MBansheeEngine/ShaderInclude.cs
  14. 3 0
      SBansheeEditor/Include/BsScriptEditorApplication.h
  15. 9 0
      SBansheeEditor/Include/BsScriptProjectLibrary.h
  16. 0 1
      SBansheeEditor/Source/BsEditorScriptLibrary.cpp
  17. 10 0
      SBansheeEditor/Source/BsGUIResourceField.cpp
  18. 21 0
      SBansheeEditor/Source/BsScriptEditorApplication.cpp
  19. 15 0
      SBansheeEditor/Source/BsScriptProjectLibrary.cpp
  20. 1 0
      SBansheeEngine/Include/BsManagedSerializableObjectInfo.h
  21. 2 1
      SBansheeEngine/Include/BsScriptResource.h
  22. 22 0
      SBansheeEngine/Include/BsScriptShaderInclude.h
  23. 2 0
      SBansheeEngine/SBansheeEngine.vcxproj
  24. 6 0
      SBansheeEngine/SBansheeEngine.vcxproj.filters
  25. 28 0
      SBansheeEngine/Source/BsManagedSerializableField.cpp
  26. 3 0
      SBansheeEngine/Source/BsManagedSerializableObjectInfo.cpp
  27. 7 0
      SBansheeEngine/Source/BsScriptAssemblyManager.cpp
  28. 4 0
      SBansheeEngine/Source/BsScriptResource.cpp
  29. 6 0
      SBansheeEngine/Source/BsScriptResourceManager.cpp
  30. 16 0
      SBansheeEngine/Source/BsScriptShaderInclude.cpp
  31. 2 0
      TODO.txt

+ 6 - 0
BansheeEditor/Include/BsGUIStatusBar.h

@@ -68,6 +68,11 @@ namespace BansheeEngine
 		 */
 		void setScene(const WString& name, bool modified);
 
+		/**
+		 * @brief	Activates or deactivates the "compilation in progress" visuals on the status bar.
+		 */
+		void setIsCompiling(bool compiling);
+
 		/**
 		 * @copydoc	GUIElement::setTint
 		 */
@@ -112,6 +117,7 @@ namespace BansheeEngine
 		GUIButton* mMessage;
 		GUILabel* mScene;
 		GUILabel* mProject;
+		GUILabel* mCompiling;
 		GUITexture* mBackground;
 
 		HEvent mLogEntryAddedConn;

+ 1 - 1
BansheeEditor/Include/BsProjectLibrary.h

@@ -246,7 +246,7 @@ namespace BansheeEngine
 
 		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. */
-		Event<void(const Path&)> onEntryImport; /**< Triggered when a resource is being (re)imported. Path provided is absolute. */
+		Event<void(const Path&)> onEntryImported; /**< Triggered when a resource is being (re)imported. Path provided is absolute. */
 
 		static const Path RESOURCES_DIR;
 		static const Path INTERNAL_RESOURCES_DIR;

+ 9 - 0
BansheeEditor/Source/BsGUIStatusBar.cpp

@@ -30,6 +30,7 @@ namespace BansheeEngine
 		mMessage = GUIButton::create(HString(L""), GUIOptions(GUIOption::flexibleWidth()), getSubStyleName(getGUIMessageTypeName()));
 		mScene = GUILabel::create(HString(L"Scene: Unnamed"), GUIOptions(GUIOption::fixedWidth(150)));
 		mProject = GUILabel::create(HString(L"Project: None"), GUIOptions(GUIOption::fixedWidth(200)));
+		mCompiling = GUILabel::create(HString(L"Compiling..."), GUIOptions(GUIOption::fixedWidth(100)));
 
 		GUILayoutY* vertLayout = mPanel->addNewElement<GUILayoutY>();
 		vertLayout->addNewElement<GUIFixedSpace>(3);
@@ -42,8 +43,11 @@ namespace BansheeEngine
 		horzLayout->addNewElement<GUIFixedSpace>(10);
 		horzLayout->addElement(mProject);
 		horzLayout->addNewElement<GUIFixedSpace>(10);
+		horzLayout->addElement(mCompiling);
+		horzLayout->addNewElement<GUIFixedSpace>(10);
 
 		mBgPanel->addElement(mBackground);
+		mCompiling->setActive(false);
 
 		mLogEntryAddedConn = gDebug().onLogEntryAdded.connect(std::bind(&GUIStatusBar::logEntryAdded, this, _1));
 		mMessageBtnPressedConn = mMessage->onClick.connect(std::bind(&GUIStatusBar::messageBtnClicked, this));
@@ -104,6 +108,11 @@ namespace BansheeEngine
 
 		mScene->setContent(HString(content.str()));
 	}
+
+	void GUIStatusBar::setIsCompiling(bool compiling)
+	{
+		mCompiling->setActive(compiling);
+	}
 	
 	void GUIStatusBar::setTint(const Color& color)
 	{

+ 5 - 3
BansheeEditor/Source/BsProjectLibrary.cpp

@@ -449,7 +449,7 @@ namespace BansheeEngine
 
 			resource->lastUpdateTime = std::time(nullptr);
 
-			onEntryImport(resource->path);
+			onEntryImported(resource->path);
 			reimportDependants(resource->path);
 		}
 	}
@@ -954,7 +954,7 @@ namespace BansheeEngine
 
 		ResourceEntry* resEntry = static_cast<ResourceEntry*>(entry);
 		if (resEntry->meta == nullptr)
-			return;
+			return HResource();
 
 		String resUUID = resEntry->meta->getUUID();
 
@@ -1228,9 +1228,11 @@ namespace BansheeEngine
 			String uuid = file.getFilename(false);
 			if (mUUIDToPath.find(uuid) == mUUIDToPath.end())
 				toDelete.push_back(file);
+
+			return true;
 		};
 
-		FileSystem::iterate(internalResourcesFolder, &processFile);
+		FileSystem::iterate(internalResourcesFolder, processFile);
 
 		for (auto& entry : toDelete)
 			FileSystem::remove(entry);

+ 34 - 1
MBansheeEditor/CodeEditor.cs

@@ -21,6 +21,19 @@ namespace BansheeEditor
     /// </summary>
     public static class CodeEditor
     {
+        /// <summary>
+        /// Contains resource types that are relevant to the code editor.
+        /// </summary>
+        public static readonly ResourceType[] CodeTypes =
+        {
+            ResourceType.ScriptCode,
+            ResourceType.PlainText,
+            ResourceType.Shader,
+            ResourceType.ShaderInclude
+        };
+
+        private static bool isSolutionDirty;
+
         /// <summary>
         /// Currently active code editor.
         /// </summary>
@@ -29,6 +42,14 @@ namespace BansheeEditor
             set { Internal_SetActiveEditor(value); }
         }
 
+        /// <summary>
+        /// Checks if the code editor's solution requires updating.
+        /// </summary>
+        internal static bool IsSolutionDirty
+        {
+            get { return isSolutionDirty; }
+        }
+
         /// <summary>
         /// Returns a list of all code editors available on this machine.
         /// </summary>
@@ -40,10 +61,13 @@ namespace BansheeEditor
         /// <summary>
         /// Opens a script file in the currently active code editor.
         /// </summary>
-        /// <param name="path">Path to the script file to open, either absolute or relative to the project folder.</param>
+        /// <param name="path">Path to the script file to open, either absolute or relative to the project resources folder.</param>
         /// <param name="line">Line in the file to focus the editor on.</param>
         public static void OpenFile(string path, UInt32 line)
         {
+            if (IsSolutionDirty)
+                SyncSolution();
+
             Internal_OpenFile(path, line);
         }
 
@@ -53,6 +77,15 @@ namespace BansheeEditor
         public static void SyncSolution()
         {
             Internal_SyncSolution();
+            isSolutionDirty = false;
+        }
+
+        /// <summary>
+        /// Notifies the code editor that code file structure has changed and the solution needs to be rebuilt.
+        /// </summary>
+        internal static void MarkSolutionDirty()
+        {
+            isSolutionDirty = true;
         }
 
         [MethodImpl(MethodImplOptions.InternalCall)]

+ 31 - 4
MBansheeEditor/EditorApplication.cs

@@ -113,25 +113,26 @@ namespace BansheeEditor
         /// <summary>
         /// Name of the builtin assembly containing engine specific types.
         /// </summary>
-        internal static string EngineAssembly { get { return Internal_GetEngineAssemblyName(); } }
+        internal static string EngineAssemblyName { get { return Internal_GetEngineAssemblyName(); } }
 
         /// <summary>
         /// Name of the builtin assembly containing editor specific types.
         /// </summary>
-        internal static string EditorAssembly { get { return Internal_GetEditorAssemblyName(); } }
+        internal static string EditorAssemblyName { get { return Internal_GetEditorAssemblyName(); } }
 
         /// <summary>
         /// Name of the custom assembly compiled from non-editor scripts within the project.
         /// </summary>
-        internal static string ScriptGameAssembly { get { return Internal_GetScriptGameAssemblyName(); } }
+        internal static string ScriptGameAssemblyName { get { return Internal_GetScriptGameAssemblyName(); } }
 
         /// <summary>
         /// Name of the custom assembly compiled from editor scripts within the project.
         /// </summary>
-        internal static string ScriptEditorAssembly { get { return Internal_GetScriptEditorAssemblyName(); } }
+        internal static string ScriptEditorAssemblyName { get { return Internal_GetScriptEditorAssemblyName(); } }
 
         private static EditorApplication instance;
         private static FolderMonitor monitor;
+        private static ScriptCodeManager codeManager;
         private static HashSet<string> dirtyResources = new HashSet<string>();
         private static bool sceneDirty;
         private static bool unitTestsExecuted;
@@ -142,6 +143,7 @@ namespace BansheeEditor
         internal EditorApplication()
         {
             instance = this;
+            codeManager = new ScriptCodeManager();
 
             // Register controls
             InputConfiguration inputConfig = VirtualInput.KeyConfig;
@@ -182,6 +184,7 @@ namespace BansheeEditor
         internal void OnEditorUpdate()
         {
             ProjectLibrary.Update();
+            codeManager.Update();
         }
 
         /// <summary>
@@ -526,6 +529,15 @@ namespace BansheeEditor
                 continueUnload();
         }
 
+        /// <summary>
+        /// Reloads all script assemblies in case they were modified. This action is delayed and will be executed
+        /// at the beginning of the next frame.
+        /// </summary>
+        public static void ReloadAssemblies()
+        {
+            Internal_ReloadAssemblies();
+        }
+
         /// <summary>
         /// Changes the scene displayed on the status bar.
         /// </summary>
@@ -545,6 +557,15 @@ namespace BansheeEditor
             Internal_SetStatusProject(modified);
         }
 
+        /// <summary>
+        /// Displays or hides the "compilation in progress" visual on the status bar.
+        /// </summary>
+        /// <param name="compiling">True to display the visual, false otherwise.</param>
+        internal static void SetStatusCompiling(bool compiling)
+        {
+            Internal_SetStatusCompiling(compiling);
+        }
+
         /// <summary>
         /// Checks did we make any modifications to the scene since it was last saved.
         /// </summary>
@@ -570,6 +591,9 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_SetStatusProject(bool modified);
 
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetStatusCompiling(bool compiling);
+
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern string Internal_GetProjectPath();
 
@@ -621,6 +645,9 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_CreateProject(string path);
 
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_ReloadAssemblies();
+
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_OpenExternally(string path);
 

+ 6 - 0
MBansheeEditor/Library/LibraryGUIEntry.cs

@@ -291,6 +291,10 @@ namespace BansheeEditor
                     {
                         EditorApplication.LoadScene(resEntry.Path);
                     }
+                    else if (resEntry.ResType == ResourceType.ScriptCode)
+                    {
+                        CodeEditor.OpenFile(resEntry.Path, 0);
+                    }
                 }
             }
         }
@@ -326,6 +330,8 @@ namespace BansheeEditor
                         return EditorBuiltin.GetLibraryItemIcon(LibraryItemIcon.SpriteTexture, size);
                     case ResourceType.Shader:
                         return EditorBuiltin.GetLibraryItemIcon(LibraryItemIcon.Shader, size);
+                    case ResourceType.ShaderInclude:
+                        return EditorBuiltin.GetLibraryItemIcon(LibraryItemIcon.Shader, size);
                     case ResourceType.Material:
                         return EditorBuiltin.GetLibraryItemIcon(LibraryItemIcon.Material, size);
                     case ResourceType.Prefab:

+ 1 - 0
MBansheeEditor/MBansheeEditor.csproj

@@ -146,6 +146,7 @@
     <Compile Include="Scene\Handle.cs" />
     <Compile Include="Scene\RotateHandle.cs" />
     <Compile Include="Scene\ScaleHandle.cs" />
+    <Compile Include="ScriptCodeManager.cs" />
     <Compile Include="ScriptCompiler.cs" />
     <Compile Include="Selection.cs" />
     <Compile Include="SettingsWindow.cs" />

+ 18 - 1
MBansheeEditor/ProjectLibrary.cs

@@ -34,6 +34,12 @@ namespace BansheeEditor
         /// </summary>
         public static event Action<string> OnEntryRemoved;
 
+        /// <summary>
+        /// Triggered when an entry is (re)imported in the project library. Provided path relative to the project library 
+        /// resources folder.
+        /// </summary>
+        public static event Action<string> OnEntryImported;
+
         private static HashSet<string> queuedForImport = new HashSet<string>();
         private static int numImportedFiles;
         private static int totalFilesToImport;
@@ -329,6 +335,16 @@ namespace BansheeEditor
                 OnEntryRemoved(path);
         }
 
+        /// <summary>
+        /// Triggered internally by the runtime when an entry is (re)imported in the project library.
+        /// </summary>
+        /// <param name="path">Path relative to the project library resources folder.</param>
+        private static void Internal_DoOnEntryImported(string path)
+        {
+            if (OnEntryImported != null)
+                OnEntryImported(path);
+        }
+
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern string[] Internal_Refresh(string path, bool import);
 
@@ -394,7 +410,8 @@ namespace BansheeEditor
     /// </summary>
     public enum ResourceType // Note: Must match the C++ enum ScriptResourceType
     {
-        Texture, SpriteTexture, Mesh, Font, Shader, Material, Prefab, PlainText, ScriptCode, StringTable, GUISkin, Undefined
+        Texture, SpriteTexture, Mesh, Font, Shader, ShaderInclude, Material, Prefab, PlainText, 
+        ScriptCode, StringTable, GUISkin, Undefined
     }
 
     /// <summary>

+ 161 - 0
MBansheeEditor/ScriptCodeManager.cs

@@ -0,0 +1,161 @@
+using System.Text;
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    /// <summary>
+    /// Handles various operations related to script code in the active project, like compilation and code editor syncing.
+    /// </summary>
+    public sealed class ScriptCodeManager
+    {
+        private bool isGameAssemblyDirty;
+        private bool isEditorAssemblyDirty;
+        private CompilerInstance compilerInstance;
+
+        /// <summary>
+        /// Constructs a new script code manager.
+        /// </summary>
+        internal ScriptCodeManager()
+        {
+            ProjectLibrary.OnEntryAdded += OnEntryAdded;
+            ProjectLibrary.OnEntryRemoved += OnEntryRemoved;
+            ProjectLibrary.OnEntryImported += OnEntryImported;
+        }
+
+        /// <summary>
+        /// Triggers required compilation or code editor syncing if needed.
+        /// </summary>
+        internal void Update()
+        {
+            if (CodeEditor.IsSolutionDirty)
+                CodeEditor.SyncSolution();
+
+            if (compilerInstance == null)
+            {
+                string outputDir = EditorApplication.ScriptAssemblyPath;
+
+                if (isGameAssemblyDirty)
+                {
+                    compilerInstance = ScriptCompiler.CompileAsync(
+                        ScriptAssemblyType.Game, BuildManager.ActivePlatform, true, outputDir);
+
+                    EditorApplication.SetStatusCompiling(true);
+                    isGameAssemblyDirty = false;
+                }
+                else if (isEditorAssemblyDirty)
+                {
+                    compilerInstance = ScriptCompiler.CompileAsync(
+                        ScriptAssemblyType.Editor, BuildManager.ActivePlatform, true, outputDir);
+
+                    EditorApplication.SetStatusCompiling(true);
+                    isEditorAssemblyDirty = false;
+                }
+            }
+            else
+            {
+                if (compilerInstance.IsDone)
+                {
+                    if (compilerInstance.HasErrors)
+                    {
+                        foreach (var msg in compilerInstance.WarningMessages)
+                            Debug.LogError(FormMessage(msg));
+
+                        foreach (var msg in compilerInstance.ErrorMessages)
+                            Debug.LogError(FormMessage(msg));
+                    }
+
+                    compilerInstance.Dispose();
+                    compilerInstance = null;
+
+                    EditorApplication.SetStatusCompiling(false);
+                    EditorApplication.ReloadAssemblies();
+                }
+            }
+        }
+
+        /// <summary>
+        /// Triggered when a new resource is added to the project library.
+        /// </summary>
+        /// <param name="path">Path of the added resource, relative to the project's resource folder.</param>
+        private void OnEntryAdded(string path)
+        {
+            if (IsCodeEditorFile(path))
+                CodeEditor.MarkSolutionDirty();
+        }
+
+        /// <summary>
+        /// Triggered when a resource is removed from the project library.
+        /// </summary>
+        /// <param name="path">Path of the removed resource, relative to the project's resource folder.</param>
+        private void OnEntryRemoved(string path)
+        {
+            if (IsCodeEditorFile(path))
+                CodeEditor.MarkSolutionDirty();
+        }
+
+        /// <summary>
+        /// Triggered when a resource is (re)imported in the project library.
+        /// </summary>
+        /// <param name="path">Path of the imported resource, relative to the project's resource folder.</param>
+        private void OnEntryImported(string path)
+        {
+            LibraryEntry entry = ProjectLibrary.GetEntry(path);
+            if (entry == null || entry.Type != LibraryEntryType.File)
+                return;
+
+            FileEntry fileEntry = (FileEntry)entry;
+            if (fileEntry.ResType != ResourceType.ScriptCode)
+                return;
+
+            ScriptCode codeFile = ProjectLibrary.Load<ScriptCode>(path);
+            if(codeFile == null)
+                return;
+
+            if(codeFile.EditorScript)
+                isEditorAssemblyDirty = true;
+            else
+                isGameAssemblyDirty = true;
+        }
+
+        /// <summary>
+        /// Checks is the resource at the provided path a file relevant to the code editor.
+        /// </summary>
+        /// <param name="path">Path to the resource, absolute or relative to the project's resources folder.</param>
+        /// <returns>True if the file is relevant to the code editor, false otherwise.</returns>
+        private bool IsCodeEditorFile(string path)
+        {
+            LibraryEntry entry = ProjectLibrary.GetEntry(path);
+            if (entry != null && entry.Type == LibraryEntryType.File)
+            {
+                FileEntry fileEntry = (FileEntry)entry;
+
+                foreach (var codeType in CodeEditor.CodeTypes)
+                {
+                    if (fileEntry.ResType == codeType)
+                        return true;
+                }
+            }
+
+            return false;
+        }
+
+        /// <summary>
+        /// Converts data reported by the compiler into a readable string.
+        /// </summary>
+        /// <param name="msg">Message data as reported by the compiler.</param>
+        /// <returns>Readable message string.</returns>
+        private string FormMessage(CompilerMessage msg)
+        {
+            StringBuilder sb = new StringBuilder();
+
+            if (msg.type == CompilerMessageType.Error)
+                sb.AppendLine("Compiler error: " + msg.message);
+            else
+                sb.AppendLine("Compiler warning: " + msg.message);
+
+            sb.AppendLine("\tin " + msg.file + "[" + msg.line + ":" + msg.column + "]");
+
+            return sb.ToString();
+        }
+    }
+}

+ 6 - 6
MBansheeEditor/ScriptCompiler.cs

@@ -76,9 +76,9 @@ namespace BansheeEditor
                 };
 
                 assemblies = new string[frameworkAssemblies.Length + 1];
-                assemblies[assemblies.Length - 1] = EditorApplication.EngineAssembly;
+                assemblies[assemblies.Length - 1] = EditorApplication.EngineAssemblyName;
 
-                outputFile = Path.Combine(outputDir, EditorApplication.ScriptGameAssembly);
+                outputFile = Path.Combine(outputDir, EditorApplication.ScriptGameAssemblyName);
             }
             else
             {
@@ -90,11 +90,11 @@ namespace BansheeEditor
                 };
 
                 assemblies = new string[frameworkAssemblies.Length + 3];
-                assemblies[assemblies.Length - 1] = EditorApplication.EngineAssembly;
-                assemblies[assemblies.Length - 2] = EditorApplication.EditorAssembly;
-                assemblies[assemblies.Length - 3] = EditorApplication.ScriptGameAssembly;
+                assemblies[assemblies.Length - 1] = EditorApplication.EngineAssemblyName;
+                assemblies[assemblies.Length - 2] = EditorApplication.EditorAssemblyName;
+                assemblies[assemblies.Length - 3] = EditorApplication.ScriptGameAssemblyName;
 
-                outputFile = Path.Combine(outputDir, EditorApplication.ScriptEditorAssembly);
+                outputFile = Path.Combine(outputDir, EditorApplication.ScriptEditorAssemblyName);
             }
 
             Array.Copy(frameworkAssemblies, assemblies, frameworkAssemblies.Length);

+ 1 - 0
MBansheeEngine/MBansheeEngine.csproj

@@ -135,6 +135,7 @@
     <Compile Include="SerializeObject.cs" />
     <Compile Include="SerializeField.cs" />
     <Compile Include="Shader.cs" />
+    <Compile Include="ShaderInclude.cs" />
     <Compile Include="ShortcutKey.cs" />
     <Compile Include="Sphere.cs" />
     <Compile Include="SpriteTexture.cs" />

+ 16 - 0
MBansheeEngine/ShaderInclude.cs

@@ -0,0 +1,16 @@
+using System;
+
+namespace BansheeEngine
+{
+    /// <summary>
+    /// Contains code and definitions that are shared between <see cref="Shader"/> resources.
+    /// </summary>
+    public class ShaderInclude : Resource
+    {
+        /// <summary>
+        /// Constuctor for internal runtime use only.
+        /// </summary>
+        private ShaderInclude()
+        { }
+    }
+}

+ 3 - 0
SBansheeEditor/Include/BsScriptEditorApplication.h

@@ -22,6 +22,7 @@ namespace BansheeEngine
 		ScriptEditorApplication(MonoObject* instance);
 
 		static bool mRequestProjectLoad;
+		static bool mRequestAssemblyReload;
 		static Path mProjectLoadPath;
 
 		/************************************************************************/
@@ -29,6 +30,7 @@ namespace BansheeEngine
 		/************************************************************************/
 		static void internal_SetStatusScene(MonoString* name, bool modified);
 		static void internal_SetStatusProject(bool modified);
+		static void internal_SetStatusCompiling(bool compiling);
 		static MonoString* internal_GetProjectPath();
 		static MonoString* internal_GetProjectName();
 		static bool internal_GetProjectLoaded();
@@ -46,6 +48,7 @@ namespace BansheeEngine
 		static void internal_LoadProject(MonoString* path);
 		static void internal_UnloadProject();
 		static void internal_CreateProject(MonoString* path);
+		static void internal_ReloadAssemblies();
 		static void internal_OpenExternally(MonoString* path);
 		static void internal_RunUnitTests();
 

+ 9 - 0
SBansheeEditor/Include/BsScriptProjectLibrary.h

@@ -42,8 +42,16 @@ namespace BansheeEngine
 		 */
 		static void onEntryRemoved(const Path& path);
 
+		/**
+		 * @brief	Triggered when an entry was (re) imported in the library.
+		 *
+		 * @param	path	Absolute path to the imported entry.
+		 */
+		static void onEntryImported(const Path& path);
+
 		static HEvent mOnEntryAddedConn;
 		static HEvent mOnEntryRemovedConn;
+		static HEvent mOnEntryImportedConn;
 
 		/************************************************************************/
 		/* 								CLR HOOKS						   		*/
@@ -52,6 +60,7 @@ namespace BansheeEngine
 
 		static OnEntryChangedThunkDef OnEntryAddedThunk;
 		static OnEntryChangedThunkDef OnEntryRemovedThunk;
+		static OnEntryChangedThunkDef OnEntryImportedThunk;
 
 		static MonoArray* internal_Refresh(MonoString* path, bool import);
 		static void internal_Create(MonoObject* resource, MonoString* path);

+ 0 - 1
SBansheeEditor/Source/BsEditorScriptLibrary.cpp

@@ -47,7 +47,6 @@ namespace BansheeEngine
 			assemblies.push_back({ EDITOR_ASSEMBLY, editorAssemblyPath });
 			if (gEditorApplication().isProjectLoaded())
 			{
-				
 				if (FileSystem::exists(editorScriptAssemblyPath))
 					assemblies.push_back({ SCRIPT_EDITOR_ASSEMBLY, editorScriptAssemblyPath });
 			}

+ 10 - 0
SBansheeEditor/Source/BsGUIResourceField.cpp

@@ -25,6 +25,7 @@
 #include "BsScriptMesh.h"
 #include "BsScriptFont.h"
 #include "BsScriptShader.h"
+#include "BsScriptShaderInclude.h"
 #include "BsScriptPlainText.h"
 #include "BsScriptScriptCode.h"
 #include "BsScriptStringTable.h"
@@ -344,6 +345,15 @@ namespace BansheeEngine
 				}
 			}
 				break;
+			case TID_ShaderInclude:
+			{
+				if (ScriptShaderInclude::getMetaData()->scriptClass->isSubClassOf(acceptedClass))
+				{
+					setUUID(uuid);
+					found = true;
+				}
+			}
+			break;
 			case TID_Material:
 			{
 				if (ScriptMaterial::getMetaData()->scriptClass->isSubClassOf(acceptedClass))

+ 21 - 0
SBansheeEditor/Source/BsScriptEditorApplication.cpp

@@ -14,6 +14,7 @@
 #include "BsGUIStatusBar.h"
 #include "BsScriptEditorTestSuite.h"
 #include "BsTestOutput.h"
+#include "BsScriptManager.h"
 #include "BsPlatform.h"
 #include "BsResources.h"
 #include "BsScriptEditorWindow.h"
@@ -26,6 +27,7 @@
 namespace BansheeEngine
 {
 	bool ScriptEditorApplication::mRequestProjectLoad = false;
+	bool ScriptEditorApplication::mRequestAssemblyReload = false;
 	Path ScriptEditorApplication::mProjectLoadPath;
 
 	ScriptEditorApplication::OnProjectLoadedThunkDef ScriptEditorApplication::onProjectLoadedThunk;
@@ -38,6 +40,7 @@ namespace BansheeEngine
 	{
 		metaData.scriptClass->addInternalCall("Internal_SetStatusScene", &ScriptEditorApplication::internal_SetStatusScene);
 		metaData.scriptClass->addInternalCall("Internal_SetStatusProject", &ScriptEditorApplication::internal_SetStatusProject);
+		metaData.scriptClass->addInternalCall("Internal_SetStatusCompiling", &ScriptEditorApplication::internal_SetStatusCompiling);
 		metaData.scriptClass->addInternalCall("Internal_GetProjectPath", &ScriptEditorApplication::internal_GetProjectPath);
 		metaData.scriptClass->addInternalCall("Internal_GetProjectName", &ScriptEditorApplication::internal_GetProjectName);
 		metaData.scriptClass->addInternalCall("Internal_GetProjectLoaded", &ScriptEditorApplication::internal_GetProjectLoaded);
@@ -55,6 +58,7 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_LoadProject", &ScriptEditorApplication::internal_LoadProject);
 		metaData.scriptClass->addInternalCall("Internal_UnloadProject", &ScriptEditorApplication::internal_UnloadProject);
 		metaData.scriptClass->addInternalCall("Internal_CreateProject", &ScriptEditorApplication::internal_CreateProject);
+		metaData.scriptClass->addInternalCall("Internal_ReloadAssemblies", &ScriptEditorApplication::internal_ReloadAssemblies);
 		metaData.scriptClass->addInternalCall("Internal_OpenExternally", &ScriptEditorApplication::internal_OpenExternally);
 		metaData.scriptClass->addInternalCall("Internal_RunUnitTests", &ScriptEditorApplication::internal_RunUnitTests);
 
@@ -71,8 +75,14 @@ namespace BansheeEngine
 			gEditorApplication().loadProject(mProjectLoadPath);
 
 			mRequestProjectLoad = false;
+			mRequestAssemblyReload = false;
 			MonoUtil::invokeThunk(onProjectLoadedThunk);
 		}
+		else if (mRequestAssemblyReload)
+		{
+			ScriptManager::instance().reload();
+			mRequestAssemblyReload = false;
+		}
 	}
 
 	void ScriptEditorApplication::internal_SetStatusScene(MonoString* name, bool modified)
@@ -93,6 +103,12 @@ namespace BansheeEngine
 			mainWindow->getStatusBar().setProject(L"None", false);
 	}
 
+	void ScriptEditorApplication::internal_SetStatusCompiling(bool compiling)
+	{
+		MainEditorWindow* mainWindow = EditorWindowManager::instance().getMainWindow();
+		mainWindow->getStatusBar().setIsCompiling(compiling);
+	}
+
 	MonoString* ScriptEditorApplication::internal_GetProjectPath()
 	{
 		Path projectPath = gEditorApplication().getProjectPath();
@@ -219,6 +235,11 @@ namespace BansheeEngine
 		gEditorApplication().createProject(nativePath);
 	}
 
+	void ScriptEditorApplication::internal_ReloadAssemblies()
+	{
+		mRequestAssemblyReload = true;
+	}
+
 	void ScriptEditorApplication::internal_OpenExternally(MonoString* path)
 	{
 		Path nativePath = MonoUtil::monoToWString(path);

+ 15 - 0
SBansheeEditor/Source/BsScriptProjectLibrary.cpp

@@ -23,9 +23,11 @@ namespace BansheeEngine
 {
 	ScriptProjectLibrary::OnEntryChangedThunkDef ScriptProjectLibrary::OnEntryAddedThunk;
 	ScriptProjectLibrary::OnEntryChangedThunkDef ScriptProjectLibrary::OnEntryRemovedThunk;
+	ScriptProjectLibrary::OnEntryChangedThunkDef ScriptProjectLibrary::OnEntryImportedThunk;
 
 	HEvent ScriptProjectLibrary::mOnEntryAddedConn;
 	HEvent ScriptProjectLibrary::mOnEntryRemovedConn;
+	HEvent ScriptProjectLibrary::mOnEntryImportedConn;
 
 	ScriptProjectLibrary::ScriptProjectLibrary(MonoObject* instance)
 		:ScriptObject(instance)
@@ -53,6 +55,7 @@ namespace BansheeEngine
 
 		OnEntryAddedThunk = (OnEntryChangedThunkDef)metaData.scriptClass->getMethod("Internal_DoOnEntryAdded", 1)->getThunk();
 		OnEntryRemovedThunk = (OnEntryChangedThunkDef)metaData.scriptClass->getMethod("Internal_DoOnEntryRemoved", 1)->getThunk();
+		OnEntryImportedThunk = (OnEntryChangedThunkDef)metaData.scriptClass->getMethod("Internal_DoOnEntryImported", 1)->getThunk();
 	}
 
 	MonoArray* ScriptProjectLibrary::internal_Refresh(MonoString* path, bool import)
@@ -256,12 +259,14 @@ namespace BansheeEngine
 	{
 		mOnEntryAddedConn = gProjectLibrary().onEntryAdded.connect(std::bind(&ScriptProjectLibrary::onEntryAdded, _1));
 		mOnEntryRemovedConn = gProjectLibrary().onEntryRemoved.connect(std::bind(&ScriptProjectLibrary::onEntryRemoved, _1));
+		mOnEntryImportedConn = gProjectLibrary().onEntryImported.connect(std::bind(&ScriptProjectLibrary::onEntryImported, _1));
 	}
 
 	void ScriptProjectLibrary::shutDown()
 	{
 		mOnEntryAddedConn.disconnect();
 		mOnEntryRemovedConn.disconnect();
+		mOnEntryImportedConn.disconnect();
 	}
 
 	void ScriptProjectLibrary::onEntryAdded(const Path& path)
@@ -284,6 +289,16 @@ namespace BansheeEngine
 		MonoUtil::invokeThunk(OnEntryRemovedThunk, pathStr);
 	}
 
+	void ScriptProjectLibrary::onEntryImported(const Path& path)
+	{
+		Path relativePath = path;
+		if (relativePath.isAbsolute())
+			relativePath.makeRelative(gProjectLibrary().getResourcesFolder());
+
+		MonoString* pathStr = MonoUtil::wstringToMono(MonoManager::instance().getDomain(), relativePath.toWString());
+		MonoUtil::invokeThunk(OnEntryImportedThunk, pathStr);
+	}
+
 	ScriptLibraryEntryBase::ScriptLibraryEntryBase(MonoObject* instance)
 		:ScriptObjectBase(instance)
 	{ }

+ 1 - 0
SBansheeEngine/Include/BsManagedSerializableObjectInfo.h

@@ -32,6 +32,7 @@ namespace BansheeEngine
 		PlainTextRef,
 		ScriptCodeRef,
 		ShaderRef,
+		ShaderIncludeRef,
 		MaterialRef,
 		MeshRef,
 		PrefabRef,

+ 2 - 1
SBansheeEngine/Include/BsScriptResource.h

@@ -10,7 +10,8 @@ namespace BansheeEngine
 	 */
 	enum class ScriptResourceType // Note: Must be the same as C# enum ScriptResourceType
 	{
-		Texture, SpriteTexture, Mesh, Font, Shader, Material, Prefab, PlainText, ScriptCode, StringTable, GUISkin, Undefined
+		Texture, SpriteTexture, Mesh, Font, Shader, ShaderInclude, Material, Prefab, 
+		PlainText, ScriptCode, StringTable, GUISkin, Undefined
 	};
 
 	/**

+ 22 - 0
SBansheeEngine/Include/BsScriptShaderInclude.h

@@ -0,0 +1,22 @@
+#pragma once
+
+#include "BsScriptEnginePrerequisites.h"
+#include "BsScriptResource.h"
+#include "BsShaderInclude.h"
+
+namespace BansheeEngine
+{
+	/**
+	 * @brief	Interop class between C++ & CLR for ShaderInclude.
+	 */
+	class BS_SCR_BE_EXPORT ScriptShaderInclude : public TScriptResource <ScriptShaderInclude, ShaderInclude>
+	{
+	public:
+		SCRIPT_OBJ(ENGINE_ASSEMBLY, "BansheeEngine", "ShaderInclude")
+
+	private:
+		friend class ScriptResourceManager;
+
+		ScriptShaderInclude(MonoObject* instance, const HShaderInclude& shaderInclude);
+	};
+}

+ 2 - 0
SBansheeEngine/SBansheeEngine.vcxproj

@@ -341,6 +341,7 @@
     <ClInclude Include="Include\BsScriptSerializableProperty.h" />
     <ClInclude Include="Include\BsScriptSerializableUtility.h" />
     <ClInclude Include="Include\BsScriptShader.h" />
+    <ClInclude Include="Include\BsScriptShaderInclude.h" />
     <ClInclude Include="Include\BsScriptSpriteTexture.h" />
     <ClInclude Include="Include\BsScriptStringTable.h" />
     <ClInclude Include="Include\BsScriptStringTableManager.h" />
@@ -439,6 +440,7 @@
     <ClCompile Include="Source\BsScriptSerializableProperty.cpp" />
     <ClCompile Include="Source\BsScriptSerializableUtility.cpp" />
     <ClCompile Include="Source\BsScriptShader.cpp" />
+    <ClCompile Include="Source\BsScriptShaderInclude.cpp" />
     <ClCompile Include="Source\BsScriptSpriteTexture.cpp" />
     <ClCompile Include="Source\BsScriptStringTable.cpp" />
     <ClCompile Include="Source\BsScriptStringTableManager.cpp" />

+ 6 - 0
SBansheeEngine/SBansheeEngine.vcxproj.filters

@@ -348,6 +348,9 @@
     <ClInclude Include="Include\BsScriptSerializableUtility.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="Include\BsScriptShaderInclude.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsScriptTexture2D.cpp">
@@ -635,5 +638,8 @@
     <ClCompile Include="Source\BsScriptSerializableUtility.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="Source\BsScriptShaderInclude.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 28 - 0
SBansheeEngine/Source/BsManagedSerializableField.cpp

@@ -13,6 +13,7 @@
 #include "BsScriptPlainText.h"
 #include "BsScriptScriptCode.h"
 #include "BsScriptShader.h"
+#include "BsScriptShaderInclude.h"
 #include "BsScriptMaterial.h"
 #include "BsScriptMesh.h"
 #include "BsScriptPrefab.h"
@@ -248,6 +249,18 @@ namespace BansheeEngine
 
 				return fieldData;
 			}
+			case ScriptPrimitiveType::ShaderIncludeRef:
+			{
+				auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataResourceRef>();
+
+				if (value != nullptr)
+				{
+					ScriptShaderInclude* scriptShaderInclude = ScriptShaderInclude::toNative(value);
+					fieldData->value = scriptShaderInclude->getHandle();
+				}
+
+				return fieldData;
+			}
 			case ScriptPrimitiveType::MaterialRef:
 			{
 				auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataResourceRef>();
@@ -674,6 +687,21 @@ namespace BansheeEngine
 				else
 					return nullptr;
 			}
+			else if (primitiveTypeInfo->mType == ScriptPrimitiveType::ShaderIncludeRef)
+			{
+				if (value)
+				{
+					HShaderInclude shader = static_resource_cast<ShaderInclude>(value);
+
+					ScriptShaderInclude* scriptResource;
+					ScriptResourceManager::instance().getScriptResource(shader, &scriptResource, true);
+
+					if (scriptResource != nullptr)
+						return scriptResource->getManagedInstance();
+				}
+				else
+					return nullptr;
+			}
 			else if (primitiveTypeInfo->mType == ScriptPrimitiveType::MaterialRef)
 			{
 				if (value)

+ 3 - 0
SBansheeEngine/Source/BsManagedSerializableObjectInfo.cpp

@@ -20,6 +20,7 @@
 #include "BsScriptMesh.h"
 #include "BsScriptFont.h"
 #include "BsScriptShader.h"
+#include "BsScriptShaderInclude.h"
 #include "BsScriptPlainText.h"
 #include "BsScriptScriptCode.h"
 #include "BsScriptStringTable.h"
@@ -171,6 +172,8 @@ namespace BansheeEngine
 			return ScriptSpriteTexture::getMetaData()->scriptClass->_getInternalClass();
 		case ScriptPrimitiveType::ShaderRef:
 			return ScriptShader::getMetaData()->scriptClass->_getInternalClass();
+		case ScriptPrimitiveType::ShaderIncludeRef:
+			return ScriptShaderInclude::getMetaData()->scriptClass->_getInternalClass();
 		case ScriptPrimitiveType::MaterialRef:
 			return ScriptMaterial::getMetaData()->scriptClass->_getInternalClass();
 		case ScriptPrimitiveType::MeshRef:

+ 7 - 0
SBansheeEngine/Source/BsScriptAssemblyManager.cpp

@@ -17,6 +17,7 @@
 #include "BsScriptMesh.h"
 #include "BsScriptFont.h"
 #include "BsScriptShader.h"
+#include "BsScriptShaderInclude.h"
 #include "BsScriptPlainText.h"
 #include "BsScriptScriptCode.h"
 #include "BsScriptStringTable.h"
@@ -303,6 +304,12 @@ namespace BansheeEngine
 				typeInfo->mType = ScriptPrimitiveType::ShaderRef;
 				return typeInfo;
 			}
+			else if (monoClass->isSubClassOf(ScriptShaderInclude::getMetaData()->scriptClass))
+			{
+				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
+				typeInfo->mType = ScriptPrimitiveType::ShaderIncludeRef;
+				return typeInfo;
+			}
 			else if (monoClass->isSubClassOf(ScriptMaterial::getMetaData()->scriptClass))
 			{
 				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();

+ 4 - 0
SBansheeEngine/Source/BsScriptResource.cpp

@@ -49,6 +49,8 @@ namespace BansheeEngine
 			return ScriptResourceType::Mesh;
 		case TID_Shader:
 			return ScriptResourceType::Shader;
+		case TID_ShaderInclude:
+			return ScriptResourceType::ShaderInclude;
 		case TID_Material:
 			return ScriptResourceType::Material;
 		case TID_Font:
@@ -80,6 +82,8 @@ namespace BansheeEngine
 			return TID_Mesh;
 		case ScriptResourceType::Shader:
 			return TID_Shader;
+		case ScriptResourceType::ShaderInclude:
+			return TID_ShaderInclude;
 		case ScriptResourceType::Font:
 			return TID_Font;
 		case ScriptResourceType::Material:

+ 6 - 0
SBansheeEngine/Source/BsScriptResourceManager.cpp

@@ -10,6 +10,7 @@
 #include "BsScriptPlainText.h"
 #include "BsScriptScriptCode.h"
 #include "BsScriptShader.h"
+#include "BsScriptShaderInclude.h"
 #include "BsScriptMaterial.h"
 #include "BsScriptMesh.h"
 #include "BsScriptFont.h"
@@ -130,6 +131,8 @@ namespace BansheeEngine
 			return createScriptResource(static_resource_cast<ScriptCode>(resourceHandle), (ScriptScriptCode**)out);
 		case TID_Shader:
 			return createScriptResource(static_resource_cast<Shader>(resourceHandle), (ScriptShader**)out);
+		case TID_ShaderInclude:
+			return createScriptResource(static_resource_cast<ShaderInclude>(resourceHandle), (ScriptShaderInclude**)out);
 		case TID_Prefab:
 			return createScriptResource(static_resource_cast<Prefab>(resourceHandle), (ScriptPrefab**)out);
 		case TID_StringTable:
@@ -157,6 +160,7 @@ namespace BansheeEngine
 	template BS_SCR_BE_EXPORT void ScriptResourceManager::createScriptResource(const ResourceHandle<Mesh>&, ScriptMesh**);
 	template BS_SCR_BE_EXPORT void ScriptResourceManager::createScriptResource(const ResourceHandle<Material>&, ScriptMaterial**);
 	template BS_SCR_BE_EXPORT void ScriptResourceManager::createScriptResource(const ResourceHandle<Shader>&, ScriptShader**);
+	template BS_SCR_BE_EXPORT void ScriptResourceManager::createScriptResource(const ResourceHandle<ShaderInclude>&, ScriptShaderInclude**);
 	template BS_SCR_BE_EXPORT void ScriptResourceManager::createScriptResource(const ResourceHandle<Prefab>&, ScriptPrefab**);
 	template BS_SCR_BE_EXPORT void ScriptResourceManager::createScriptResource(const ResourceHandle<Font>&, ScriptFont**);
 	template BS_SCR_BE_EXPORT void ScriptResourceManager::createScriptResource(const ResourceHandle<PlainText>&, ScriptPlainText**);
@@ -171,6 +175,7 @@ namespace BansheeEngine
 	template BS_SCR_BE_EXPORT void ScriptResourceManager::createScriptResource(MonoObject*, const ResourceHandle<Mesh>&, ScriptMesh**);
 	template BS_SCR_BE_EXPORT void ScriptResourceManager::createScriptResource(MonoObject*, const ResourceHandle<Material>&, ScriptMaterial**);
 	template BS_SCR_BE_EXPORT void ScriptResourceManager::createScriptResource(MonoObject*, const ResourceHandle<Shader>&, ScriptShader**);
+	template BS_SCR_BE_EXPORT void ScriptResourceManager::createScriptResource(MonoObject*, const ResourceHandle<ShaderInclude>&, ScriptShaderInclude**);
 	template BS_SCR_BE_EXPORT void ScriptResourceManager::createScriptResource(MonoObject*, const ResourceHandle<Prefab>&, ScriptPrefab**);
 	template BS_SCR_BE_EXPORT void ScriptResourceManager::createScriptResource(MonoObject*, const ResourceHandle<Font>&, ScriptFont**);
 	template BS_SCR_BE_EXPORT void ScriptResourceManager::createScriptResource(MonoObject*, const ResourceHandle<PlainText>&, ScriptPlainText**);
@@ -187,6 +192,7 @@ namespace BansheeEngine
 	template BS_SCR_BE_EXPORT void ScriptResourceManager::getScriptResource(const ResourceHandle<Mesh>& resourceHandle, ScriptMesh** out, bool create);
 	template BS_SCR_BE_EXPORT void ScriptResourceManager::getScriptResource(const ResourceHandle<Material>& resourceHandle, ScriptMaterial** out, bool create);
 	template BS_SCR_BE_EXPORT void ScriptResourceManager::getScriptResource(const ResourceHandle<Shader>& resourceHandle, ScriptShader** out, bool create);
+	template BS_SCR_BE_EXPORT void ScriptResourceManager::getScriptResource(const ResourceHandle<ShaderInclude>& resourceHandle, ScriptShaderInclude** out, bool create);
 	template BS_SCR_BE_EXPORT void ScriptResourceManager::getScriptResource(const ResourceHandle<Prefab>& resourceHandle, ScriptPrefab** out, bool create);
 	template BS_SCR_BE_EXPORT void ScriptResourceManager::getScriptResource(const ResourceHandle<Font>& resourceHandle, ScriptFont** out, bool create);
 	template BS_SCR_BE_EXPORT void ScriptResourceManager::getScriptResource(const ResourceHandle<PlainText>& resourceHandle, ScriptPlainText** out, bool create);

+ 16 - 0
SBansheeEngine/Source/BsScriptShaderInclude.cpp

@@ -0,0 +1,16 @@
+#include "BsScriptShaderInclude.h"
+#include "BsMonoManager.h"
+
+namespace BansheeEngine
+{
+	ScriptShaderInclude::ScriptShaderInclude(MonoObject* instance, const HShaderInclude& shaderInclude)
+		:TScriptResource(instance, shaderInclude)
+	{
+
+	}
+
+	void ScriptShaderInclude::initRuntimeData()
+	{
+
+	}
+}

+ 2 - 0
TODO.txt

@@ -75,6 +75,8 @@ Finalizing:
 ----------------------------------------------------------------------
 Build system
  - Test Resources (if loading works and if they're properly packaged in build)
+ - Game/Editor assemblies in editor are compiled with debug information, add a toggle for this in build settings and recompile without it if needed
+  - Will also need to compile a different version of the built-in BansheeEngine assembly
  - 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
     - Which set of binaries is used depends on selected platform (e.g. win/mac/linux or 32/64bit)