Просмотр исходного кода

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

BearishSun 10 лет назад
Родитель
Сommit
d3b00942e8
31 измененных файлов с 452 добавлено и 18 удалено
  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);
 		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
 		 * @copydoc	GUIElement::setTint
 		 */
 		 */
@@ -112,6 +117,7 @@ namespace BansheeEngine
 		GUIButton* mMessage;
 		GUIButton* mMessage;
 		GUILabel* mScene;
 		GUILabel* mScene;
 		GUILabel* mProject;
 		GUILabel* mProject;
+		GUILabel* mCompiling;
 		GUITexture* mBackground;
 		GUITexture* mBackground;
 
 
 		HEvent mLogEntryAddedConn;
 		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&)> 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&)> 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 RESOURCES_DIR;
 		static const Path INTERNAL_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()));
 		mMessage = GUIButton::create(HString(L""), GUIOptions(GUIOption::flexibleWidth()), getSubStyleName(getGUIMessageTypeName()));
 		mScene = GUILabel::create(HString(L"Scene: Unnamed"), GUIOptions(GUIOption::fixedWidth(150)));
 		mScene = GUILabel::create(HString(L"Scene: Unnamed"), GUIOptions(GUIOption::fixedWidth(150)));
 		mProject = GUILabel::create(HString(L"Project: None"), GUIOptions(GUIOption::fixedWidth(200)));
 		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>();
 		GUILayoutY* vertLayout = mPanel->addNewElement<GUILayoutY>();
 		vertLayout->addNewElement<GUIFixedSpace>(3);
 		vertLayout->addNewElement<GUIFixedSpace>(3);
@@ -42,8 +43,11 @@ namespace BansheeEngine
 		horzLayout->addNewElement<GUIFixedSpace>(10);
 		horzLayout->addNewElement<GUIFixedSpace>(10);
 		horzLayout->addElement(mProject);
 		horzLayout->addElement(mProject);
 		horzLayout->addNewElement<GUIFixedSpace>(10);
 		horzLayout->addNewElement<GUIFixedSpace>(10);
+		horzLayout->addElement(mCompiling);
+		horzLayout->addNewElement<GUIFixedSpace>(10);
 
 
 		mBgPanel->addElement(mBackground);
 		mBgPanel->addElement(mBackground);
+		mCompiling->setActive(false);
 
 
 		mLogEntryAddedConn = gDebug().onLogEntryAdded.connect(std::bind(&GUIStatusBar::logEntryAdded, this, _1));
 		mLogEntryAddedConn = gDebug().onLogEntryAdded.connect(std::bind(&GUIStatusBar::logEntryAdded, this, _1));
 		mMessageBtnPressedConn = mMessage->onClick.connect(std::bind(&GUIStatusBar::messageBtnClicked, this));
 		mMessageBtnPressedConn = mMessage->onClick.connect(std::bind(&GUIStatusBar::messageBtnClicked, this));
@@ -104,6 +108,11 @@ namespace BansheeEngine
 
 
 		mScene->setContent(HString(content.str()));
 		mScene->setContent(HString(content.str()));
 	}
 	}
+
+	void GUIStatusBar::setIsCompiling(bool compiling)
+	{
+		mCompiling->setActive(compiling);
+	}
 	
 	
 	void GUIStatusBar::setTint(const Color& color)
 	void GUIStatusBar::setTint(const Color& color)
 	{
 	{

+ 5 - 3
BansheeEditor/Source/BsProjectLibrary.cpp

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

+ 34 - 1
MBansheeEditor/CodeEditor.cs

@@ -21,6 +21,19 @@ namespace BansheeEditor
     /// </summary>
     /// </summary>
     public static class CodeEditor
     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>
         /// <summary>
         /// Currently active code editor.
         /// Currently active code editor.
         /// </summary>
         /// </summary>
@@ -29,6 +42,14 @@ namespace BansheeEditor
             set { Internal_SetActiveEditor(value); }
             set { Internal_SetActiveEditor(value); }
         }
         }
 
 
+        /// <summary>
+        /// Checks if the code editor's solution requires updating.
+        /// </summary>
+        internal static bool IsSolutionDirty
+        {
+            get { return isSolutionDirty; }
+        }
+
         /// <summary>
         /// <summary>
         /// Returns a list of all code editors available on this machine.
         /// Returns a list of all code editors available on this machine.
         /// </summary>
         /// </summary>
@@ -40,10 +61,13 @@ namespace BansheeEditor
         /// <summary>
         /// <summary>
         /// Opens a script file in the currently active code editor.
         /// Opens a script file in the currently active code editor.
         /// </summary>
         /// </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>
         /// <param name="line">Line in the file to focus the editor on.</param>
         public static void OpenFile(string path, UInt32 line)
         public static void OpenFile(string path, UInt32 line)
         {
         {
+            if (IsSolutionDirty)
+                SyncSolution();
+
             Internal_OpenFile(path, line);
             Internal_OpenFile(path, line);
         }
         }
 
 
@@ -53,6 +77,15 @@ namespace BansheeEditor
         public static void SyncSolution()
         public static void SyncSolution()
         {
         {
             Internal_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)]
         [MethodImpl(MethodImplOptions.InternalCall)]

+ 31 - 4
MBansheeEditor/EditorApplication.cs

@@ -113,25 +113,26 @@ namespace BansheeEditor
         /// <summary>
         /// <summary>
         /// Name of the builtin assembly containing engine specific types.
         /// Name of the builtin assembly containing engine specific types.
         /// </summary>
         /// </summary>
-        internal static string EngineAssembly { get { return Internal_GetEngineAssemblyName(); } }
+        internal static string EngineAssemblyName { get { return Internal_GetEngineAssemblyName(); } }
 
 
         /// <summary>
         /// <summary>
         /// Name of the builtin assembly containing editor specific types.
         /// Name of the builtin assembly containing editor specific types.
         /// </summary>
         /// </summary>
-        internal static string EditorAssembly { get { return Internal_GetEditorAssemblyName(); } }
+        internal static string EditorAssemblyName { get { return Internal_GetEditorAssemblyName(); } }
 
 
         /// <summary>
         /// <summary>
         /// Name of the custom assembly compiled from non-editor scripts within the project.
         /// Name of the custom assembly compiled from non-editor scripts within the project.
         /// </summary>
         /// </summary>
-        internal static string ScriptGameAssembly { get { return Internal_GetScriptGameAssemblyName(); } }
+        internal static string ScriptGameAssemblyName { get { return Internal_GetScriptGameAssemblyName(); } }
 
 
         /// <summary>
         /// <summary>
         /// Name of the custom assembly compiled from editor scripts within the project.
         /// Name of the custom assembly compiled from editor scripts within the project.
         /// </summary>
         /// </summary>
-        internal static string ScriptEditorAssembly { get { return Internal_GetScriptEditorAssemblyName(); } }
+        internal static string ScriptEditorAssemblyName { get { return Internal_GetScriptEditorAssemblyName(); } }
 
 
         private static EditorApplication instance;
         private static EditorApplication instance;
         private static FolderMonitor monitor;
         private static FolderMonitor monitor;
+        private static ScriptCodeManager codeManager;
         private static HashSet<string> dirtyResources = new HashSet<string>();
         private static HashSet<string> dirtyResources = new HashSet<string>();
         private static bool sceneDirty;
         private static bool sceneDirty;
         private static bool unitTestsExecuted;
         private static bool unitTestsExecuted;
@@ -142,6 +143,7 @@ namespace BansheeEditor
         internal EditorApplication()
         internal EditorApplication()
         {
         {
             instance = this;
             instance = this;
+            codeManager = new ScriptCodeManager();
 
 
             // Register controls
             // Register controls
             InputConfiguration inputConfig = VirtualInput.KeyConfig;
             InputConfiguration inputConfig = VirtualInput.KeyConfig;
@@ -182,6 +184,7 @@ namespace BansheeEditor
         internal void OnEditorUpdate()
         internal void OnEditorUpdate()
         {
         {
             ProjectLibrary.Update();
             ProjectLibrary.Update();
+            codeManager.Update();
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -526,6 +529,15 @@ namespace BansheeEditor
                 continueUnload();
                 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>
         /// <summary>
         /// Changes the scene displayed on the status bar.
         /// Changes the scene displayed on the status bar.
         /// </summary>
         /// </summary>
@@ -545,6 +557,15 @@ namespace BansheeEditor
             Internal_SetStatusProject(modified);
             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>
         /// <summary>
         /// Checks did we make any modifications to the scene since it was last saved.
         /// Checks did we make any modifications to the scene since it was last saved.
         /// </summary>
         /// </summary>
@@ -570,6 +591,9 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_SetStatusProject(bool modified);
         private static extern void Internal_SetStatusProject(bool modified);
 
 
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetStatusCompiling(bool compiling);
+
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern string Internal_GetProjectPath();
         private static extern string Internal_GetProjectPath();
 
 
@@ -621,6 +645,9 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_CreateProject(string path);
         private static extern void Internal_CreateProject(string path);
 
 
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_ReloadAssemblies();
+
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_OpenExternally(string path);
         private static extern void Internal_OpenExternally(string path);
 
 

+ 6 - 0
MBansheeEditor/Library/LibraryGUIEntry.cs

@@ -291,6 +291,10 @@ namespace BansheeEditor
                     {
                     {
                         EditorApplication.LoadScene(resEntry.Path);
                         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);
                         return EditorBuiltin.GetLibraryItemIcon(LibraryItemIcon.SpriteTexture, size);
                     case ResourceType.Shader:
                     case ResourceType.Shader:
                         return EditorBuiltin.GetLibraryItemIcon(LibraryItemIcon.Shader, size);
                         return EditorBuiltin.GetLibraryItemIcon(LibraryItemIcon.Shader, size);
+                    case ResourceType.ShaderInclude:
+                        return EditorBuiltin.GetLibraryItemIcon(LibraryItemIcon.Shader, size);
                     case ResourceType.Material:
                     case ResourceType.Material:
                         return EditorBuiltin.GetLibraryItemIcon(LibraryItemIcon.Material, size);
                         return EditorBuiltin.GetLibraryItemIcon(LibraryItemIcon.Material, size);
                     case ResourceType.Prefab:
                     case ResourceType.Prefab:

+ 1 - 0
MBansheeEditor/MBansheeEditor.csproj

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

+ 18 - 1
MBansheeEditor/ProjectLibrary.cs

@@ -34,6 +34,12 @@ namespace BansheeEditor
         /// </summary>
         /// </summary>
         public static event Action<string> OnEntryRemoved;
         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 HashSet<string> queuedForImport = new HashSet<string>();
         private static int numImportedFiles;
         private static int numImportedFiles;
         private static int totalFilesToImport;
         private static int totalFilesToImport;
@@ -329,6 +335,16 @@ namespace BansheeEditor
                 OnEntryRemoved(path);
                 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)]
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern string[] Internal_Refresh(string path, bool import);
         private static extern string[] Internal_Refresh(string path, bool import);
 
 
@@ -394,7 +410,8 @@ namespace BansheeEditor
     /// </summary>
     /// </summary>
     public enum ResourceType // Note: Must match the C++ enum ScriptResourceType
     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>
     /// <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 = 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
             else
             {
             {
@@ -90,11 +90,11 @@ namespace BansheeEditor
                 };
                 };
 
 
                 assemblies = new string[frameworkAssemblies.Length + 3];
                 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);
             Array.Copy(frameworkAssemblies, assemblies, frameworkAssemblies.Length);

+ 1 - 0
MBansheeEngine/MBansheeEngine.csproj

@@ -135,6 +135,7 @@
     <Compile Include="SerializeObject.cs" />
     <Compile Include="SerializeObject.cs" />
     <Compile Include="SerializeField.cs" />
     <Compile Include="SerializeField.cs" />
     <Compile Include="Shader.cs" />
     <Compile Include="Shader.cs" />
+    <Compile Include="ShaderInclude.cs" />
     <Compile Include="ShortcutKey.cs" />
     <Compile Include="ShortcutKey.cs" />
     <Compile Include="Sphere.cs" />
     <Compile Include="Sphere.cs" />
     <Compile Include="SpriteTexture.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);
 		ScriptEditorApplication(MonoObject* instance);
 
 
 		static bool mRequestProjectLoad;
 		static bool mRequestProjectLoad;
+		static bool mRequestAssemblyReload;
 		static Path mProjectLoadPath;
 		static Path mProjectLoadPath;
 
 
 		/************************************************************************/
 		/************************************************************************/
@@ -29,6 +30,7 @@ namespace BansheeEngine
 		/************************************************************************/
 		/************************************************************************/
 		static void internal_SetStatusScene(MonoString* name, bool modified);
 		static void internal_SetStatusScene(MonoString* name, bool modified);
 		static void internal_SetStatusProject(bool modified);
 		static void internal_SetStatusProject(bool modified);
+		static void internal_SetStatusCompiling(bool compiling);
 		static MonoString* internal_GetProjectPath();
 		static MonoString* internal_GetProjectPath();
 		static MonoString* internal_GetProjectName();
 		static MonoString* internal_GetProjectName();
 		static bool internal_GetProjectLoaded();
 		static bool internal_GetProjectLoaded();
@@ -46,6 +48,7 @@ namespace BansheeEngine
 		static void internal_LoadProject(MonoString* path);
 		static void internal_LoadProject(MonoString* path);
 		static void internal_UnloadProject();
 		static void internal_UnloadProject();
 		static void internal_CreateProject(MonoString* path);
 		static void internal_CreateProject(MonoString* path);
+		static void internal_ReloadAssemblies();
 		static void internal_OpenExternally(MonoString* path);
 		static void internal_OpenExternally(MonoString* path);
 		static void internal_RunUnitTests();
 		static void internal_RunUnitTests();
 
 

+ 9 - 0
SBansheeEditor/Include/BsScriptProjectLibrary.h

@@ -42,8 +42,16 @@ namespace BansheeEngine
 		 */
 		 */
 		static void onEntryRemoved(const Path& path);
 		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 mOnEntryAddedConn;
 		static HEvent mOnEntryRemovedConn;
 		static HEvent mOnEntryRemovedConn;
+		static HEvent mOnEntryImportedConn;
 
 
 		/************************************************************************/
 		/************************************************************************/
 		/* 								CLR HOOKS						   		*/
 		/* 								CLR HOOKS						   		*/
@@ -52,6 +60,7 @@ namespace BansheeEngine
 
 
 		static OnEntryChangedThunkDef OnEntryAddedThunk;
 		static OnEntryChangedThunkDef OnEntryAddedThunk;
 		static OnEntryChangedThunkDef OnEntryRemovedThunk;
 		static OnEntryChangedThunkDef OnEntryRemovedThunk;
+		static OnEntryChangedThunkDef OnEntryImportedThunk;
 
 
 		static MonoArray* internal_Refresh(MonoString* path, bool import);
 		static MonoArray* internal_Refresh(MonoString* path, bool import);
 		static void internal_Create(MonoObject* resource, MonoString* path);
 		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 });
 			assemblies.push_back({ EDITOR_ASSEMBLY, editorAssemblyPath });
 			if (gEditorApplication().isProjectLoaded())
 			if (gEditorApplication().isProjectLoaded())
 			{
 			{
-				
 				if (FileSystem::exists(editorScriptAssemblyPath))
 				if (FileSystem::exists(editorScriptAssemblyPath))
 					assemblies.push_back({ SCRIPT_EDITOR_ASSEMBLY, editorScriptAssemblyPath });
 					assemblies.push_back({ SCRIPT_EDITOR_ASSEMBLY, editorScriptAssemblyPath });
 			}
 			}

+ 10 - 0
SBansheeEditor/Source/BsGUIResourceField.cpp

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

+ 21 - 0
SBansheeEditor/Source/BsScriptEditorApplication.cpp

@@ -14,6 +14,7 @@
 #include "BsGUIStatusBar.h"
 #include "BsGUIStatusBar.h"
 #include "BsScriptEditorTestSuite.h"
 #include "BsScriptEditorTestSuite.h"
 #include "BsTestOutput.h"
 #include "BsTestOutput.h"
+#include "BsScriptManager.h"
 #include "BsPlatform.h"
 #include "BsPlatform.h"
 #include "BsResources.h"
 #include "BsResources.h"
 #include "BsScriptEditorWindow.h"
 #include "BsScriptEditorWindow.h"
@@ -26,6 +27,7 @@
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
 	bool ScriptEditorApplication::mRequestProjectLoad = false;
 	bool ScriptEditorApplication::mRequestProjectLoad = false;
+	bool ScriptEditorApplication::mRequestAssemblyReload = false;
 	Path ScriptEditorApplication::mProjectLoadPath;
 	Path ScriptEditorApplication::mProjectLoadPath;
 
 
 	ScriptEditorApplication::OnProjectLoadedThunkDef ScriptEditorApplication::onProjectLoadedThunk;
 	ScriptEditorApplication::OnProjectLoadedThunkDef ScriptEditorApplication::onProjectLoadedThunk;
@@ -38,6 +40,7 @@ namespace BansheeEngine
 	{
 	{
 		metaData.scriptClass->addInternalCall("Internal_SetStatusScene", &ScriptEditorApplication::internal_SetStatusScene);
 		metaData.scriptClass->addInternalCall("Internal_SetStatusScene", &ScriptEditorApplication::internal_SetStatusScene);
 		metaData.scriptClass->addInternalCall("Internal_SetStatusProject", &ScriptEditorApplication::internal_SetStatusProject);
 		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_GetProjectPath", &ScriptEditorApplication::internal_GetProjectPath);
 		metaData.scriptClass->addInternalCall("Internal_GetProjectName", &ScriptEditorApplication::internal_GetProjectName);
 		metaData.scriptClass->addInternalCall("Internal_GetProjectName", &ScriptEditorApplication::internal_GetProjectName);
 		metaData.scriptClass->addInternalCall("Internal_GetProjectLoaded", &ScriptEditorApplication::internal_GetProjectLoaded);
 		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_LoadProject", &ScriptEditorApplication::internal_LoadProject);
 		metaData.scriptClass->addInternalCall("Internal_UnloadProject", &ScriptEditorApplication::internal_UnloadProject);
 		metaData.scriptClass->addInternalCall("Internal_UnloadProject", &ScriptEditorApplication::internal_UnloadProject);
 		metaData.scriptClass->addInternalCall("Internal_CreateProject", &ScriptEditorApplication::internal_CreateProject);
 		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_OpenExternally", &ScriptEditorApplication::internal_OpenExternally);
 		metaData.scriptClass->addInternalCall("Internal_RunUnitTests", &ScriptEditorApplication::internal_RunUnitTests);
 		metaData.scriptClass->addInternalCall("Internal_RunUnitTests", &ScriptEditorApplication::internal_RunUnitTests);
 
 
@@ -71,8 +75,14 @@ namespace BansheeEngine
 			gEditorApplication().loadProject(mProjectLoadPath);
 			gEditorApplication().loadProject(mProjectLoadPath);
 
 
 			mRequestProjectLoad = false;
 			mRequestProjectLoad = false;
+			mRequestAssemblyReload = false;
 			MonoUtil::invokeThunk(onProjectLoadedThunk);
 			MonoUtil::invokeThunk(onProjectLoadedThunk);
 		}
 		}
+		else if (mRequestAssemblyReload)
+		{
+			ScriptManager::instance().reload();
+			mRequestAssemblyReload = false;
+		}
 	}
 	}
 
 
 	void ScriptEditorApplication::internal_SetStatusScene(MonoString* name, bool modified)
 	void ScriptEditorApplication::internal_SetStatusScene(MonoString* name, bool modified)
@@ -93,6 +103,12 @@ namespace BansheeEngine
 			mainWindow->getStatusBar().setProject(L"None", false);
 			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()
 	MonoString* ScriptEditorApplication::internal_GetProjectPath()
 	{
 	{
 		Path projectPath = gEditorApplication().getProjectPath();
 		Path projectPath = gEditorApplication().getProjectPath();
@@ -219,6 +235,11 @@ namespace BansheeEngine
 		gEditorApplication().createProject(nativePath);
 		gEditorApplication().createProject(nativePath);
 	}
 	}
 
 
+	void ScriptEditorApplication::internal_ReloadAssemblies()
+	{
+		mRequestAssemblyReload = true;
+	}
+
 	void ScriptEditorApplication::internal_OpenExternally(MonoString* path)
 	void ScriptEditorApplication::internal_OpenExternally(MonoString* path)
 	{
 	{
 		Path nativePath = MonoUtil::monoToWString(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::OnEntryAddedThunk;
 	ScriptProjectLibrary::OnEntryChangedThunkDef ScriptProjectLibrary::OnEntryRemovedThunk;
 	ScriptProjectLibrary::OnEntryChangedThunkDef ScriptProjectLibrary::OnEntryRemovedThunk;
+	ScriptProjectLibrary::OnEntryChangedThunkDef ScriptProjectLibrary::OnEntryImportedThunk;
 
 
 	HEvent ScriptProjectLibrary::mOnEntryAddedConn;
 	HEvent ScriptProjectLibrary::mOnEntryAddedConn;
 	HEvent ScriptProjectLibrary::mOnEntryRemovedConn;
 	HEvent ScriptProjectLibrary::mOnEntryRemovedConn;
+	HEvent ScriptProjectLibrary::mOnEntryImportedConn;
 
 
 	ScriptProjectLibrary::ScriptProjectLibrary(MonoObject* instance)
 	ScriptProjectLibrary::ScriptProjectLibrary(MonoObject* instance)
 		:ScriptObject(instance)
 		:ScriptObject(instance)
@@ -53,6 +55,7 @@ namespace BansheeEngine
 
 
 		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();
+		OnEntryImportedThunk = (OnEntryChangedThunkDef)metaData.scriptClass->getMethod("Internal_DoOnEntryImported", 1)->getThunk();
 	}
 	}
 
 
 	MonoArray* ScriptProjectLibrary::internal_Refresh(MonoString* path, bool import)
 	MonoArray* ScriptProjectLibrary::internal_Refresh(MonoString* path, bool import)
@@ -256,12 +259,14 @@ namespace BansheeEngine
 	{
 	{
 		mOnEntryAddedConn = gProjectLibrary().onEntryAdded.connect(std::bind(&ScriptProjectLibrary::onEntryAdded, _1));
 		mOnEntryAddedConn = gProjectLibrary().onEntryAdded.connect(std::bind(&ScriptProjectLibrary::onEntryAdded, _1));
 		mOnEntryRemovedConn = gProjectLibrary().onEntryRemoved.connect(std::bind(&ScriptProjectLibrary::onEntryRemoved, _1));
 		mOnEntryRemovedConn = gProjectLibrary().onEntryRemoved.connect(std::bind(&ScriptProjectLibrary::onEntryRemoved, _1));
+		mOnEntryImportedConn = gProjectLibrary().onEntryImported.connect(std::bind(&ScriptProjectLibrary::onEntryImported, _1));
 	}
 	}
 
 
 	void ScriptProjectLibrary::shutDown()
 	void ScriptProjectLibrary::shutDown()
 	{
 	{
 		mOnEntryAddedConn.disconnect();
 		mOnEntryAddedConn.disconnect();
 		mOnEntryRemovedConn.disconnect();
 		mOnEntryRemovedConn.disconnect();
+		mOnEntryImportedConn.disconnect();
 	}
 	}
 
 
 	void ScriptProjectLibrary::onEntryAdded(const Path& path)
 	void ScriptProjectLibrary::onEntryAdded(const Path& path)
@@ -284,6 +289,16 @@ namespace BansheeEngine
 		MonoUtil::invokeThunk(OnEntryRemovedThunk, pathStr);
 		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)
 	ScriptLibraryEntryBase::ScriptLibraryEntryBase(MonoObject* instance)
 		:ScriptObjectBase(instance)
 		:ScriptObjectBase(instance)
 	{ }
 	{ }

+ 1 - 0
SBansheeEngine/Include/BsManagedSerializableObjectInfo.h

@@ -32,6 +32,7 @@ namespace BansheeEngine
 		PlainTextRef,
 		PlainTextRef,
 		ScriptCodeRef,
 		ScriptCodeRef,
 		ShaderRef,
 		ShaderRef,
+		ShaderIncludeRef,
 		MaterialRef,
 		MaterialRef,
 		MeshRef,
 		MeshRef,
 		PrefabRef,
 		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
 	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\BsScriptSerializableProperty.h" />
     <ClInclude Include="Include\BsScriptSerializableUtility.h" />
     <ClInclude Include="Include\BsScriptSerializableUtility.h" />
     <ClInclude Include="Include\BsScriptShader.h" />
     <ClInclude Include="Include\BsScriptShader.h" />
+    <ClInclude Include="Include\BsScriptShaderInclude.h" />
     <ClInclude Include="Include\BsScriptSpriteTexture.h" />
     <ClInclude Include="Include\BsScriptSpriteTexture.h" />
     <ClInclude Include="Include\BsScriptStringTable.h" />
     <ClInclude Include="Include\BsScriptStringTable.h" />
     <ClInclude Include="Include\BsScriptStringTableManager.h" />
     <ClInclude Include="Include\BsScriptStringTableManager.h" />
@@ -439,6 +440,7 @@
     <ClCompile Include="Source\BsScriptSerializableProperty.cpp" />
     <ClCompile Include="Source\BsScriptSerializableProperty.cpp" />
     <ClCompile Include="Source\BsScriptSerializableUtility.cpp" />
     <ClCompile Include="Source\BsScriptSerializableUtility.cpp" />
     <ClCompile Include="Source\BsScriptShader.cpp" />
     <ClCompile Include="Source\BsScriptShader.cpp" />
+    <ClCompile Include="Source\BsScriptShaderInclude.cpp" />
     <ClCompile Include="Source\BsScriptSpriteTexture.cpp" />
     <ClCompile Include="Source\BsScriptSpriteTexture.cpp" />
     <ClCompile Include="Source\BsScriptStringTable.cpp" />
     <ClCompile Include="Source\BsScriptStringTable.cpp" />
     <ClCompile Include="Source\BsScriptStringTableManager.cpp" />
     <ClCompile Include="Source\BsScriptStringTableManager.cpp" />

+ 6 - 0
SBansheeEngine/SBansheeEngine.vcxproj.filters

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

+ 28 - 0
SBansheeEngine/Source/BsManagedSerializableField.cpp

@@ -13,6 +13,7 @@
 #include "BsScriptPlainText.h"
 #include "BsScriptPlainText.h"
 #include "BsScriptScriptCode.h"
 #include "BsScriptScriptCode.h"
 #include "BsScriptShader.h"
 #include "BsScriptShader.h"
+#include "BsScriptShaderInclude.h"
 #include "BsScriptMaterial.h"
 #include "BsScriptMaterial.h"
 #include "BsScriptMesh.h"
 #include "BsScriptMesh.h"
 #include "BsScriptPrefab.h"
 #include "BsScriptPrefab.h"
@@ -248,6 +249,18 @@ namespace BansheeEngine
 
 
 				return fieldData;
 				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:
 			case ScriptPrimitiveType::MaterialRef:
 			{
 			{
 				auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataResourceRef>();
 				auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataResourceRef>();
@@ -674,6 +687,21 @@ namespace BansheeEngine
 				else
 				else
 					return nullptr;
 					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)
 			else if (primitiveTypeInfo->mType == ScriptPrimitiveType::MaterialRef)
 			{
 			{
 				if (value)
 				if (value)

+ 3 - 0
SBansheeEngine/Source/BsManagedSerializableObjectInfo.cpp

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

+ 7 - 0
SBansheeEngine/Source/BsScriptAssemblyManager.cpp

@@ -17,6 +17,7 @@
 #include "BsScriptMesh.h"
 #include "BsScriptMesh.h"
 #include "BsScriptFont.h"
 #include "BsScriptFont.h"
 #include "BsScriptShader.h"
 #include "BsScriptShader.h"
+#include "BsScriptShaderInclude.h"
 #include "BsScriptPlainText.h"
 #include "BsScriptPlainText.h"
 #include "BsScriptScriptCode.h"
 #include "BsScriptScriptCode.h"
 #include "BsScriptStringTable.h"
 #include "BsScriptStringTable.h"
@@ -303,6 +304,12 @@ namespace BansheeEngine
 				typeInfo->mType = ScriptPrimitiveType::ShaderRef;
 				typeInfo->mType = ScriptPrimitiveType::ShaderRef;
 				return typeInfo;
 				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))
 			else if (monoClass->isSubClassOf(ScriptMaterial::getMetaData()->scriptClass))
 			{
 			{
 				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
 				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;
 			return ScriptResourceType::Mesh;
 		case TID_Shader:
 		case TID_Shader:
 			return ScriptResourceType::Shader;
 			return ScriptResourceType::Shader;
+		case TID_ShaderInclude:
+			return ScriptResourceType::ShaderInclude;
 		case TID_Material:
 		case TID_Material:
 			return ScriptResourceType::Material;
 			return ScriptResourceType::Material;
 		case TID_Font:
 		case TID_Font:
@@ -80,6 +82,8 @@ namespace BansheeEngine
 			return TID_Mesh;
 			return TID_Mesh;
 		case ScriptResourceType::Shader:
 		case ScriptResourceType::Shader:
 			return TID_Shader;
 			return TID_Shader;
+		case ScriptResourceType::ShaderInclude:
+			return TID_ShaderInclude;
 		case ScriptResourceType::Font:
 		case ScriptResourceType::Font:
 			return TID_Font;
 			return TID_Font;
 		case ScriptResourceType::Material:
 		case ScriptResourceType::Material:

+ 6 - 0
SBansheeEngine/Source/BsScriptResourceManager.cpp

@@ -10,6 +10,7 @@
 #include "BsScriptPlainText.h"
 #include "BsScriptPlainText.h"
 #include "BsScriptScriptCode.h"
 #include "BsScriptScriptCode.h"
 #include "BsScriptShader.h"
 #include "BsScriptShader.h"
+#include "BsScriptShaderInclude.h"
 #include "BsScriptMaterial.h"
 #include "BsScriptMaterial.h"
 #include "BsScriptMesh.h"
 #include "BsScriptMesh.h"
 #include "BsScriptFont.h"
 #include "BsScriptFont.h"
@@ -130,6 +131,8 @@ namespace BansheeEngine
 			return createScriptResource(static_resource_cast<ScriptCode>(resourceHandle), (ScriptScriptCode**)out);
 			return createScriptResource(static_resource_cast<ScriptCode>(resourceHandle), (ScriptScriptCode**)out);
 		case TID_Shader:
 		case TID_Shader:
 			return createScriptResource(static_resource_cast<Shader>(resourceHandle), (ScriptShader**)out);
 			return createScriptResource(static_resource_cast<Shader>(resourceHandle), (ScriptShader**)out);
+		case TID_ShaderInclude:
+			return createScriptResource(static_resource_cast<ShaderInclude>(resourceHandle), (ScriptShaderInclude**)out);
 		case TID_Prefab:
 		case TID_Prefab:
 			return createScriptResource(static_resource_cast<Prefab>(resourceHandle), (ScriptPrefab**)out);
 			return createScriptResource(static_resource_cast<Prefab>(resourceHandle), (ScriptPrefab**)out);
 		case TID_StringTable:
 		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<Mesh>&, ScriptMesh**);
 	template BS_SCR_BE_EXPORT void ScriptResourceManager::createScriptResource(const ResourceHandle<Material>&, ScriptMaterial**);
 	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<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<Prefab>&, ScriptPrefab**);
 	template BS_SCR_BE_EXPORT void ScriptResourceManager::createScriptResource(const ResourceHandle<Font>&, ScriptFont**);
 	template BS_SCR_BE_EXPORT void ScriptResourceManager::createScriptResource(const ResourceHandle<Font>&, ScriptFont**);
 	template BS_SCR_BE_EXPORT void ScriptResourceManager::createScriptResource(const ResourceHandle<PlainText>&, ScriptPlainText**);
 	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<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<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<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<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<Font>&, ScriptFont**);
 	template BS_SCR_BE_EXPORT void ScriptResourceManager::createScriptResource(MonoObject*, const ResourceHandle<PlainText>&, ScriptPlainText**);
 	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<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<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<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<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<Font>& resourceHandle, ScriptFont** out, bool create);
 	template BS_SCR_BE_EXPORT void ScriptResourceManager::getScriptResource(const ResourceHandle<PlainText>& resourceHandle, ScriptPlainText** 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
 Build system
  - Test Resources (if loading works and if they're properly packaged in build)
  - 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:
  - 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)