Browse Source

Modified GUI so GUI elements always destroy their children when they are destroyed
Added methods and UI for modifying arrays in Inspector (WIP)
Added updatePlugin functions to plugins
Mono method calls will always forward exceptions to C++ now
Fixed a Win32 compilation error due to incorrect function call type

Marko Pintera 11 years ago
parent
commit
3fcc9e78d4

+ 4 - 0
BansheeCore/Include/BsCoreApplication.h

@@ -95,11 +95,15 @@ namespace BansheeEngine
 		void endCoreProfiling();
 
 	private:
+		typedef void(*UpdatePluginFunc)();
+
 		RenderWindowPtr mPrimaryWindow;
 
 		DynLib* mSceneManagerPlugin;
 		DynLib* mRendererPlugin;
 
+		Map<DynLib*, UpdatePluginFunc> mPluginUpdateFunctions;
+
 		bool mIsFrameRenderingFinished;
 		BS_MUTEX(mFrameRenderingFinishedMutex);
 		BS_THREAD_SYNCHRONISER(mFrameRenderingFinishedCondition);

+ 15 - 3
BansheeCore/Source/BsCoreApplication.cpp

@@ -171,6 +171,10 @@ namespace BansheeEngine
 			gCoreThread().queueCommand(std::bind(&CoreApplication::beginCoreProfiling, this));
 			gCoreThread().queueCommand(std::bind(&QueryManager::_update, QueryManager::instancePtr()));
 
+			// Update plugins
+			for (auto& pluginUpdateFunc : mPluginUpdateFunctions)
+				pluginUpdateFunc.second();
+
 			update();
 
 			PROFILE_CALL(RendererManager::instance().getActive()->renderAll(), "Render");
@@ -256,6 +260,7 @@ namespace BansheeEngine
 		if(library != nullptr)
 			*library = loadedLibrary;
 
+		void* retVal = nullptr;
 		if(loadedLibrary != nullptr)
 		{
 			if (passThrough == nullptr)
@@ -265,7 +270,7 @@ namespace BansheeEngine
 				LoadPluginFunc loadPluginFunc = (LoadPluginFunc)loadedLibrary->getSymbol("loadPlugin");
 
 				if (loadPluginFunc != nullptr)
-					return loadPluginFunc();
+					retVal = loadPluginFunc();
 			}
 			else
 			{
@@ -274,11 +279,16 @@ namespace BansheeEngine
 				LoadPluginFunc loadPluginFunc = (LoadPluginFunc)loadedLibrary->getSymbol("loadPlugin");
 
 				if (loadPluginFunc != nullptr)
-					return loadPluginFunc(passThrough);
+					retVal = loadPluginFunc(passThrough);
 			}
+
+			UpdatePluginFunc loadPluginFunc = (UpdatePluginFunc)loadedLibrary->getSymbol("updatePlugin");
+
+			if (loadPluginFunc != nullptr)
+				mPluginUpdateFunctions[loadedLibrary] = loadPluginFunc;
 		}
 
-		return nullptr;
+		return retVal;
 	}
 
 	void CoreApplication::unloadPlugin(DynLib* library)
@@ -290,6 +300,8 @@ namespace BansheeEngine
 		if(unloadPluginFunc != nullptr)
 			unloadPluginFunc();
 
+		mPluginUpdateFunctions.erase(library);
+
 		gDynLibManager().unload(library);
 	}
 

+ 1 - 1
BansheeCore/Source/BsPixelUtil.cpp

@@ -843,7 +843,7 @@ namespace BansheeEngine
 
 		virtual void beginImage(int size, int width, int height, int depth, int face, int miplevel)
 		{ 
-			assert(miplevel >= 0 && miplevel < buffers.size());
+			assert(miplevel >= 0 && miplevel < (int)buffers.size());
 			assert(size == buffers[miplevel]->getConsecutiveSize());
 
 			activeBuffer = buffers[miplevel];

+ 8 - 8
BansheeEngine.sln

@@ -224,10 +224,10 @@ Global
 		{876EB338-489E-4727-84DA-8CBBF0DA5B5E}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{876EB338-489E-4727-84DA-8CBBF0DA5B5E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
 		{876EB338-489E-4727-84DA-8CBBF0DA5B5E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
-		{876EB338-489E-4727-84DA-8CBBF0DA5B5E}.Debug|Win32.ActiveCfg = Release|Any CPU
-		{876EB338-489E-4727-84DA-8CBBF0DA5B5E}.Debug|Win32.Build.0 = Release|Any CPU
-		{876EB338-489E-4727-84DA-8CBBF0DA5B5E}.Debug|x64.ActiveCfg = Release|Any CPU
-		{876EB338-489E-4727-84DA-8CBBF0DA5B5E}.Debug|x64.Build.0 = Release|Any CPU
+		{876EB338-489E-4727-84DA-8CBBF0DA5B5E}.Debug|Win32.ActiveCfg = Debug|Any CPU
+		{876EB338-489E-4727-84DA-8CBBF0DA5B5E}.Debug|Win32.Build.0 = Debug|Any CPU
+		{876EB338-489E-4727-84DA-8CBBF0DA5B5E}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{876EB338-489E-4727-84DA-8CBBF0DA5B5E}.Debug|x64.Build.0 = Debug|Any CPU
 		{876EB338-489E-4727-84DA-8CBBF0DA5B5E}.DebugRelease|Any CPU.ActiveCfg = Release|Any CPU
 		{876EB338-489E-4727-84DA-8CBBF0DA5B5E}.DebugRelease|Any CPU.Build.0 = Release|Any CPU
 		{876EB338-489E-4727-84DA-8CBBF0DA5B5E}.DebugRelease|Mixed Platforms.ActiveCfg = Release|Any CPU
@@ -248,10 +248,10 @@ Global
 		{ABC62E37-342E-4345-A374-E37CA06C036E}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{ABC62E37-342E-4345-A374-E37CA06C036E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
 		{ABC62E37-342E-4345-A374-E37CA06C036E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
-		{ABC62E37-342E-4345-A374-E37CA06C036E}.Debug|Win32.ActiveCfg = Release|Any CPU
-		{ABC62E37-342E-4345-A374-E37CA06C036E}.Debug|Win32.Build.0 = Release|Any CPU
-		{ABC62E37-342E-4345-A374-E37CA06C036E}.Debug|x64.ActiveCfg = Release|Any CPU
-		{ABC62E37-342E-4345-A374-E37CA06C036E}.Debug|x64.Build.0 = Release|Any CPU
+		{ABC62E37-342E-4345-A374-E37CA06C036E}.Debug|Win32.ActiveCfg = Debug|Any CPU
+		{ABC62E37-342E-4345-A374-E37CA06C036E}.Debug|Win32.Build.0 = Debug|Any CPU
+		{ABC62E37-342E-4345-A374-E37CA06C036E}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{ABC62E37-342E-4345-A374-E37CA06C036E}.Debug|x64.Build.0 = Debug|Any CPU
 		{ABC62E37-342E-4345-A374-E37CA06C036E}.DebugRelease|Any CPU.ActiveCfg = Release|Any CPU
 		{ABC62E37-342E-4345-A374-E37CA06C036E}.DebugRelease|Any CPU.Build.0 = Release|Any CPU
 		{ABC62E37-342E-4345-A374-E37CA06C036E}.DebugRelease|Mixed Platforms.ActiveCfg = Release|Any CPU

+ 9 - 7
BansheeEngine/Source/BsGUIElementBase.cpp

@@ -15,16 +15,16 @@ namespace BansheeEngine
 
 	GUIElementBase::~GUIElementBase()
 	{
-		for(auto& child : mChildren)
+		for (auto& child : mChildren)
 		{
-			// Non-GUIElement are owned by us
-			if(child->_getType() != GUIElementBase::Type::Element)
-				bs_delete<PoolAlloc>(child);
-			else
+			if (child->_getType() == GUIElementBase::Type::Element)
 			{
 				GUIElement* element = static_cast<GUIElement*>(child);
 				element->_setParent(nullptr);
+				GUIElement::destroy(element);
 			}
+			else
+				bs_delete(child);
 		}
 	}
 
@@ -119,11 +119,13 @@ namespace BansheeEngine
 		{
 			mParentElement = parent; 
 
-			if(parent != nullptr)
+			if (parent != nullptr)
 			{
-				if(_getParentWidget() != parent->_getParentWidget())
+				if (_getParentWidget() != parent->_getParentWidget())
 					_changeParentWidget(parent->_getParentWidget());
 			}
+			else
+				_changeParentWidget(nullptr);
 		}
 	}
 

+ 5 - 5
BansheeEngine/Source/BsGUIWidget.cpp

@@ -147,11 +147,11 @@ namespace BansheeEngine
 
 		auto iterFind = std::find(begin(mElements), end(mElements), elem);
 
-		if(iterFind == mElements.end())
-			BS_EXCEPT(InvalidParametersException, "Cannot unregister an element that is not registered on this widget.");
-
-		mElements.erase(iterFind);
-		mWidgetIsDirty = true;
+		if (iterFind != mElements.end())
+		{
+			mElements.erase(iterFind);
+			mWidgetIsDirty = true;
+		}
 	}
 
 	void GUIWidget::registerArea(GUIArea* area)

+ 2 - 2
BansheeGLRenderSystem/Source/BsGLRenderSystem.cpp

@@ -29,7 +29,7 @@ namespace BansheeEngine
 {
 	String MODULE_NAME = "BansheeGLRenderSystem.dll";
 
-	void openGlErrorCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, GLvoid *userParam);
+	void __stdcall openGlErrorCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, GLvoid *userParam);
 
 	/************************************************************************/
 	/* 								PUBLIC INTERFACE                   		*/
@@ -2068,7 +2068,7 @@ namespace BansheeEngine
 		dest = matrix;
 	}
 
-	void openGlErrorCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, GLvoid *userParam)
+	void __stdcall openGlErrorCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, GLvoid *userParam)
 	{
 		BS_EXCEPT(RenderingAPIException, "OpenGL error: " + String(message));
 	}

+ 11 - 2
BansheeMono/Source/BsMonoMethod.cpp

@@ -1,5 +1,6 @@
 #include "BsMonoMethod.h"
 #include "BsMonoManager.h"
+#include "BsMonoUtil.h"
 
 namespace BansheeEngine
 {
@@ -11,14 +12,22 @@ namespace BansheeEngine
 
 	MonoObject* MonoMethod::invoke(MonoObject* instance, void** params)
 	{
-		return mono_runtime_invoke(mMethod, instance, params, nullptr);
+		MonoObject* exception = nullptr;
+		MonoObject* retVal = mono_runtime_invoke(mMethod, instance, params, &exception);
+
+		MonoUtil::throwIfException(exception);
+		return retVal;
 	}		
 
 	MonoObject* MonoMethod::invokeVirtual(MonoObject* instance, void** params)
 	{
 		::MonoMethod* virtualMethod = mono_object_get_virtual_method(instance, mMethod);
 
-		return mono_runtime_invoke(virtualMethod, instance, params, nullptr);
+		MonoObject* exception = nullptr;
+		MonoObject* retVal = mono_runtime_invoke(virtualMethod, instance, params, nullptr);
+
+		MonoUtil::throwIfException(exception);
+		return retVal;
 	}		
 
 	void* MonoMethod::getThunk() const

+ 2 - 0
Inspector.txt

@@ -3,6 +3,8 @@ Update GUIFoldout with sub styles
 
 Test if drag and dropping scene objects works with object and resource fields. Especially custom resources and components.
 
+Test clone method in SerializableProperty
+
 Test custom resources:
  - Can I load them? (Will likely need ProjectLIbrary::load)
  - Can I reference them in Component and will the reference be held after after cloning?

+ 9 - 3
MBansheeEditor/Inspector/InspectableArray.cs

@@ -18,7 +18,7 @@ namespace BansheeEditor
             public GUIButton moveUpBtn;
             public GUIButton moveDownBtn;
 
-            public EntryRow(GUILayout parentLayout)
+            public EntryRow(GUILayout parentLayout, int seqIndex, InspectableArray parent)
             {
                 rowLayout = parentLayout.AddLayoutX();
                 contentLayout = rowLayout.AddLayoutY();
@@ -27,6 +27,11 @@ namespace BansheeEditor
                 moveUpBtn = new GUIButton("Up");
                 moveDownBtn = new GUIButton("Down");
 
+                cloneBtn.OnClick += () => parent.OnCloneButtonClicked(seqIndex);
+                deleteBtn.OnClick += () => parent.OnDeleteButtonClicked(seqIndex);
+                moveUpBtn.OnClick += () => parent.OnMoveUpButtonClicked(seqIndex);
+                moveDownBtn.OnClick += () => parent.OnMoveDownButtonClicked(seqIndex);
+
                 rowLayout.AddElement(cloneBtn);
                 rowLayout.AddElement(deleteBtn);
                 rowLayout.AddElement(moveUpBtn);
@@ -74,6 +79,7 @@ namespace BansheeEditor
 
             guiLabel = new GUILabel(title); // TODO - Add foldout and hook up its callbacks
             guiSizeField = new GUIIntField();
+            guiSizeField.Value = property.GetArray().GetLength();
             guiSizeField.SetRange(0, int.MaxValue);
             guiResizeBtn = new GUIButton("Resize");
             guiResizeBtn.OnClick += OnResizeButtonClicked;
@@ -128,7 +134,7 @@ namespace BansheeEditor
             numArrayElements = array.GetLength();
             for (int i = 0; i < numArrayElements; i++)
             {
-                EntryRow newRow = new EntryRow(guiContentLayout);
+                EntryRow newRow = new EntryRow(guiContentLayout, i, this);
                 rows.Add(newRow);
 
                 InspectableObjectBase childObj = CreateDefaultInspectable(i + ".", new InspectableFieldLayout(newRow.contentLayout), array.GetProperty(i));
@@ -189,7 +195,7 @@ namespace BansheeEditor
 
                 if (i == index)
                 {
-                    // TODO - Clone
+                    clonedEntry = array.GetProperty(i).GetValueCopy<object>();
                 }
             }
 

+ 4 - 3
MBansheeEditor/Inspector/InspectableObjectBase.cs

@@ -67,10 +67,11 @@ namespace BansheeEditor
         protected virtual void Update(int layoutIndex)
         {
             // Destroy all children as we expect update to rebuild them
-
             InspectableObjectBase[] childrenCopy = children.ToArray();
             for (int i = 0; i < childrenCopy.Length; i++)
-                children[i].Destroy();
+            {
+                childrenCopy[i].Destroy();
+            }
 
             children.Clear();
         }
@@ -81,7 +82,7 @@ namespace BansheeEditor
 
             InspectableObjectBase[] childrenCopy = children.ToArray();
             for (int i = 0; i < childrenCopy.Length; i++)
-                children[i].Destroy();
+                childrenCopy[i].Destroy();
 
             children.Clear();
 

+ 8 - 2
MBansheeEditor/Program.cs

@@ -6,16 +6,17 @@ namespace BansheeEditor
 {
     class ProgramEd
     {
+        private static InspectorWindow window;
+
         static void Main()
         {
-            InspectorWindow window = EditorWindow.OpenWindow<InspectorWindow>();
+            window = EditorWindow.OpenWindow<InspectorWindow>();
 
             SceneObject newDbgObject = new SceneObject("NewDbgObject");
             newDbgObject.AddComponent<Debug_Component1>();
             newDbgObject.AddComponent<Debug_Component2>();
 
             window.SetObjectToInspect(newDbgObject);
-            window.Refresh(); // TODO - This should be called N times per second
 
             DbgResource testResource = new DbgResource();
             //ProjectLibrary.Create(testResource, @"D:\DummyBansheeProject\Resources\testResource");
@@ -35,6 +36,11 @@ namespace BansheeEditor
 
             //dbgStyle.textColor = newColor;
         }
+
+        static void EditorUpdate()
+        {
+            window.Refresh();
+        }
     }
 
     //class SceneView : EditorWindow

+ 1 - 1
MBansheeEngine/GUI/GUIElement.cs

@@ -12,7 +12,7 @@ namespace BansheeEngine
         internal virtual void SetParent(GUILayout layout)
         {
             if (parent != null)
-                parent.Remove(this);
+                parent.RemoveInternal(this);
 
             parent = layout;
         }

+ 7 - 1
MBansheeEngine/GUI/GUILayout.cs

@@ -51,10 +51,16 @@ namespace BansheeEngine
             return false;
         }
 
+
+        internal void RemoveInternal(GUIElement element)
+        {
+            children.Remove(element);
+        }
+
         internal override void SetParent(GUILayout layout)
         {
             if (parent != null)
-                parent.Remove(this);
+                parent.RemoveInternal(this);
 
             parent = layout;
 

+ 25 - 18
MBansheeEngine/Program.cs

@@ -1,6 +1,7 @@
 using System;
 using System.Collections.Generic;
 using System.Runtime.CompilerServices;
+using System.Diagnostics;
 
 [assembly: InternalsVisibleTo("MBansheeEditor")]
 
@@ -8,7 +9,8 @@ namespace BansheeEngine
 {
     class Program
     {
-        static void Main()
+        // TODO: Make this an actual unit test
+        static void UnitTest1_ManagedSerialization()
         {
             SceneObject otherSO = new SceneObject("OtherSO");
             DbgComponent2 dbgComponent2 = otherSO.AddComponent<DbgComponent2>();
@@ -83,24 +85,35 @@ namespace BansheeEngine
 
             //dbgComponent.zeArray[4][1][3] = 129;
 
-            dbgTestComponentClone(so);
+            UnitTest1_GameObjectClone(so);
 
             for (int i = 0; i < so.GetNumChildren(); i++)
             {
                 SceneObject childSO = so.GetChild(i);
 
                 DbgComponent otherComponent = childSO.GetComponent<DbgComponent>();
-                reportDbgValue(otherComponent.a, otherComponent.b, otherComponent.complex.someValue,
-                               otherComponent.complex2.anotherValue2);
-
-                reportDbgValue(otherComponent.arrA[4], otherComponent.arrB[4], otherComponent.arrComplex[4].someValue,
-                  otherComponent.arrComplex2[4].anotherValue2);
-
-                reportDbgValue(otherComponent.listA[0], otherComponent.listB[0], otherComponent.listComplex[1].someValue,
-                    otherComponent.listComplex2[0].anotherValue2);
-
-                //reportDbgValue(childSO.GetComponent<DbgComponent>().zeDict["lolz"], childSO.GetComponent<DbgComponent>().zeList[2].someValue, childSO.GetComponent<DbgComponent>().zeArray[4][1][3], typeof(DbgComponent));
+                System.Diagnostics.Debug.Assert(otherComponent.a == 5);
+                System.Diagnostics.Debug.Assert(otherComponent.b == "SomeTestVal");
+                System.Diagnostics.Debug.Assert(otherComponent.complex.someValue == 19);
+                System.Diagnostics.Debug.Assert(otherComponent.complex2.anotherValue2 == "AnotherValue2");
+
+                System.Diagnostics.Debug.Assert(otherComponent.arrA[4] == 5);
+                System.Diagnostics.Debug.Assert(otherComponent.arrB[4] == "ArrAnotherValue");
+                System.Diagnostics.Debug.Assert(otherComponent.arrComplex[4].someValue == 99);
+                System.Diagnostics.Debug.Assert(otherComponent.arrComplex2[4].anotherValue2 == "ArrComplex2AnotherValue");
+
+                System.Diagnostics.Debug.Assert(otherComponent.listA[0] == 5);
+                System.Diagnostics.Debug.Assert(otherComponent.listB[0] == "ListAnotherValue");
+                System.Diagnostics.Debug.Assert(otherComponent.listComplex[1].someValue == 99);
+                System.Diagnostics.Debug.Assert(otherComponent.listComplex2[0].anotherValue2 == "ListComplexAnotherValue");
             }
+        }
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void UnitTest1_GameObjectClone(SceneObject so);
+        static void Main()
+        {
+            UnitTest1_ManagedSerialization();
 
             //Color newColor = Color.red;
 
@@ -133,11 +146,5 @@ namespace BansheeEngine
             else
                 Debug.Log("New value: " + prop2.GetValue<DbgSerzCls>().anotherValue2);
         }
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void dbgTestComponentClone(SceneObject so);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void reportDbgValue(int a, string b, int a2, string b2);
     }
 }

+ 24 - 0
SBansheeEditor/Include/BsEditorScriptManager.h

@@ -0,0 +1,24 @@
+#pragma once
+
+#include "BsScriptEditorPrerequisites.h"
+#include "BsModule.h"
+
+namespace BansheeEngine
+{
+	class BS_SCR_BED_EXPORT EditorScriptManager : public Module<EditorScriptManager>
+	{
+	public:
+		EditorScriptManager();
+
+		void update();
+
+	private:
+		static const float EDITOR_UPDATE_RATE;
+
+		MonoAssembly* mEditorAssembly;
+		float mLastUpdateTime;
+
+		MonoClass* mProgramEdClass;
+		MonoMethod* mUpdateMethod;
+	};
+}

+ 2 - 0
SBansheeEditor/SBansheeEditor.vcxproj

@@ -226,6 +226,7 @@
     </Link>
   </ItemDefinitionGroup>
   <ItemGroup>
+    <ClInclude Include="Include\BsEditorScriptManager.h" />
     <ClInclude Include="Include\BsGUIGameObjectField.h" />
     <ClInclude Include="Include\BsGUIPanelContainer.h" />
     <ClInclude Include="Include\BsGUIResourceField.h" />
@@ -246,6 +247,7 @@
     <ClInclude Include="Include\BsScriptProjectLibrary.h" />
   </ItemGroup>
   <ItemGroup>
+    <ClCompile Include="Source\BsEditorScriptManager.cpp" />
     <ClCompile Include="Source\BsGUIGameObjectField.cpp" />
     <ClCompile Include="Source\BsGUIPanelContainer.cpp" />
     <ClCompile Include="Source\BsGUIResourceField.cpp" />

+ 6 - 0
SBansheeEditor/SBansheeEditor.vcxproj.filters

@@ -69,6 +69,9 @@
     <ClInclude Include="Include\BsScriptProjectLibrary.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="Include\BsEditorScriptManager.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsScriptEditorPlugin.cpp">
@@ -125,5 +128,8 @@
     <ClCompile Include="Source\BsScriptProjectLibrary.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="Source\BsEditorScriptManager.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 50 - 0
SBansheeEditor/Source/BsEditorScriptManager.cpp

@@ -0,0 +1,50 @@
+#include "BsEditorScriptManager.h"
+#include "BsScriptEditorWindow.h"
+#include "BsMonoManager.h"
+#include "BsMonoAssembly.h"
+#include "BsMonoClass.h"
+#include "BsMonoMethod.h"
+#include "BsRuntimeScriptObjects.h"
+#include "BsTime.h"
+#include "BsMath.h"
+
+namespace BansheeEngine
+{
+	const float EditorScriptManager::EDITOR_UPDATE_RATE = 1.0f/60.0f; // Seconds
+
+	EditorScriptManager::EditorScriptManager()
+		:mEditorAssembly(nullptr), mProgramEdClass(nullptr), mUpdateMethod(nullptr)
+	{
+		const String ENGINE_ASSEMBLY_PATH = "..\\..\\Assemblies\\MBansheeEditor.dll";
+		const String ENGINE_ASSEMBLY_NAME = BansheeEditorAssemblyName;
+		const String ASSEMBLY_ENTRY_POINT = "ProgramEd::Main";
+
+		mEditorAssembly = &MonoManager::instance().loadAssembly(ENGINE_ASSEMBLY_PATH, ENGINE_ASSEMBLY_NAME);
+		ScriptEditorWindow::registerManagedEditorWindows();
+
+		RuntimeScriptObjects::instance().refreshScriptObjects(BansheeEditorAssemblyName);
+
+		mProgramEdClass = mEditorAssembly->getClass("BansheeEditor", "ProgramEd");
+		mUpdateMethod = &mProgramEdClass->getMethod("EditorUpdate");
+
+		mEditorAssembly->invoke(ASSEMBLY_ENTRY_POINT);
+		
+		// Initial update
+		mLastUpdateTime = gTime().getTime();
+		mUpdateMethod->invoke(nullptr, nullptr);
+	}
+
+	void EditorScriptManager::update()
+	{
+		float curTime = gTime().getTime();
+		float diff = curTime - mLastUpdateTime;
+
+		if (diff > EDITOR_UPDATE_RATE)
+		{
+			mUpdateMethod->invoke(nullptr, nullptr);
+
+			INT32 numUpdates = Math::floorToInt(diff / EDITOR_UPDATE_RATE);
+			mLastUpdateTime += numUpdates * EDITOR_UPDATE_RATE;
+		}
+	}
+}

+ 11 - 13
SBansheeEditor/Source/BsScriptEditorPlugin.cpp

@@ -1,8 +1,5 @@
 #include "BsScriptEditorPrerequisites.h"
-#include "BsScriptEditorWindow.h"
-#include "BsMonoManager.h"
-#include "BsMonoAssembly.h"
-#include "BsRuntimeScriptObjects.h"
+#include "BsEditorScriptManager.h"
 
 namespace BansheeEngine
 {
@@ -14,17 +11,18 @@ namespace BansheeEngine
 
 	extern "C" BS_SCR_BED_EXPORT void* loadPlugin()
 	{
-		const String ENGINE_ASSEMBLY_PATH = "..\\..\\Assemblies\\MBansheeEditor.dll";
-		const String ENGINE_ASSEMBLY_NAME = BansheeEditorAssemblyName;
-		const String ASSEMBLY_ENTRY_POINT = "ProgramEd::Main";
+		EditorScriptManager::startUp();
 
-		MonoAssembly& assembly = MonoManager::instance().loadAssembly(ENGINE_ASSEMBLY_PATH, ENGINE_ASSEMBLY_NAME);
-		ScriptEditorWindow::registerManagedEditorWindows();
-
-		RuntimeScriptObjects::instance().refreshScriptObjects(BansheeEditorAssemblyName);
+		return nullptr;
+	}
 
-		assembly.invoke(ASSEMBLY_ENTRY_POINT);
+	extern "C" BS_SCR_BED_EXPORT void updatePlugin()
+	{
+		EditorScriptManager::instance().update();
+	}
 
-		return nullptr;
+	extern "C" BS_SCR_BED_EXPORT void unloadPlugin()
+	{
+		EditorScriptManager::shutDown();
 	}
 }

+ 3 - 1
SBansheeEngine/Source/BsManagedSerializableArray.cpp

@@ -65,7 +65,7 @@ namespace BansheeEngine
 		}
 
 		void* params[2] = {
-			mono_type_get_object(MonoManager::instance().getDomain(), mono_class_get_type(typeInfo->getMonoClass())), lengthArray };
+			mono_type_get_object(MonoManager::instance().getDomain(), mono_class_get_type(typeInfo->mElementType->getMonoClass())), lengthArray };
 
 		return createInstance->invoke(nullptr, params);
 	}
@@ -142,6 +142,8 @@ namespace BansheeEngine
 		UINT32 numElems = (UINT32)mono_array_length(array);
 		assert(arrayIdx < numElems);
 	
+		UINT32 dbgSIze = mono_array_element_size(mono_object_get_class(mManagedInstance));
+
 		void* elemAddr = mono_array_addr_with_size(array, mElemSize, arrayIdx);
 		memcpy(elemAddr, val, mElemSize);
 	}

+ 2 - 11
SBansheeEngine/Source/BsScriptEnginePlugin.cpp

@@ -12,7 +12,7 @@
 
 namespace BansheeEngine
 {
-	void dbgTestComponentClone(MonoObject* instance)
+	void unitTest1_GameObjectClone(MonoObject* instance)
 	{
 		ScriptSceneObject* nativeInstance = ScriptSceneObject::toNative(instance);
 
@@ -22,14 +22,6 @@ namespace BansheeEngine
 		cloneSO->setParent(SO);
 	}
 
-	void reportDbgValue(int a, MonoString* b, int a2, MonoString* b2)
-	{
-		WString bStr = MonoUtil::monoToWString(b);
-		WString b2Str = MonoUtil::monoToWString(b2);
-
-		int end = 5;
-	}
-
 	extern "C" BS_SCR_BE_EXPORT const String& getPluginName()
 	{
 		static String pluginName = "SBansheeEngine";
@@ -45,8 +37,7 @@ namespace BansheeEngine
 		MonoAssembly& bansheeEngineAssembly = MonoManager::instance().loadAssembly(ENGINE_ASSEMBLY_PATH, ENGINE_ASSEMBLY_NAME);
 
 		// DEBUG ONLY
-		mono_add_internal_call("BansheeEngine.Program::dbgTestComponentClone", &dbgTestComponentClone);
-		mono_add_internal_call("BansheeEngine.Program::reportDbgValue", &reportDbgValue);
+		mono_add_internal_call("BansheeEngine.Program::UnitTest1_GameObjectClone", &unitTest1_GameObjectClone);
 
 		RuntimeScriptObjects::startUp();
 		ScriptResourceManager::startUp();