BsScriptUndoRedo.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "Wrappers/BsScriptUndoRedo.h"
  4. #include "BsScriptMeta.h"
  5. #include "BsMonoClass.h"
  6. #include "BsMonoMethod.h"
  7. #include "Wrappers/BsScriptSceneObject.h"
  8. #include "BsMonoUtil.h"
  9. #include "BsScriptGameObjectManager.h"
  10. #include "UndoRedo/BsUndoRedo.h"
  11. #include "UndoRedo/BsCmdCloneSO.h"
  12. #include "UndoRedo/BsCmdCreateSO.h"
  13. #include "UndoRedo/BsCmdDeleteSO.h"
  14. #include "UndoRedo/BsCmdInstantiateSO.h"
  15. #include "UndoRedo/BsCmdReparentSO.h"
  16. #include "UndoRedo/BsCmdBreakPrefab.h"
  17. #include "Wrappers/BsScriptPrefab.h"
  18. #include "BsManagedEditorCommand.h"
  19. #include "Scene/BsPrefab.h"
  20. #include "BsScriptObjectManager.h"
  21. namespace bs
  22. {
  23. ScriptUndoRedo* ScriptUndoRedo::sGlobalUndoRedo = nullptr;
  24. HEvent ScriptUndoRedo::sDomainLoadConn;
  25. ScriptUndoRedo::ScriptUndoRedo(MonoObject* instance, const SPtr<UndoRedo>& undoRedo)
  26. :ScriptObject(instance), mUndoRedo(undoRedo)
  27. { }
  28. void ScriptUndoRedo::initRuntimeData()
  29. {
  30. metaData.scriptClass->addInternalCall("Internal_CreateInstance", (void*)&ScriptUndoRedo::internal_CreateInstance);
  31. metaData.scriptClass->addInternalCall("Internal_Undo", (void*)&ScriptUndoRedo::internal_Undo);
  32. metaData.scriptClass->addInternalCall("Internal_Redo", (void*)&ScriptUndoRedo::internal_Redo);
  33. metaData.scriptClass->addInternalCall("Internal_RegisterCommand", (void*)&ScriptUndoRedo::internal_RegisterCommand);
  34. metaData.scriptClass->addInternalCall("Internal_PushGroup", (void*)&ScriptUndoRedo::internal_PushGroup);
  35. metaData.scriptClass->addInternalCall("Internal_PopGroup", (void*)&ScriptUndoRedo::internal_PopGroup);
  36. metaData.scriptClass->addInternalCall("Internal_Clear", (void*)&ScriptUndoRedo::internal_Clear);
  37. metaData.scriptClass->addInternalCall("Internal_GetTopCommandId", (void*)&ScriptUndoRedo::internal_GetTopCommandId);
  38. metaData.scriptClass->addInternalCall("Internal_PopCommand", (void*)&ScriptUndoRedo::internal_PopCommand);
  39. metaData.scriptClass->addInternalCall("Internal_CloneSO", (void*)&ScriptUndoRedo::internal_CloneSO);
  40. metaData.scriptClass->addInternalCall("Internal_CloneSOMulti", (void*)&ScriptUndoRedo::internal_CloneSOMulti);
  41. metaData.scriptClass->addInternalCall("Internal_Instantiate", (void*)&ScriptUndoRedo::internal_Instantiate);
  42. metaData.scriptClass->addInternalCall("Internal_CreateSO", (void*)&ScriptUndoRedo::internal_CreateSO);
  43. metaData.scriptClass->addInternalCall("Internal_CreateSO2", (void*)&ScriptUndoRedo::internal_CreateSO2);
  44. metaData.scriptClass->addInternalCall("Internal_DeleteSO", (void*)&ScriptUndoRedo::internal_DeleteSO);
  45. metaData.scriptClass->addInternalCall("Internal_ReparentSO", (void*)&ScriptUndoRedo::internal_ReparentSO);
  46. metaData.scriptClass->addInternalCall("Internal_ReparentSOMulti", (void*)&ScriptUndoRedo::internal_ReparentSOMulti);
  47. metaData.scriptClass->addInternalCall("Internal_BreakPrefab", (void*)&ScriptUndoRedo::internal_BreakPrefab);
  48. }
  49. void ScriptUndoRedo::startUp()
  50. {
  51. auto createPanel = []()
  52. {
  53. assert(sGlobalUndoRedo == nullptr);
  54. bool dummy = false;
  55. void* ctorParams[1] = { &dummy };
  56. MonoObject* instance = metaData.scriptClass->createInstance("bool", ctorParams);
  57. new (bs_alloc<ScriptUndoRedo>()) ScriptUndoRedo(instance, nullptr);
  58. MonoMethod* setGlobal = metaData.scriptClass->getMethod("Internal_SetGlobal", 1);
  59. void* setGlobalParams[1] = { instance };
  60. setGlobal->invoke(nullptr, setGlobalParams);
  61. };
  62. sDomainLoadConn = ScriptObjectManager::instance().onRefreshDomainLoaded.connect(createPanel);
  63. createPanel();
  64. }
  65. void ScriptUndoRedo::shutDown()
  66. {
  67. sDomainLoadConn.disconnect();
  68. }
  69. MonoObject* ScriptUndoRedo::create()
  70. {
  71. bool dummy = false;
  72. void* params[1] = { &dummy };
  73. MonoObject* instance = metaData.scriptClass->createInstance("bool", params);
  74. SPtr<UndoRedo> undoRedo = bs_shared_ptr_new<UndoRedo>();
  75. new (bs_alloc<ScriptUndoRedo>()) ScriptUndoRedo(instance, undoRedo);
  76. return instance;
  77. }
  78. void ScriptUndoRedo::internal_CreateInstance(MonoObject* instance)
  79. {
  80. SPtr<UndoRedo> undoRedo = bs_shared_ptr_new<UndoRedo>();
  81. new (bs_alloc<ScriptUndoRedo>()) ScriptUndoRedo(instance, undoRedo);
  82. }
  83. void ScriptUndoRedo::internal_Undo(ScriptUndoRedo* thisPtr)
  84. {
  85. UndoRedo* undoRedo = thisPtr->mUndoRedo != nullptr ? thisPtr->mUndoRedo.get() : UndoRedo::instancePtr();
  86. undoRedo->undo();
  87. }
  88. void ScriptUndoRedo::internal_Redo(ScriptUndoRedo* thisPtr)
  89. {
  90. UndoRedo* undoRedo = thisPtr->mUndoRedo != nullptr ? thisPtr->mUndoRedo.get() : UndoRedo::instancePtr();
  91. undoRedo->redo();
  92. }
  93. void ScriptUndoRedo::internal_RegisterCommand(ScriptUndoRedo* thisPtr, ScriptCmdManaged* command)
  94. {
  95. UndoRedo* undoRedo = thisPtr->mUndoRedo != nullptr ? thisPtr->mUndoRedo.get() : UndoRedo::instancePtr();
  96. undoRedo->registerCommand(command->getInternal());
  97. }
  98. void ScriptUndoRedo::internal_PushGroup(ScriptUndoRedo* thisPtr, MonoString* name)
  99. {
  100. String nativeName = MonoUtil::monoToString(name);
  101. UndoRedo* undoRedo = thisPtr->mUndoRedo != nullptr ? thisPtr->mUndoRedo.get() : UndoRedo::instancePtr();
  102. undoRedo->pushGroup(nativeName);
  103. }
  104. void ScriptUndoRedo::internal_PopGroup(ScriptUndoRedo* thisPtr, MonoString* name)
  105. {
  106. String nativeName = MonoUtil::monoToString(name);
  107. UndoRedo* undoRedo = thisPtr->mUndoRedo != nullptr ? thisPtr->mUndoRedo.get() : UndoRedo::instancePtr();
  108. undoRedo->popGroup(nativeName);
  109. }
  110. void ScriptUndoRedo::internal_Clear(ScriptUndoRedo* thisPtr)
  111. {
  112. UndoRedo* undoRedo = thisPtr->mUndoRedo != nullptr ? thisPtr->mUndoRedo.get() : UndoRedo::instancePtr();
  113. return undoRedo->clear();
  114. }
  115. UINT32 ScriptUndoRedo::internal_GetTopCommandId(ScriptUndoRedo* thisPtr)
  116. {
  117. UndoRedo* undoRedo = thisPtr->mUndoRedo != nullptr ? thisPtr->mUndoRedo.get() : UndoRedo::instancePtr();
  118. return undoRedo->getTopCommandId();
  119. }
  120. void ScriptUndoRedo::internal_PopCommand(ScriptUndoRedo* thisPtr, UINT32 id)
  121. {
  122. UndoRedo* undoRedo = thisPtr->mUndoRedo != nullptr ? thisPtr->mUndoRedo.get() : UndoRedo::instancePtr();
  123. undoRedo->popCommand(id);
  124. }
  125. MonoObject* ScriptUndoRedo::internal_CloneSO(ScriptSceneObject* soPtr, MonoString* description)
  126. {
  127. String nativeDescription = MonoUtil::monoToString(description);
  128. HSceneObject clone = CmdCloneSO::execute(soPtr->getHandle(), nativeDescription);
  129. ScriptSceneObject* cloneSoPtr = ScriptGameObjectManager::instance().getOrCreateScriptSceneObject(clone);
  130. return cloneSoPtr->getManagedInstance();
  131. }
  132. MonoArray* ScriptUndoRedo::internal_CloneSOMulti(MonoArray* soPtrs, MonoString* description)
  133. {
  134. String nativeDescription = MonoUtil::monoToString(description);
  135. ScriptArray input(soPtrs);
  136. ScriptArray output = ScriptArray::create<ScriptSceneObject>(input.size());
  137. for (UINT32 i = 0; i < input.size(); i++)
  138. {
  139. ScriptSceneObject* soPtr = input.get<ScriptSceneObject*>(i);
  140. HSceneObject clone = CmdCloneSO::execute(soPtr->getHandle(), nativeDescription);
  141. ScriptSceneObject* cloneSoPtr = ScriptGameObjectManager::instance().getOrCreateScriptSceneObject(clone);
  142. output.set(i, cloneSoPtr->getManagedInstance());
  143. }
  144. return output.getInternal();
  145. }
  146. MonoObject* ScriptUndoRedo::internal_Instantiate(ScriptPrefab* prefabPtr, MonoString* description)
  147. {
  148. HPrefab prefab = prefabPtr->getHandle();
  149. if (!prefab.isLoaded())
  150. return nullptr;
  151. String nativeDescription = MonoUtil::monoToString(description);
  152. HSceneObject clone = CmdInstantiateSO::execute(prefab, nativeDescription);
  153. ScriptSceneObject* cloneSoPtr = ScriptGameObjectManager::instance().getOrCreateScriptSceneObject(clone);
  154. return cloneSoPtr->getManagedInstance();
  155. }
  156. MonoObject* ScriptUndoRedo::internal_CreateSO(MonoString* name, MonoString* description)
  157. {
  158. String nativeName = MonoUtil::monoToString(name);
  159. String nativeDescription = MonoUtil::monoToString(description);
  160. HSceneObject newObj = CmdCreateSO::execute(nativeName, 0, nativeDescription);
  161. return ScriptGameObjectManager::instance().getOrCreateScriptSceneObject(newObj)->getManagedInstance();
  162. }
  163. MonoObject* ScriptUndoRedo::internal_CreateSO2(MonoString* name, MonoArray* types, MonoString* description)
  164. {
  165. String nativeName = MonoUtil::monoToString(name);
  166. String nativeDescription = MonoUtil::monoToString(description);
  167. ScriptAssemblyManager& sam = ScriptAssemblyManager::instance();
  168. MonoClass* managedComponent = sam.getBuiltinClasses().managedComponentClass;
  169. ScriptArray scriptArray(types);
  170. Vector<UINT32> typeIds;
  171. for (UINT32 i = 0; i < scriptArray.size(); i++)
  172. {
  173. MonoReflectionType* paramType = scriptArray.get<MonoReflectionType*>(i);
  174. if(!paramType)
  175. continue;
  176. ::MonoClass* requestedClass = MonoUtil::getClass(paramType);
  177. bool isManagedComponent = MonoUtil::isSubClassOf(requestedClass, managedComponent->_getInternalClass());
  178. if (isManagedComponent)
  179. {
  180. BS_LOG(Warning, Editor, "Only built-in components can be added though this method.");
  181. continue;
  182. }
  183. BuiltinComponentInfo* info = sam.getBuiltinComponentInfo(paramType);
  184. if (info == nullptr)
  185. {
  186. BS_LOG(Warning, Editor, "Provided type is not a valid component")
  187. continue;
  188. }
  189. typeIds.push_back(info->typeId);
  190. }
  191. HSceneObject newObj = CmdCreateSO::execute(nativeName, 0, typeIds, nativeDescription);
  192. return ScriptGameObjectManager::instance().getOrCreateScriptSceneObject(newObj)->getManagedInstance();
  193. }
  194. void ScriptUndoRedo::internal_DeleteSO(ScriptSceneObject* soPtr, MonoString* description)
  195. {
  196. String nativeDescription = MonoUtil::monoToString(description);
  197. CmdDeleteSO::execute(soPtr->getHandle(), nativeDescription);
  198. }
  199. void ScriptUndoRedo::internal_ReparentSO(ScriptSceneObject* soPtr, ScriptSceneObject* parentSOPtr, MonoString* description)
  200. {
  201. HSceneObject parent;
  202. if (parentSOPtr != nullptr)
  203. parent = parentSOPtr->getHandle();
  204. String nativeDescription = MonoUtil::monoToString(description);
  205. HSceneObject so = soPtr->getHandle();
  206. CmdReparentSO::execute(so, parent, nativeDescription);
  207. }
  208. void ScriptUndoRedo::internal_ReparentSOMulti(MonoArray* soPtrs, ScriptSceneObject* parentSOPtr, MonoString* description)
  209. {
  210. HSceneObject parent;
  211. if (parentSOPtr != nullptr)
  212. parent = parentSOPtr->getHandle();
  213. String nativeDescription = MonoUtil::monoToString(description);
  214. ScriptArray input(soPtrs);
  215. for (UINT32 i = 0; i < input.size(); i++)
  216. {
  217. ScriptSceneObject* soPtr = input.get<ScriptSceneObject*>(i);
  218. HSceneObject so = soPtr->getHandle();
  219. CmdReparentSO::execute(so, parent, nativeDescription);
  220. }
  221. }
  222. void ScriptUndoRedo::internal_BreakPrefab(ScriptSceneObject* soPtr, MonoString* description)
  223. {
  224. String nativeDescription = MonoUtil::monoToString(description);
  225. HSceneObject so = soPtr->getHandle();
  226. CmdBreakPrefab::execute(so, nativeDescription);
  227. }
  228. }