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

Fix for an issue causing a nullref when releasing a managed instance
Updated mono manager so that script assemblies get loaded in a separate domain which can be reloaded if needed
Changed how managed assembly "corlib" is loaded
Fixed a few issues with DX9 render system unloading
Fix for DockManager shutting down after the editor widget manager is shut down
Added Mono 3.4.0 compilation instructions

Marko Pintera 11 лет назад
Родитель
Сommit
ed1d293920

+ 3 - 2
BansheeCore/Source/BsCoreApplication.cpp

@@ -119,12 +119,10 @@ namespace BansheeEngine
 		unloadPlugin(mSceneManagerPlugin);
 		unloadPlugin(mSceneManagerPlugin);
 		
 		
 		RendererManager::shutDown();
 		RendererManager::shutDown();
-		RenderSystemManager::shutDown();
 		unloadPlugin(mRendererPlugin);
 		unloadPlugin(mRendererPlugin);
 
 
 		Input::shutDown();
 		Input::shutDown();
 
 
-		GpuProgramManager::shutDown();
 		Resources::shutDown();
 		Resources::shutDown();
 		GameObjectManager::shutDown();
 		GameObjectManager::shutDown();
 
 
@@ -133,6 +131,9 @@ namespace BansheeEngine
 		gCoreThread().update();
 		gCoreThread().update();
 		gCoreThread().submitAccessors(true);
 		gCoreThread().submitAccessors(true);
 
 
+		RenderSystemManager::shutDown();
+		GpuProgramManager::shutDown();
+
 		CoreObjectManager::shutDown(); // Must shut down before DynLibManager to ensure all objects are destroyed before unloading their libraries
 		CoreObjectManager::shutDown(); // Must shut down before DynLibManager to ensure all objects are destroyed before unloading their libraries
 		DynLibManager::shutDown();
 		DynLibManager::shutDown();
 		Time::shutDown();
 		Time::shutDown();

+ 0 - 2
BansheeD3D11RenderSystem/Source/BsD3D11Texture.cpp

@@ -54,8 +54,6 @@ namespace BansheeEngine
 		SAFE_RELEASE(m3DTex);
 		SAFE_RELEASE(m3DTex);
 		SAFE_RELEASE(mStagingBuffer);
 		SAFE_RELEASE(mStagingBuffer);
 
 
-		clearBufferViews();
-
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_Texture);
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_Texture);
 		Texture::destroy_internal();
 		Texture::destroy_internal();
 	}
 	}

+ 0 - 2
BansheeD3D9RenderSystem/Source/BsD3D9Texture.cpp

@@ -61,8 +61,6 @@ namespace BansheeEngine
 		mMapDeviceToTextureResources.clear();
 		mMapDeviceToTextureResources.clear();
 		mSurfaceList.clear();
 		mSurfaceList.clear();
 
 
-		clearBufferViews();
-
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_Texture);
 		BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_Texture);
 		Texture::destroy_internal();
 		Texture::destroy_internal();
 	}
 	}

+ 2 - 0
BansheeEditor/Include/BsDockManager.h

@@ -91,6 +91,8 @@ namespace BansheeEngine
 
 
 		void setArea(INT32 x, INT32 y, UINT32 width, UINT32 height);
 		void setArea(INT32 x, INT32 y, UINT32 width, UINT32 height);
 
 
+		void closeAll();
+
 	protected:
 	protected:
 		~DockManager();
 		~DockManager();
 
 

+ 6 - 0
BansheeEditor/Source/BsDockManager.cpp

@@ -495,6 +495,12 @@ namespace BansheeEngine
 		updateDropOverlay(x, y, width, height);
 		updateDropOverlay(x, y, width, height);
 	}
 	}
 
 
+	void DockManager::closeAll()
+	{
+		mRootContainer = DockContainer();
+		mMouseOverContainer = nullptr;
+	}
+
 	DockManagerLayoutPtr DockManager::getLayout() const
 	DockManagerLayoutPtr DockManager::getLayout() const
 	{
 	{
 		struct StackElem
 		struct StackElem

+ 1 - 0
BansheeEditor/Source/BsMainEditorWindow.cpp

@@ -88,6 +88,7 @@ namespace BansheeEngine
 
 
 	MainEditorWindow::~MainEditorWindow()
 	MainEditorWindow::~MainEditorWindow()
 	{
 	{
+		mDockManager->closeAll();
 		GUIElement::destroy(mDockManager);
 		GUIElement::destroy(mDockManager);
 		bs_delete(mMenuBar);
 		bs_delete(mMenuBar);
 	}
 	}

+ 2 - 1
BansheeEngine.sln

@@ -180,7 +180,8 @@ EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Guides", "Guides", "{4259680D-8A9B-4C17-B75B-CA29482AB299}"
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Guides", "Guides", "{4259680D-8A9B-4C17-B75B-CA29482AB299}"
 	ProjectSection(SolutionItems) = preProject
 	ProjectSection(SolutionItems) = preProject
 		Dependencies.txt = Dependencies.txt
 		Dependencies.txt = Dependencies.txt
-		MonoIntegrationGuide.txt = MonoIntegrationGuide.txt
+		Mono-3.2.3-IntegrationGuide.txt = Mono-3.2.3-IntegrationGuide.txt
+		Mono-3.4.0-IntegrationGuide.txt = Mono-3.4.0-IntegrationGuide.txt
 	EndProjectSection
 	EndProjectSection
 EndProject
 EndProject
 Global
 Global

+ 5 - 2
BansheeMono/Include/BsMonoAssembly.h

@@ -69,12 +69,15 @@ namespace BansheeEngine
 		/**
 		/**
 		 * @brief	Loads an assembly from the specified path.
 		 * @brief	Loads an assembly from the specified path.
 		 */
 		 */
-		void load(const String& path, const String& name);
+		void load(MonoDomain* domain, const String& path, const String& name);
 
 
 		/**
 		/**
 		 * @brief	Loads an assembly from an internal mono image.
 		 * @brief	Loads an assembly from an internal mono image.
+		 *
+		 * @note	Normally used for assemblies that were already loaded by the managed runtime
+		 *			as dependencies.
 		 */
 		 */
-		void loadAsDependency(MonoImage* image, const String& name);
+		void loadFromImage(MonoImage* image, const String& name);
 
 
 		/**
 		/**
 		 * @brief	Unloads the assembly and all the types associated with it.
 		 * @brief	Unloads the assembly and all the types associated with it.

+ 3 - 2
BansheeMono/Include/BsMonoManager.h

@@ -65,7 +65,7 @@ namespace BansheeEngine
 		/**
 		/**
 		 * @brief	Returns the current Mono domains.
 		 * @brief	Returns the current Mono domains.
 		 */
 		 */
-		MonoDomain* getDomain() const { return mDomain; }
+		MonoDomain* getDomain() const { return mScriptDomain; }
 
 
 		/**
 		/**
 		 * @brief	Attempts to find a previously loaded assembly with the specified name.
 		 * @brief	Attempts to find a previously loaded assembly with the specified name.
@@ -93,7 +93,8 @@ namespace BansheeEngine
 		}
 		}
 
 
 		UnorderedMap<String, MonoAssembly*> mAssemblies;
 		UnorderedMap<String, MonoAssembly*> mAssemblies;
-		MonoDomain* mDomain;
+		MonoDomain* mScriptDomain;
+		MonoDomain* mRootDomain;
 		bool mIsCoreLoaded;
 		bool mIsCoreLoaded;
 	};
 	};
 }
 }

+ 5 - 5
BansheeMono/Source/BsMonoAssembly.cpp

@@ -44,9 +44,9 @@ namespace BansheeEngine
 		unload();
 		unload();
 	}
 	}
 
 
-	void MonoAssembly::load(const String& path, const String& name)
+	void MonoAssembly::load(MonoDomain* domain, const String& path, const String& name)
 	{
 	{
-		::MonoAssembly* monoAssembly = mono_domain_assembly_open (MonoManager::instance().getDomain(), path.c_str());
+		::MonoAssembly* monoAssembly = mono_domain_assembly_open(domain, path.c_str());
 		if(monoAssembly == nullptr)
 		if(monoAssembly == nullptr)
 		{
 		{
 			BS_EXCEPT(InvalidParametersException, "Cannot load Mono assembly: " + path);
 			BS_EXCEPT(InvalidParametersException, "Cannot load Mono assembly: " + path);
@@ -64,7 +64,7 @@ namespace BansheeEngine
 		mIsDependency = false;
 		mIsDependency = false;
 	}
 	}
 
 
-	void MonoAssembly::loadAsDependency(MonoImage* image, const String& name)
+	void MonoAssembly::loadFromImage(MonoImage* image, const String& name)
 	{
 	{
 		::MonoAssembly* monoAssembly = mono_image_get_assembly(image);
 		::MonoAssembly* monoAssembly = mono_image_get_assembly(image);
 		if(monoAssembly == nullptr)
 		if(monoAssembly == nullptr)
@@ -93,8 +93,8 @@ namespace BansheeEngine
 
 
 		if(mMonoImage != nullptr && !mIsDependency)
 		if(mMonoImage != nullptr && !mIsDependency)
 		{
 		{
-			//mono_image_close(mMonoImage); // This seems to cause a crash but unloading just the assembly /seems/ to work
-			mono_assembly_close(mMonoAssembly);
+			// Note: I used to call mono_image_close and mono_assembly_close here but those 
+			// didn't seem to be necessary and were just crashing the program.
 			mMonoImage = nullptr;
 			mMonoImage = nullptr;
 		}
 		}
 
 

+ 35 - 30
BansheeMono/Source/BsMonoManager.cpp

@@ -3,6 +3,7 @@
 #include "BsScriptMeta.h"
 #include "BsScriptMeta.h"
 #include "BsMonoAssembly.h"
 #include "BsMonoAssembly.h"
 #include "BsMonoClass.h"
 #include "BsMonoClass.h"
+#include "BsMonoUtil.h"
 
 
 #include <mono/metadata/assembly.h>
 #include <mono/metadata/assembly.h>
 #include <mono/metadata/mono-config.h>
 #include <mono/metadata/mono-config.h>
@@ -14,48 +15,58 @@ namespace BansheeEngine
 	const String MonoManager::MONO_ETC_DIR = "..\\..\\Mono\\etc";
 	const String MonoManager::MONO_ETC_DIR = "..\\..\\Mono\\etc";
 
 
 	MonoManager::MonoManager()
 	MonoManager::MonoManager()
-		:mDomain(nullptr), mIsCoreLoaded(false)
+		:mRootDomain(nullptr), mScriptDomain(nullptr), mIsCoreLoaded(false)
 	{
 	{
 		mono_set_dirs(MONO_LIB_DIR.c_str(), MONO_ETC_DIR.c_str()); 
 		mono_set_dirs(MONO_LIB_DIR.c_str(), MONO_ETC_DIR.c_str()); 
 		mono_config_parse(nullptr);
 		mono_config_parse(nullptr);
+
+		mRootDomain = mono_jit_init_version("BansheeMono", "v4.0.30319"); // TODO: Allow user-defined version here?
+		if (mRootDomain == nullptr)
+			BS_EXCEPT(InternalErrorException, "Cannot initialize Mono runtime.");
 	}
 	}
 
 
 	MonoManager::~MonoManager()
 	MonoManager::~MonoManager()
 	{
 	{
-		if (mDomain != nullptr)
+		for (auto& entry : mAssemblies)
+		{
+			bs_delete(entry.second);
+		}
+
+		mAssemblies.clear();
+
+		if (mScriptDomain != nullptr)
 		{
 		{
-			// TODO - Someone suggested I need to GC collect and wait for finalizers before cleanup
-			// I don't see how that would help unless I manually release all references before that as well
-			// BUT that is a good way to debug those errors on exit
+			mono_domain_set(mono_get_root_domain(), false);
+			mono_domain_finalize(mScriptDomain, 2000);
+			
+			MonoObject* exception = nullptr;
+			mono_domain_try_unload(mScriptDomain, &exception);
 
 
-			// TODO: This might not be necessary
-			//mono_gc_collect(mono_gc_max_generation());
-			//mono_domain_finalize(mDomain, -1);
+			if (exception != nullptr)
+				MonoUtil::throwIfException(exception);
 
 
-			// TODO: Commented out because it crashes for no reason
-			mono_jit_cleanup(mDomain);
-			mDomain = nullptr;
+			mScriptDomain = nullptr;
 		}
 		}
 
 
-		for (auto& entry : mAssemblies)
+		if (mRootDomain != nullptr)
 		{
 		{
-			//unloadAssembly(*entry.second);
-			//bs_delete(entry.second);
+			mono_jit_cleanup(mRootDomain);
+			mRootDomain = nullptr;
 		}
 		}
-
-		mAssemblies.clear();
 	}
 	}
 
 
 	MonoAssembly& MonoManager::loadAssembly(const String& path, const String& name)
 	MonoAssembly& MonoManager::loadAssembly(const String& path, const String& name)
 	{
 	{
 		MonoAssembly* assembly = nullptr;
 		MonoAssembly* assembly = nullptr;
 
 
-		if(mDomain == nullptr)
+		if (mScriptDomain == nullptr)
 		{
 		{
-			mDomain = mono_jit_init (path.c_str());
-			if(mDomain == nullptr)
+			mScriptDomain = mono_domain_create_appdomain(const_cast<char *>(path.c_str()), nullptr);
+			mono_domain_set(mScriptDomain, false);
+
+			if (mScriptDomain == nullptr)
 			{
 			{
-				BS_EXCEPT(InternalErrorException, "Cannot initialize Mono runtime.");
+				BS_EXCEPT(InternalErrorException, "Cannot create script app domain.");
 			}
 			}
 		}
 		}
 
 
@@ -72,7 +83,7 @@ namespace BansheeEngine
 		
 		
 		if(!assembly->mIsLoaded)
 		if(!assembly->mIsLoaded)
 		{
 		{
-			assembly->load(path, name);
+			assembly->load(mScriptDomain, path, name);
 
 
 			// Fully initialize all types that use this assembly
 			// Fully initialize all types that use this assembly
 			Vector<ScriptMeta*>& mTypeMetas = getTypesToInitialize()[name];
 			Vector<ScriptMeta*>& mTypeMetas = getTypesToInitialize()[name];
@@ -95,16 +106,10 @@ namespace BansheeEngine
 		{
 		{
 			mIsCoreLoaded = true;
 			mIsCoreLoaded = true;
 
 
-			MonoImage* existingImage = mono_image_loaded("mscorlib");
-			if(existingImage != nullptr)
-			{
-				MonoAssembly* mscorlib = new (bs_alloc<MonoAssembly>()) MonoAssembly();
-				mAssemblies["mscorlib"] = mscorlib;
+			MonoAssembly* corlib = new (bs_alloc<MonoAssembly>()) MonoAssembly();
+			mAssemblies["corlib"] = corlib;
 
 
-				mscorlib->loadAsDependency(existingImage, "mscorlib");
-			}
-			else
-				loadAssembly("mscorlib", "mscorlib");			
+			corlib->loadFromImage(mono_get_corlib(), "corlib");		
 		}
 		}
 
 
 		return *assembly;
 		return *assembly;

+ 2 - 0
MBansheeEngine/Program.cs

@@ -87,6 +87,8 @@ namespace BansheeEngine
 
 
             UnitTest1_GameObjectClone(so);
             UnitTest1_GameObjectClone(so);
 
 
+            System.Diagnostics.Debug.Assert(so.GetNumChildren() == 1);
+
             for (int i = 0; i < so.GetNumChildren(); i++)
             for (int i = 0; i < so.GetNumChildren(); i++)
             {
             {
                 SceneObject childSO = so.GetChild(i);
                 SceneObject childSO = so.GetChild(i);

+ 118 - 118
MonoIntegrationGuide.txt → Mono-3.2.3-IntegrationGuide.txt

@@ -1,119 +1,119 @@
-Download mono 3.2.3 source from http://download.mono-project.com/sources/.
-
-Mono can be a bit problematic to compile on Windows as MSVC solution is not maintained very often. 
-Cygwin option that is provided doesn't come with a 64bit configuration, plus it also has errors.
-
---------------------------------------Compiling with Visual Studio 2012 on Windows 7 x64--------------------------------------------------
- - 3.2.3 version is missing "mono.props" file and without it Visual Studio will fail to open some project files. To fix download the .props file 
-   from https://raw.github.com/mono/mono/master/msvc/mono.props and put it in mono-3.2.3\msvc folder before opening any projects or solution
- - Even though solution is VS2010, it will only compile with VS2012 unless you change platform toolkit to 
-   v10 for all projects. (Haven't actually tested with VS2010)
- - If compiler complains it cannot find pthreads.h make sure to define "HAS_64BITS_ATOMIC" in libmonoutils project (for all configurations)
- - In dlmalloc.c change #include <dlmalloc.h> to #include "dlmalloc.h" if compiler complains it cannot find that file
- - In "mono-proclib.c" add this bit of code somewhere near the start of the file:
-
-#ifdef HOST_WIN32
-#define strtoll _strtoi64
-#define strtoull _strtoui64
-#endif
-
-  - In "threads.c" replace a line in ves_icall_System_Threading_Interlocked_CompareExchange_Long method, from:
-
-return InterlockedCompareExchange64 (location, value, comparand);
-
-    to
-
-#ifdef HOST_WIN32
-	return _InterlockedCompareExchange64 (location, value, comparand);
-#else
-	return InterlockedCompareExchange64 (location, value, comparand); 
-#endif
-
-    InterlockedCompareExchange64 is just a typedef for _InterlockedCompareExchange64 on Windows and for some
-	reason compiler doesn't realize it (typedefs to intrinstics don't work?). Anyway, so we just reference the intrinsic
-	directly.
-
-  - In "threads.c" replace a line in ves_icall_System_Threading_Thread_VolatileRead8 method, from:
-
-return InterlockedCompareExchange64 (ptr, 0, 0);
-     
-	to
-
-#ifdef HOST_WIN32
-	return _InterlockedCompareExchange64 (ptr, 0, 0);
-#else
-	return InterlockedCompareExchange64 (ptr, 0, 0);    
-#endif
-
-    Same problem as previous.
-
-  - For all projects and configurations update their property pages under "C/C++->Optimization" and set "Enable Intrinsic Functions" to "Yes"
-    - You might be able to skip this step.
-  - In "exceptions-amd64.c" replace line 121:
-
-if (win32_chained_exception_needs_run) { 
-    
-   with
-
-if (mono_win_chained_exception_needs_run) {
-
-  - In "exceptions-amd64.c" delete lines 167 and 168:
-
-if (old_win32_toplevel_exception_filter)
-	SetUnhandledExceptionFilter(mono_old_win_toplevel_exception_filter);
-
-  - In "exceptions-amd64.c" move line 166 (line # after previous changes) to start of the function:
-
-guint32 ret = 0;
-
-  - in threads.c in mono_thread_get_stack_bounds method replace the bit of code under "#if defined(HOST_WIN32)" from:
-
-void* tib = (void*)__readfsdword(0x18);
-guint8 *stackTop = (guint8*)*(int*)((char*)tib + 4);
-guint8 *stackBottom = (guint8*)*(int*)((char*)tib + 8);
-
-    to:
-
-NT_TIB* tib = (NT_TIB*)NtCurrentTeb();
-guint8 *stackTop = (guint8*)tib->StackBase;
-guint8 *stackBottom = (guint8*)tib->StackLimit;
-
-    __readfsdword doesn't exist when building 64bit. Use may use __readgsqword instead but then you need
-	to double all your offsets. NtCurrentTeb works equally for both 32 and 64 bit builds.
-
-  - Build "mono" project. 
-  - You should end up with mono-2.0.dll, mono-2.0.lib, MonoPosixHelper.dll and mono.exe and we are done compiling
-
---------------------------------------VS2013 specific changes--------------------------------------------
-
-If compiling for VS2013 you will also need to perform these modifications:
- - Edit libmonoruntime project file and remove item "..\mono\metadata\sgen-bridge.c" as it is duplicate 
-  (just search for it and you'll see two copies). If you dont VS2013 will fail to load that project.
-
- - In mono_compiler.h at line 192 rename "trunc" macro to "mono_trunc" and all its references too.
-   - (Should just be 4 references in jit-icalls.c at lines 888, 891, 904, 932.)
-   - This is needed because standard math.h now contains a trunc method which conflicts with the macro
-
--------------------------------Special Banshee-specific changes--------------------------------------------
-
-Move & modify:
-  MonoClass* mono_class_bind_generic_parameters (MonoClass *klass, int type_argc, MonoType **types, gboolean is_dynamic) MONO_INTERNAL; 
-from object-internals.h
-to:
-  MONO_API MonoClass* mono_class_bind_generic_parameters (MonoClass *klass, int type_argc, MonoType **types, mono_bool is_dynamic);
-in object.h
-
-In reflection.c change:
-  MonoClass* mono_class_bind_generic_parameters (MonoClass *klass, int type_argc, MonoType **types, gboolean is_dynamic)
-to:
-  MonoClass* mono_class_bind_generic_parameters (MonoClass *klass, int type_argc, MonoType **types, mono_bool is_dynamic)
-
-
---------------------------------Integrating Mono into Banshee----------------------------------------------
- - Add mono-2.0.dll to (BansheeRootDir)/bin/(Platform)/(Configuration)
- - Add mono-2.0.lib to (BansheeRootDir)/Dependencies/lib/(Platform)/(Configuration)
- - Install mono 3.2.3 prebuilt binaries
-   - Copy contents of (PrebuiltMonoFolder)/include/mono/mono-2.0/mono to (BansheeRootDir)/Dependencies/Include/Mono
-   - Copy folders (PrebuiltMonoFolder)/etc and (PrebuiltMonoFolder)/lib folders into (BansheeRootDir)/bin/Mono
-     - TODO - Not all files from /lib are needed, but I haven't yet determined which are
+Download mono 3.2.3 source from http://download.mono-project.com/sources/.
+
+Mono can be a bit problematic to compile on Windows as MSVC solution is not maintained very often. 
+Cygwin option that is provided doesn't come with a 64bit configuration, plus it also has errors.
+
+--------------------------------------Compiling with Visual Studio 2012 on Windows 7 x64--------------------------------------------------
+ - 3.2.3 version is missing "mono.props" file and without it Visual Studio will fail to open some project files. To fix download the .props file 
+   from https://raw.github.com/mono/mono/master/msvc/mono.props and put it in mono-3.2.3\msvc folder before opening any projects or solution
+ - Even though solution is VS2010, it will only compile with VS2012 unless you change platform toolkit to 
+   v10 for all projects. (Haven't actually tested with VS2010)
+ - If compiler complains it cannot find pthreads.h make sure to define "HAS_64BITS_ATOMIC" in libmonoutils project (for all configurations)
+ - In dlmalloc.c change #include <dlmalloc.h> to #include "dlmalloc.h" if compiler complains it cannot find that file
+ - In "mono-proclib.c" add this bit of code somewhere near the start of the file:
+
+#ifdef HOST_WIN32
+#define strtoll _strtoi64
+#define strtoull _strtoui64
+#endif
+
+  - In "threads.c" replace a line in ves_icall_System_Threading_Interlocked_CompareExchange_Long method, from:
+
+return InterlockedCompareExchange64 (location, value, comparand);
+
+    to
+
+#ifdef HOST_WIN32
+	return _InterlockedCompareExchange64 (location, value, comparand);
+#else
+	return InterlockedCompareExchange64 (location, value, comparand); 
+#endif
+
+    InterlockedCompareExchange64 is just a typedef for _InterlockedCompareExchange64 on Windows and for some
+	reason compiler doesn't realize it (typedefs to intrinstics don't work?). Anyway, so we just reference the intrinsic
+	directly.
+
+  - In "threads.c" replace a line in ves_icall_System_Threading_Thread_VolatileRead8 method, from:
+
+return InterlockedCompareExchange64 (ptr, 0, 0);
+     
+	to
+
+#ifdef HOST_WIN32
+	return _InterlockedCompareExchange64 (ptr, 0, 0);
+#else
+	return InterlockedCompareExchange64 (ptr, 0, 0);    
+#endif
+
+    Same problem as previous.
+
+  - For all projects and configurations update their property pages under "C/C++->Optimization" and set "Enable Intrinsic Functions" to "Yes"
+    - You might be able to skip this step.
+  - In "exceptions-amd64.c" replace line 121:
+
+if (win32_chained_exception_needs_run) { 
+    
+   with
+
+if (mono_win_chained_exception_needs_run) {
+
+  - In "exceptions-amd64.c" delete lines 167 and 168:
+
+if (old_win32_toplevel_exception_filter)
+	SetUnhandledExceptionFilter(mono_old_win_toplevel_exception_filter);
+
+  - In "exceptions-amd64.c" move line 166 (line # after previous changes) to start of the function:
+
+guint32 ret = 0;
+
+  - in threads.c in mono_thread_get_stack_bounds method replace the bit of code under "#if defined(HOST_WIN32)" from:
+
+void* tib = (void*)__readfsdword(0x18);
+guint8 *stackTop = (guint8*)*(int*)((char*)tib + 4);
+guint8 *stackBottom = (guint8*)*(int*)((char*)tib + 8);
+
+    to:
+
+NT_TIB* tib = (NT_TIB*)NtCurrentTeb();
+guint8 *stackTop = (guint8*)tib->StackBase;
+guint8 *stackBottom = (guint8*)tib->StackLimit;
+
+    __readfsdword doesn't exist when building 64bit. Use may use __readgsqword instead but then you need
+	to double all your offsets. NtCurrentTeb works equally for both 32 and 64 bit builds.
+
+  - Build "mono" project. 
+  - You should end up with mono-2.0.dll, mono-2.0.lib, MonoPosixHelper.dll and mono.exe and we are done compiling
+
+--------------------------------------VS2013 specific changes--------------------------------------------
+
+If compiling for VS2013 you will also need to perform these modifications:
+ - Edit libmonoruntime project file and remove item "..\mono\metadata\sgen-bridge.c" as it is duplicate 
+  (just search for it and you'll see two copies). If you dont VS2013 will fail to load that project.
+
+ - In mono_compiler.h at line 192 rename "trunc" macro to "mono_trunc" and all its references too.
+   - (Should just be 4 references in jit-icalls.c at lines 888, 891, 904, 932.)
+   - This is needed because standard math.h now contains a trunc method which conflicts with the macro
+
+-------------------------------Special Banshee-specific changes--------------------------------------------
+
+Move & modify:
+  MonoClass* mono_class_bind_generic_parameters (MonoClass *klass, int type_argc, MonoType **types, gboolean is_dynamic) MONO_INTERNAL; 
+from object-internals.h
+to:
+  MONO_API MonoClass* mono_class_bind_generic_parameters (MonoClass *klass, int type_argc, MonoType **types, mono_bool is_dynamic);
+in object.h
+
+In reflection.c change:
+  MonoClass* mono_class_bind_generic_parameters (MonoClass *klass, int type_argc, MonoType **types, gboolean is_dynamic)
+to:
+  MonoClass* mono_class_bind_generic_parameters (MonoClass *klass, int type_argc, MonoType **types, mono_bool is_dynamic)
+
+
+--------------------------------Integrating Mono into Banshee----------------------------------------------
+ - Add mono-2.0.dll to (BansheeRootDir)/bin/(Platform)/(Configuration)
+ - Add mono-2.0.lib to (BansheeRootDir)/Dependencies/lib/(Platform)/(Configuration)
+ - Install mono 3.2.3 prebuilt binaries
+   - Copy contents of (PrebuiltMonoFolder)/include/mono/mono-2.0/mono to (BansheeRootDir)/Dependencies/Include/Mono
+   - Copy folders (PrebuiltMonoFolder)/etc and (PrebuiltMonoFolder)/lib folders into (BansheeRootDir)/bin/Mono
+     - TODO - Not all files from /lib are needed, but I haven't yet determined which are
  - TODO - mono.exe and mono compiler are not used at the moment. Update docs once they are.
  - TODO - mono.exe and mono compiler are not used at the moment. Update docs once they are.

+ 7 - 0
Mono-3.4.0-IntegrationGuide.txt

@@ -0,0 +1,7 @@
+Download Mono 3.4.0 source from http://download.mono-project.com/sources/.
+Extract and open mono-3.4.0 folder.
+Open /msvc/mono.sln with Visual Studio 2013 and upgrade all projects to VS 2013 when asked
+In root folder rename "winconfig.h" to "config.h"
+Add /mono/mini/mini-native-types.c to "libmono" VS project
+Compile libmono as Debug or Release (not the SGen version as those might require some extra fixes), Win32 or x64
+When compiling x64 also remove "mono_debugger_agent_register_transport" method from /msvc/mono.def (and restore if building Win32)

+ 19 - 0
SBansheeEngine/Include/BsManagedComponentRTTI.h

@@ -7,6 +7,7 @@
 #include "BsMonoManager.h"
 #include "BsMonoManager.h"
 #include "BsManagedSerializableObject.h"
 #include "BsManagedSerializableObject.h"
 #include "BsGameObjectManager.h"
 #include "BsGameObjectManager.h"
+#include "BsScriptGameObjectManager.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
@@ -73,7 +74,25 @@ namespace BansheeEngine
 			MonoType* monoType = mono_class_get_type(monoClass);
 			MonoType* monoType = mono_class_get_type(monoClass);
 			MonoReflectionType* runtimeType = mono_type_get_object(MonoManager::instance().getDomain(), monoType);
 			MonoReflectionType* runtimeType = mono_type_get_object(MonoManager::instance().getDomain(), monoType);
 
 
+			// Find handle so we can create a script component
+			HManagedComponent componentHandle;
+			if (mc->mParent != nullptr)
+			{
+				const Vector<HComponent>& components = mc->mParent->getComponents();
+				for (auto& component : components)
+				{
+					if (component.get() == mc)
+					{
+						componentHandle = component;
+						break;
+					}
+				}
+			}
+
+			assert(componentHandle != nullptr); // It must exist as every component belongs to its parent SO
+
 			mc->construct(serializableObject->getManagedInstance(), runtimeType);
 			mc->construct(serializableObject->getManagedInstance(), runtimeType);
+			ScriptComponent* nativeInstance = ScriptGameObjectManager::instance().createScriptComponent(componentHandle);
 		}
 		}
 
 
 		virtual const String& getRTTIName()
 		virtual const String& getRTTIName()

+ 6 - 6
SBansheeEngine/Source/BsRuntimeScriptObjects.cpp

@@ -376,23 +376,23 @@ namespace BansheeEngine
 	void RuntimeScriptObjects::initializeBaseTypes()
 	void RuntimeScriptObjects::initializeBaseTypes()
 	{
 	{
 		// Get necessary classes for detecting needed class & field information
 		// Get necessary classes for detecting needed class & field information
-		MonoAssembly* mscorlib = MonoManager::instance().getAssembly("mscorlib");
-		if(mscorlib == nullptr)
-			BS_EXCEPT(InvalidStateException, "mscorlib assembly is not loaded.");
+		MonoAssembly* corlib = MonoManager::instance().getAssembly("corlib");
+		if(corlib == nullptr)
+			BS_EXCEPT(InvalidStateException, "corlib assembly is not loaded.");
 
 
 		MonoAssembly* bansheeEngineAssembly = MonoManager::instance().getAssembly(BansheeEngineAssemblyName);
 		MonoAssembly* bansheeEngineAssembly = MonoManager::instance().getAssembly(BansheeEngineAssemblyName);
 		if(bansheeEngineAssembly == nullptr)
 		if(bansheeEngineAssembly == nullptr)
 			BS_EXCEPT(InvalidStateException, String(BansheeEngineAssemblyName) +  " assembly is not loaded.");
 			BS_EXCEPT(InvalidStateException, String(BansheeEngineAssemblyName) +  " assembly is not loaded.");
 
 
-		mSystemArrayClass = mscorlib->getClass("System", "Array");
+		mSystemArrayClass = corlib->getClass("System", "Array");
 		if(mSystemArrayClass == nullptr)
 		if(mSystemArrayClass == nullptr)
 			BS_EXCEPT(InvalidStateException, "Cannot find System.Array managed class.");
 			BS_EXCEPT(InvalidStateException, "Cannot find System.Array managed class.");
 
 
-		mSystemGenericListClass = mscorlib->getClass("System.Collections.Generic", "List`1");
+		mSystemGenericListClass = corlib->getClass("System.Collections.Generic", "List`1");
 		if(mSystemGenericListClass == nullptr)
 		if(mSystemGenericListClass == nullptr)
 			BS_EXCEPT(InvalidStateException, "Cannot find List<T> managed class.");
 			BS_EXCEPT(InvalidStateException, "Cannot find List<T> managed class.");
 
 
-		mSystemGenericDictionaryClass = mscorlib->getClass("System.Collections.Generic", "Dictionary`2");
+		mSystemGenericDictionaryClass = corlib->getClass("System.Collections.Generic", "Dictionary`2");
 		if(mSystemGenericDictionaryClass == nullptr)
 		if(mSystemGenericDictionaryClass == nullptr)
 			BS_EXCEPT(InvalidStateException, "Cannot find Dictionary<TKey, TValue> managed class.");
 			BS_EXCEPT(InvalidStateException, "Cannot find Dictionary<TKey, TValue> managed class.");