Browse Source

Clear prefab diffs when saving prefabs for build
Component Update -> OnUpdate to match naming of other callbacks
Prevent compilation while the game is playing
Copy Game executable to Data folder when building

BearishSun 10 years ago
parent
commit
22028f04e4

+ 1 - 0
.gitignore

@@ -9,4 +9,5 @@ lib
 data
 data
 Intermediate
 Intermediate
 Dependencies
 Dependencies
+Builds
 *.aps
 *.aps

+ 8 - 0
BansheeCore/Include/BsSceneObject.h

@@ -92,6 +92,14 @@ namespace BansheeEngine
 		 * @brief	Checks if the scene object has a specific bit flag set.
 		 * @brief	Checks if the scene object has a specific bit flag set.
 		 */
 		 */
 		bool hasFlag(UINT32 flag) const;
 		bool hasFlag(UINT32 flag) const;
+
+		/**
+		 * @brief	Clears the internally stored prefab diff. If this object is updated from prefab its instance specific
+		 * 			changes will be lost.
+		 * 			
+		 * @note	Internal method.
+		 */
+		void _clearPrefabDiff() { mPrefabDiff = nullptr; }
 	private:
 	private:
 		SceneObject(const String& name, UINT32 flags);
 		SceneObject(const String& name, UINT32 flags);
 
 

+ 1 - 0
BansheeEngine.sln

@@ -61,6 +61,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BansheeEditorExec", "Banshe
 		{CC7F9445-71C9-4559-9976-FF0A64DCB582} = {CC7F9445-71C9-4559-9976-FF0A64DCB582}
 		{CC7F9445-71C9-4559-9976-FF0A64DCB582} = {CC7F9445-71C9-4559-9976-FF0A64DCB582}
 		{2DA6824A-4D3A-4B59-8AE9-85D3C14074A3} = {2DA6824A-4D3A-4B59-8AE9-85D3C14074A3}
 		{2DA6824A-4D3A-4B59-8AE9-85D3C14074A3} = {2DA6824A-4D3A-4B59-8AE9-85D3C14074A3}
 		{1437BB4E-DDB3-4307-AA41-8C035DA3014B} = {1437BB4E-DDB3-4307-AA41-8C035DA3014B}
 		{1437BB4E-DDB3-4307-AA41-8C035DA3014B} = {1437BB4E-DDB3-4307-AA41-8C035DA3014B}
+		{B280B769-1BA4-42AF-8263-D644A67B4473} = {B280B769-1BA4-42AF-8263-D644A67B4473}
 		{F58FF869-2EA6-4FFF-AB84-328C531BA9D9} = {F58FF869-2EA6-4FFF-AB84-328C531BA9D9}
 		{F58FF869-2EA6-4FFF-AB84-328C531BA9D9} = {F58FF869-2EA6-4FFF-AB84-328C531BA9D9}
 		{08975177-4A13-4EE7-BB21-3BB92FB3F3CC} = {08975177-4A13-4EE7-BB21-3BB92FB3F3CC}
 		{08975177-4A13-4EE7-BB21-3BB92FB3F3CC} = {08975177-4A13-4EE7-BB21-3BB92FB3F3CC}
 		{AB6C9284-D1CB-4AAD-BA4B-8A9E81AD1A73} = {AB6C9284-D1CB-4AAD-BA4B-8A9E81AD1A73}
 		{AB6C9284-D1CB-4AAD-BA4B-8A9E81AD1A73} = {AB6C9284-D1CB-4AAD-BA4B-8A9E81AD1A73}

+ 0 - 1
BansheeUtility/Include/BsTypes.h

@@ -13,7 +13,6 @@ namespace BansheeEngine
 	typedef unsigned short UINT16;
 	typedef unsigned short UINT16;
 	typedef int INT32;
 	typedef int INT32;
 	typedef unsigned int UINT32;
 	typedef unsigned int UINT32;
-	typedef unsigned short WCHAR;
 
 
 #if BS_COMPILER == BS_COMPILER_MSVC
 #if BS_COMPILER == BS_COMPILER_MSVC
 	typedef unsigned __int64 UINT64;
 	typedef unsigned __int64 UINT64;

+ 6 - 0
Game/Game.vcxproj

@@ -161,6 +161,9 @@
       <AdditionalLibraryDirectories>..\lib\x64\$(Configuration);..\Dependencies\lib\x64\Debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <AdditionalLibraryDirectories>..\lib\x64\$(Configuration);..\Dependencies\lib\x64\Debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <AdditionalDependencies>BansheeCore.lib;BansheeUtility.lib;BansheeEngine.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalDependencies>BansheeCore.lib;BansheeUtility.lib;BansheeEngine.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
     </Link>
+    <PostBuildEvent>
+      <Command>xcopy /Y /I "$(TargetDir)$(TargetName).exe" "$(SolutionDir)Data\Binaries\Win64\"</Command>
+    </PostBuildEvent>
   </ItemDefinitionGroup>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
     <ClCompile>
@@ -256,6 +259,9 @@
       <AdditionalLibraryDirectories>..\lib\x64\$(Configuration);..\Dependencies\lib\x64\DebugRelease;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <AdditionalLibraryDirectories>..\lib\x64\$(Configuration);..\Dependencies\lib\x64\DebugRelease;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <AdditionalDependencies>BansheeCore.lib;BansheeUtility.lib;BansheeEngine.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalDependencies>BansheeCore.lib;BansheeUtility.lib;BansheeEngine.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
     </Link>
+    <PostBuildEvent>
+      <Command>copy /Y "$(TargetDir)$(TargetName).dll" "$(SolutionDir)Data\Binaries\Win64\$(TargetName).dll"</Command>
+    </PostBuildEvent>
   </ItemDefinitionGroup>
   </ItemDefinitionGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\Main.cpp" />
     <ClCompile Include="Source\Main.cpp" />

+ 32 - 28
Game/Source/Main.cpp

@@ -10,6 +10,37 @@
 #include "BsSceneObject.h"
 #include "BsSceneObject.h"
 #include "BsSceneManager.h"
 #include "BsSceneManager.h"
 
 
+void runApplication();
+
+#if BS_PLATFORM == BS_PLATFORM_WIN32
+#include <windows.h>
+
+using namespace BansheeEngine;
+
+int CALLBACK WinMain(
+	_In_  HINSTANCE hInstance,
+	_In_  HINSTANCE hPrevInstance,
+	_In_  LPSTR lpCmdLine,
+	_In_  int nCmdShow
+	)
+{
+	CrashHandler::startUp();
+
+	__try
+	{
+		runApplication();
+	}
+	__except (gCrashHandler().reportCrash(GetExceptionInformation()))
+	{
+		PlatformUtility::terminate(true);
+	}
+
+	CrashHandler::shutDown();
+
+	return 0;
+}
+#endif // End BS_PLATFORM
+
 using namespace BansheeEngine;
 using namespace BansheeEngine;
 
 
 void runApplication()
 void runApplication()
@@ -94,31 +125,4 @@ void runApplication()
 
 
 	Application::instance().runMainLoop();
 	Application::instance().runMainLoop();
 	Application::shutDown();
 	Application::shutDown();
-}
-
-#if BS_PLATFORM == BS_PLATFORM_WIN32
-#include <windows.h>
-
-int CALLBACK WinMain(
-	_In_  HINSTANCE hInstance,
-	_In_  HINSTANCE hPrevInstance,
-	_In_  LPSTR lpCmdLine,
-	_In_  int nCmdShow
-	)
-{
-	CrashHandler::startUp();
-
-	__try
-	{
-		runApplication();
-	}
-	__except (gCrashHandler().reportCrash(GetExceptionInformation()))
-	{
-		PlatformUtility::terminate(true);
-	}
-
-	CrashHandler::shutDown();
-
-	return 0;
-}
-#endif // End BS_PLATFORM
+}

+ 9 - 0
MBansheeEditor/EditorApplication.cs

@@ -111,6 +111,15 @@ namespace BansheeEditor
             set { Internal_SetIsPaused(value); }
             set { Internal_SetIsPaused(value); }
         }
         }
 
 
+        /// <summary>
+        /// Returns true if the game is currently neither running nor paused. Use <see cref="IsPlaying"/> or 
+        /// <see cref="IsPaused"/> to actually change these states.
+        /// </summary>
+        public static bool IsStopped
+        {
+            get { return !IsPlaying && !IsPaused; }
+        }
+
         /// <summary>
         /// <summary>
         /// Render target that the main camera in the scene (if any) will render its view to. This generally means the main 
         /// Render target that the main camera in the scene (if any) will render its view to. This generally means the main 
         /// game window when running standalone, or the Game viewport when running in editor.
         /// game window when running standalone, or the Game viewport when running in editor.

+ 1 - 1
MBansheeEditor/Scene/SceneCamera.cs

@@ -55,7 +55,7 @@ namespace BansheeEditor
                 Cursor.Show();
                 Cursor.Show();
         }
         }
 
 
-        private void Update()
+        private void OnUpdate()
         {
         {
 		    bool goingForward = VirtualInput.IsButtonHeld(moveForwardBtn);
 		    bool goingForward = VirtualInput.IsButtonHeld(moveForwardBtn);
 		    bool goingBack = VirtualInput.IsButtonHeld(moveBackwardBtn);
 		    bool goingBack = VirtualInput.IsButtonHeld(moveBackwardBtn);

+ 32 - 29
MBansheeEditor/ScriptCodeManager.cs

@@ -32,45 +32,48 @@ namespace BansheeEditor
             if (CodeEditor.IsSolutionDirty)
             if (CodeEditor.IsSolutionDirty)
                 CodeEditor.SyncSolution();
                 CodeEditor.SyncSolution();
 
 
-            if (compilerInstance == null)
+            if (EditorApplication.IsStopped)
             {
             {
-                string outputDir = EditorApplication.ScriptAssemblyPath;
-
-                if (isGameAssemblyDirty)
+                if (compilerInstance == null)
                 {
                 {
-                    compilerInstance = ScriptCompiler.CompileAsync(
-                        ScriptAssemblyType.Game, BuildManager.ActivePlatform, true, outputDir);
+                    string outputDir = EditorApplication.ScriptAssemblyPath;
 
 
-                    EditorApplication.SetStatusCompiling(true);
-                    isGameAssemblyDirty = false;
-                }
-                else if (isEditorAssemblyDirty)
-                {
-                    compilerInstance = ScriptCompiler.CompileAsync(
-                        ScriptAssemblyType.Editor, BuildManager.ActivePlatform, true, outputDir);
+                    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;
+                        EditorApplication.SetStatusCompiling(true);
+                        isEditorAssemblyDirty = false;
+                    }
                 }
                 }
-            }
-            else
-            {
-                if (compilerInstance.IsDone)
+                else
                 {
                 {
-                    if (compilerInstance.HasErrors)
+                    if (compilerInstance.IsDone)
                     {
                     {
-                        foreach (var msg in compilerInstance.WarningMessages)
-                            Debug.LogError(FormMessage(msg));
+                        if (compilerInstance.HasErrors)
+                        {
+                            foreach (var msg in compilerInstance.WarningMessages)
+                                Debug.LogError(FormMessage(msg));
 
 
-                        foreach (var msg in compilerInstance.ErrorMessages)
-                            Debug.LogError(FormMessage(msg));
-                    }
+                            foreach (var msg in compilerInstance.ErrorMessages)
+                                Debug.LogError(FormMessage(msg));
+                        }
 
 
-                    compilerInstance.Dispose();
-                    compilerInstance = null;
+                        compilerInstance.Dispose();
+                        compilerInstance = null;
 
 
-                    EditorApplication.SetStatusCompiling(false);
-                    EditorApplication.ReloadAssemblies();
+                        EditorApplication.SetStatusCompiling(false);
+                        EditorApplication.ReloadAssemblies();
+                    }
                 }
                 }
             }
             }
         }
         }

+ 1 - 1
MBansheeEngine/Camera.cs

@@ -376,7 +376,7 @@ namespace BansheeEngine
             // TODO - Make RenderTexture a resource so I can save/restore it?
             // TODO - Make RenderTexture a resource so I can save/restore it?
         }
         }
 
 
-        private void Update()
+        private void OnUpdate()
         {
         {
             native.UpdateView(SceneObject);
             native.UpdateView(SceneObject);
         }
         }

+ 1 - 1
MBansheeEngine/Light.cs

@@ -125,7 +125,7 @@ namespace BansheeEngine
             _nativeLight.CastsShadow = serializableData.castShadows;
             _nativeLight.CastsShadow = serializableData.castShadows;
         }
         }
 
 
-        private void Update()
+        private void OnUpdate()
         {
         {
             
             
         }
         }

+ 1 - 1
MBansheeEngine/ProfilerOverlay.cs

@@ -45,7 +45,7 @@ namespace BansheeEngine
             impl = new ProfilerOverlayInternal(cam);
             impl = new ProfilerOverlayInternal(cam);
         }
         }
 
 
-        private void Update()
+        private void OnUpdate()
         {
         {
             if(!Paused)
             if(!Paused)
                 impl.Update();
                 impl.Update();

+ 1 - 1
MBansheeEngine/Renderable.cs

@@ -128,7 +128,7 @@ namespace BansheeEngine
             _native.Layers = serializableData.layers;
             _native.Layers = serializableData.layers;
         }
         }
 
 
-        private void Update()
+        private void OnUpdate()
         {
         {
             _native.UpdateTransform(SceneObject);
             _native.UpdateTransform(SceneObject);
         }
         }

+ 33 - 7
SBansheeEditor/Source/BsScriptBuildManager.cpp

@@ -16,6 +16,7 @@
 #include "BsEditorApplication.h"
 #include "BsEditorApplication.h"
 #include "BsResourceManifest.h"
 #include "BsResourceManifest.h"
 #include "BsBuiltinResources.h"
 #include "BsBuiltinResources.h"
+#include "BsSceneObject.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
@@ -289,22 +290,47 @@ namespace BansheeEngine
 
 
 			ProjectLibrary::ResourceEntry* resEntry = static_cast<ProjectLibrary::ResourceEntry*>(libEntry);
 			ProjectLibrary::ResourceEntry* resEntry = static_cast<ProjectLibrary::ResourceEntry*>(libEntry);
 
 
+			Path destPath = outputPath;
+			destPath.setFilename(entry.getFilename());
+
 			// If resource is prefab make sure to update it in case any of the prefabs it is referencing changed
 			// If resource is prefab make sure to update it in case any of the prefabs it is referencing changed
 			if (resEntry->meta->getTypeID() == TID_Prefab)
 			if (resEntry->meta->getTypeID() == TID_Prefab)
 			{
 			{
+				bool reload = gResources().isLoaded(uuid);
+
 				HPrefab prefab = static_resource_cast<Prefab>(gProjectLibrary().load(sourcePath));
 				HPrefab prefab = static_resource_cast<Prefab>(gProjectLibrary().load(sourcePath));
 				prefab->_updateChildInstances();
 				prefab->_updateChildInstances();
 
 
-				// TODO - I should also clear prefab diffs
-				gProjectLibrary().saveEntry(prefab);
+				// Clear prefab diffs as they're not used in standalone
+				Stack<HSceneObject> todo;
+				todo.push(prefab->_getRoot());
+
+				while (!todo.empty())
+				{
+					HSceneObject current = todo.top();
+					todo.pop();
+
+					current->_clearPrefabDiff();
+
+					UINT32 numChildren = current->getNumChildren();
+					for (UINT32 i = 0; i < numChildren; i++)
+					{
+						HSceneObject child = current->getChild(i);
+						todo.push(child);
+					}
+				}
+
+				gResources().save(prefab, destPath, false);
+
+				// Need to unload this one as we modified it in memory, and we don't want to persist those changes past
+				// this point
+				gResources().unload(prefab);
+
+				if (reload)
+					gProjectLibrary().load(sourcePath);
 			}
 			}
 			else
 			else
-			{
-				Path destPath = outputPath;
-				destPath.setFilename(entry.getFilename());
-
 				FileSystem::copy(entry, destPath);
 				FileSystem::copy(entry, destPath);
-			}
 		}
 		}
 
 
 		// Save icon
 		// Save icon

+ 2 - 2
SBansheeEngine/Include/BsManagedComponent.h

@@ -90,7 +90,7 @@ namespace BansheeEngine
 		void initialize(MonoObject* object);
 		void initialize(MonoObject* object);
 
 
 		typedef void(__stdcall *OnInitializedThunkDef) (MonoObject*, MonoException**);
 		typedef void(__stdcall *OnInitializedThunkDef) (MonoObject*, MonoException**);
-		typedef void(__stdcall *UpdateThunkDef) (MonoObject*, MonoException**);
+		typedef void(__stdcall *OnUpdateThunkDef) (MonoObject*, MonoException**);
 		typedef void(__stdcall *OnDestroyedThunkDef) (MonoObject*, MonoException**);
 		typedef void(__stdcall *OnDestroyedThunkDef) (MonoObject*, MonoException**);
 		typedef void(__stdcall *OnResetThunkDef) (MonoObject*, MonoException**);
 		typedef void(__stdcall *OnResetThunkDef) (MonoObject*, MonoException**);
 		typedef void(__stdcall *OnEnabledThunkDef) (MonoObject*, MonoException**);
 		typedef void(__stdcall *OnEnabledThunkDef) (MonoObject*, MonoException**);
@@ -111,7 +111,7 @@ namespace BansheeEngine
 		ManagedSerializableObjectInfoPtr mObjInfo; // Transient
 		ManagedSerializableObjectInfoPtr mObjInfo; // Transient
 
 
 		OnInitializedThunkDef mOnInitializedThunk;
 		OnInitializedThunkDef mOnInitializedThunk;
-		UpdateThunkDef mUpdateThunk;
+		OnUpdateThunkDef mOnUpdateThunk;
 		OnResetThunkDef mOnResetThunk;
 		OnResetThunkDef mOnResetThunk;
 		OnDestroyedThunkDef mOnDestroyThunk;
 		OnDestroyedThunkDef mOnDestroyThunk;
 		OnDestroyedThunkDef mOnDisabledThunk;
 		OnDestroyedThunkDef mOnDisabledThunk;

+ 8 - 8
SBansheeEngine/Source/BsManagedComponent.cpp

@@ -15,13 +15,13 @@
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
 	ManagedComponent::ManagedComponent()
 	ManagedComponent::ManagedComponent()
-		:mManagedInstance(nullptr), mUpdateThunk(nullptr), mOnDestroyThunk(nullptr), mOnInitializedThunk(nullptr), 
+		:mManagedInstance(nullptr), mOnUpdateThunk(nullptr), mOnDestroyThunk(nullptr), mOnInitializedThunk(nullptr), 
 		mOnResetThunk(nullptr), mMissingType(false), mRequiresReset(true), mOnEnabledThunk(nullptr), mOnDisabledThunk(nullptr),
 		mOnResetThunk(nullptr), mMissingType(false), mRequiresReset(true), mOnEnabledThunk(nullptr), mOnDisabledThunk(nullptr),
 		mCalculateBoundsMethod(nullptr), mRunInEditor(false)
 		mCalculateBoundsMethod(nullptr), mRunInEditor(false)
 	{ }
 	{ }
 
 
 	ManagedComponent::ManagedComponent(const HSceneObject& parent, MonoReflectionType* runtimeType)
 	ManagedComponent::ManagedComponent(const HSceneObject& parent, MonoReflectionType* runtimeType)
-		: Component(parent), mManagedInstance(nullptr), mRuntimeType(runtimeType), mUpdateThunk(nullptr), 
+		: Component(parent), mManagedInstance(nullptr), mRuntimeType(runtimeType), mOnUpdateThunk(nullptr), 
 		mOnDestroyThunk(nullptr), mOnInitializedThunk(nullptr), mOnResetThunk(nullptr), mMissingType(false), 
 		mOnDestroyThunk(nullptr), mOnInitializedThunk(nullptr), mOnResetThunk(nullptr), mMissingType(false), 
 		mRequiresReset(true), mOnEnabledThunk(nullptr), mOnDisabledThunk(nullptr), mCalculateBoundsMethod(nullptr),
 		mRequiresReset(true), mOnEnabledThunk(nullptr), mOnDisabledThunk(nullptr), mCalculateBoundsMethod(nullptr),
 		mRunInEditor(false)
 		mRunInEditor(false)
@@ -87,7 +87,7 @@ namespace BansheeEngine
 
 
 			mRuntimeType = nullptr;
 			mRuntimeType = nullptr;
 			mOnInitializedThunk = nullptr;
 			mOnInitializedThunk = nullptr;
-			mUpdateThunk = nullptr;
+			mOnUpdateThunk = nullptr;
 			mOnDestroyThunk = nullptr;
 			mOnDestroyThunk = nullptr;
 			mOnEnabledThunk = nullptr;
 			mOnEnabledThunk = nullptr;
 			mOnDisabledThunk = nullptr;
 			mOnDisabledThunk = nullptr;
@@ -150,9 +150,9 @@ namespace BansheeEngine
 			if (onInitializedMethod != nullptr)
 			if (onInitializedMethod != nullptr)
 				mOnInitializedThunk = (OnInitializedThunkDef)onInitializedMethod->getThunk();
 				mOnInitializedThunk = (OnInitializedThunkDef)onInitializedMethod->getThunk();
 
 
-			MonoMethod* updateMethod = managedClass->getMethod("Update", 0);
-			if (updateMethod != nullptr)
-				mUpdateThunk = (UpdateThunkDef)updateMethod->getThunk();
+			MonoMethod* onUpdateMethod = managedClass->getMethod("OnUpdate", 0);
+			if (onUpdateMethod != nullptr)
+				mOnUpdateThunk = (OnUpdateThunkDef)onUpdateMethod->getThunk();
 
 
 			MonoMethod* onResetMethod = managedClass->getMethod("OnReset", 0);
 			MonoMethod* onResetMethod = managedClass->getMethod("OnReset", 0);
 			if (onResetMethod != nullptr)
 			if (onResetMethod != nullptr)
@@ -229,11 +229,11 @@ namespace BansheeEngine
 
 
 		assert(mManagedInstance != nullptr);
 		assert(mManagedInstance != nullptr);
 
 
-		if (mUpdateThunk != nullptr)
+		if (mOnUpdateThunk != nullptr)
 		{
 		{
 			// Note: Not calling virtual methods. Can be easily done if needed but for now doing this
 			// Note: Not calling virtual methods. Can be easily done if needed but for now doing this
 			// for some extra speed.
 			// for some extra speed.
-			MonoUtil::invokeThunk(mUpdateThunk, mManagedInstance);
+			MonoUtil::invokeThunk(mOnUpdateThunk, mManagedInstance);
 		}
 		}
 	}
 	}
 
 

+ 1 - 0
TODO.txt

@@ -54,6 +54,7 @@ Finalizing:
  - Add copyright notices in all files & change license to GPL
  - Add copyright notices in all files & change license to GPL
  - Need to generate a proper merge of dev and preview branches
  - Need to generate a proper merge of dev and preview branches
    - Use "git revert --no-commit <COMMITID>..HEAD" to reverse anything on the preview branch that was done after the branch creation, then merge
    - Use "git revert --no-commit <COMMITID>..HEAD" to reverse anything on the preview branch that was done after the branch creation, then merge
+   - Consider moving dev to that branch completely and just marking the release with a tag (this might mean I just need to move the master branch to that repo instead of merging)
  - Test if C++ example still works
  - Test if C++ example still works
  - Add "example" for using the editor (possibly a video, or a set of screenshots + a data.rar with required resources)
  - Add "example" for using the editor (possibly a video, or a set of screenshots + a data.rar with required resources)