BsScriptModalWindow.cpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "Wrappers/BsScriptModalWindow.h"
  4. #include "BsScriptMeta.h"
  5. #include "BsMonoField.h"
  6. #include "BsMonoClass.h"
  7. #include "BsMonoMethod.h"
  8. #include "BsMonoManager.h"
  9. #include "BsMonoUtil.h"
  10. #include "BsMonoAssembly.h"
  11. #include "BsScriptObjectManager.h"
  12. #include "RenderAPI/BsRenderWindow.h"
  13. #include "Wrappers/GUI/BsScriptGUILayout.h"
  14. #include "Generated/BsScriptHString.generated.h"
  15. using namespace std::placeholders;
  16. namespace bs
  17. {
  18. MonoField* ScriptModalWindow::guiPanelField = nullptr;
  19. ScriptModalWindow::ScriptModalWindow(ManagedModalWindow* window)
  20. :ScriptObject(window->getManagedInstance()), mModalWindow(window)
  21. {
  22. mOnAssemblyRefreshStartedConn = ScriptObjectManager::instance().onRefreshStarted.connect(std::bind(&ScriptModalWindow::onAssemblyRefreshStarted, this));
  23. }
  24. ScriptModalWindow::~ScriptModalWindow()
  25. {
  26. mOnAssemblyRefreshStartedConn.disconnect();
  27. }
  28. void ScriptModalWindow::initRuntimeData()
  29. {
  30. metaData.scriptClass->addInternalCall("Internal_CreateInstance", (void*)&ScriptModalWindow::internal_createInstance);
  31. metaData.scriptClass->addInternalCall("Internal_Close", (void*)&ScriptModalWindow::internal_close);
  32. metaData.scriptClass->addInternalCall("Internal_GetWidth", (void*)&ScriptModalWindow::internal_getWidth);
  33. metaData.scriptClass->addInternalCall("Internal_GetHeight", (void*)&ScriptModalWindow::internal_getHeight);
  34. metaData.scriptClass->addInternalCall("Internal_SetWidth", (void*)&ScriptModalWindow::internal_setWidth);
  35. metaData.scriptClass->addInternalCall("Internal_SetHeight", (void*)&ScriptModalWindow::internal_setHeight);
  36. metaData.scriptClass->addInternalCall("Internal_SetTitle", (void*)&ScriptModalWindow::internal_setTitle);
  37. metaData.scriptClass->addInternalCall("Internal_ScreenToWindowPos", (void*)&ScriptModalWindow::internal_screenToWindowPos);
  38. metaData.scriptClass->addInternalCall("Internal_WindowToScreenPos", (void*)&ScriptModalWindow::internal_windowToScreenPos);
  39. guiPanelField = metaData.scriptClass->getField("GUI");
  40. }
  41. void ScriptModalWindow::internal_createInstance(MonoObject* instance, bool allowCloseButton)
  42. {
  43. ::MonoClass* rawMonoClass = MonoUtil::getClass(instance);
  44. MonoClass* monoClass = MonoManager::instance().findClass(rawMonoClass);
  45. MonoAssembly* assembly = MonoManager::instance().getAssembly(EDITOR_ASSEMBLY);
  46. MonoClass* defaultSizeAttrib = assembly->getClass(EDITOR_NS, "DefaultSize");
  47. if (defaultSizeAttrib == nullptr)
  48. BS_EXCEPT(InternalErrorException, "Cannot find DefaultSize managed class.");
  49. MonoField* defaultWidthField = defaultSizeAttrib->getField("width");
  50. MonoField* defaultHeightField = defaultSizeAttrib->getField("height");
  51. int width = 200;
  52. int height = 200;
  53. MonoObject* defaultSizeObj = monoClass->getAttribute(defaultSizeAttrib);
  54. if (defaultSizeObj != nullptr)
  55. {
  56. defaultWidthField->get(defaultSizeObj, &width);
  57. defaultHeightField->get(defaultSizeObj, &height);
  58. }
  59. ManagedModalWindow* modalWindow = bs_new<ManagedModalWindow>(allowCloseButton, width, height, instance);
  60. ScriptModalWindow* nativeInstance = new (bs_alloc<ScriptModalWindow>()) ScriptModalWindow(modalWindow);
  61. modalWindow->setParent(nativeInstance);
  62. }
  63. void ScriptModalWindow::internal_close(ScriptModalWindow* thisPtr)
  64. {
  65. if (thisPtr->mModalWindow != nullptr)
  66. thisPtr->mModalWindow->close();
  67. }
  68. void ScriptModalWindow::internal_setTitle(ScriptModalWindow* thisPtr, MonoObject* title)
  69. {
  70. HString titleStr = HString::dummy();
  71. if (title != nullptr)
  72. {
  73. ScriptHString* textScript = ScriptHString::toNative(title);
  74. titleStr = *textScript->getInternal();
  75. }
  76. thisPtr->mModalWindow->setTitle(titleStr);
  77. }
  78. void ScriptModalWindow::notifyWindowDestroyed()
  79. {
  80. mModalWindow = nullptr;
  81. }
  82. void ScriptModalWindow::onAssemblyRefreshStarted()
  83. {
  84. if (mModalWindow != nullptr)
  85. mModalWindow->close();
  86. }
  87. UINT32 ScriptModalWindow::internal_getWidth(ScriptModalWindow* thisPtr)
  88. {
  89. if (thisPtr->mModalWindow != nullptr)
  90. return thisPtr->mModalWindow->getWidth();
  91. return 0;
  92. }
  93. UINT32 ScriptModalWindow::internal_getHeight(ScriptModalWindow* thisPtr)
  94. {
  95. if (thisPtr->mModalWindow != nullptr)
  96. return thisPtr->mModalWindow->getHeight();
  97. return 0;
  98. }
  99. void ScriptModalWindow::internal_setWidth(ScriptModalWindow* thisPtr, UINT32 value)
  100. {
  101. if (thisPtr->mModalWindow != nullptr)
  102. thisPtr->mModalWindow->setSize(value, thisPtr->mModalWindow->getHeight());
  103. }
  104. void ScriptModalWindow::internal_setHeight(ScriptModalWindow* thisPtr, UINT32 value)
  105. {
  106. if (thisPtr->mModalWindow != nullptr)
  107. thisPtr->mModalWindow->setSize(thisPtr->mModalWindow->getWidth(), value);
  108. }
  109. void ScriptModalWindow::internal_screenToWindowPos(ScriptModalWindow* thisPtr, Vector2I* screenPos, Vector2I* windowPos)
  110. {
  111. if (thisPtr->mModalWindow != nullptr)
  112. *windowPos = thisPtr->mModalWindow->screenToWindowPos(*screenPos);
  113. else
  114. *windowPos = *screenPos;
  115. }
  116. void ScriptModalWindow::internal_windowToScreenPos(ScriptModalWindow* thisPtr, Vector2I* windowPos, Vector2I* screenPos)
  117. {
  118. if (thisPtr->mModalWindow != nullptr)
  119. *screenPos = thisPtr->mModalWindow->windowToScreenPos(*windowPos);
  120. else
  121. *screenPos = *windowPos;
  122. }
  123. ManagedModalWindow::ManagedModalWindow(bool allowCloseButton, UINT32 width, UINT32 height, MonoObject* managedInstance)
  124. : ModalWindow(HString::dummy(), allowCloseButton, width, height), mManagedInstance(managedInstance)
  125. {
  126. mGCHandle = MonoUtil::newGCHandle(mManagedInstance);
  127. mManagedInstance = MonoUtil::getObjectFromGCHandle(mGCHandle);
  128. MonoObject* guiPanel = ScriptGUIPanel::createFromExisting(mContents);
  129. mContentsPanel = ScriptGUILayout::toNative(guiPanel);
  130. ScriptModalWindow::guiPanelField->set(mManagedInstance, guiPanel);
  131. ::MonoClass* rawMonoClass = MonoUtil::getClass(mManagedInstance);
  132. MonoClass* monoClass = MonoManager::instance().findClass(rawMonoClass);
  133. mNamespace = monoClass->getNamespace();
  134. mTypename = monoClass->getTypeName();
  135. reloadMonoTypes(monoClass);
  136. }
  137. ManagedModalWindow::~ManagedModalWindow()
  138. {
  139. if (mGCHandle != 0)
  140. close();
  141. }
  142. bool ManagedModalWindow::createManagedInstance()
  143. {
  144. MonoAssembly* assembly = MonoManager::instance().getAssembly(EDITOR_ASSEMBLY);
  145. if (assembly != nullptr)
  146. {
  147. MonoClass* editorWindowClass = assembly->getClass(mNamespace, mTypename);
  148. if (editorWindowClass != nullptr)
  149. {
  150. mManagedInstance = editorWindowClass->createInstance(false);
  151. mGCHandle = MonoUtil::newGCHandle(mManagedInstance);
  152. mManagedInstance = MonoUtil::getObjectFromGCHandle(mGCHandle);
  153. MonoObject* guiPanel = ScriptGUIPanel::createFromExisting(mContents);
  154. mContentsPanel = ScriptGUILayout::toNative(guiPanel);
  155. ScriptModalWindow::guiPanelField->set(mManagedInstance, guiPanel);
  156. reloadMonoTypes(editorWindowClass);
  157. return true;
  158. }
  159. }
  160. return false;
  161. }
  162. void ManagedModalWindow::releaseManagedInstance()
  163. {
  164. MonoUtil::freeGCHandle(mGCHandle);
  165. mGCHandle = 0;
  166. }
  167. void ManagedModalWindow::triggerOnInitialize()
  168. {
  169. if (mOnInitializeThunk != nullptr && mManagedInstance != nullptr)
  170. {
  171. // Note: Not calling virtual methods. Can be easily done if needed but for now doing this
  172. // for some extra speed.
  173. MonoUtil::invokeThunk(mOnInitializeThunk, mManagedInstance);
  174. }
  175. }
  176. void ManagedModalWindow::triggerOnDestroy()
  177. {
  178. if (mOnDestroyThunk != nullptr && mManagedInstance != nullptr)
  179. {
  180. // Note: Not calling virtual methods. Can be easily done if needed but for now doing this
  181. // for some extra speed.
  182. MonoUtil::invokeThunk(mOnDestroyThunk, mManagedInstance);
  183. }
  184. }
  185. void ManagedModalWindow::setParent(ScriptModalWindow* parent)
  186. {
  187. mScriptParent = parent;
  188. }
  189. void ManagedModalWindow::update()
  190. {
  191. if (!mIsInitialized)
  192. {
  193. triggerOnInitialize();
  194. mIsInitialized = true;
  195. }
  196. if (mUpdateThunk != nullptr && mManagedInstance != nullptr)
  197. {
  198. // Note: Not calling virtual methods. Can be easily done if needed but for now doing this
  199. // for some extra speed.
  200. MonoUtil::invokeThunk(mUpdateThunk, mManagedInstance);
  201. }
  202. }
  203. void ManagedModalWindow::resized()
  204. {
  205. UINT32 width = getWidth();
  206. UINT32 height = getHeight();
  207. if (mOnWindowResizedMethod != nullptr && mManagedInstance != nullptr)
  208. {
  209. void* params[] = { &width, &height };
  210. mOnWindowResizedMethod->invokeVirtual(mManagedInstance, params);
  211. }
  212. ModalWindow::resized();
  213. }
  214. void ManagedModalWindow::close()
  215. {
  216. triggerOnDestroy();
  217. mContentsPanel->destroy();
  218. mContentsPanel = nullptr;
  219. releaseManagedInstance();
  220. mScriptParent->notifyWindowDestroyed();
  221. ModalWindow::close();
  222. }
  223. void ManagedModalWindow::reloadMonoTypes(MonoClass* windowClass)
  224. {
  225. MonoMethod* updateMethod = windowClass->getMethod("OnEditorUpdate", 0);
  226. if (updateMethod != nullptr)
  227. mUpdateThunk = (UpdateThunkDef)updateMethod->getThunk();
  228. MonoMethod* onInitializeMethod = windowClass->getMethod("OnInitialize", 0);
  229. if (onInitializeMethod != nullptr)
  230. mOnInitializeThunk = (OnInitializeThunkDef)onInitializeMethod->getThunk();
  231. MonoMethod* onDestroyMethod = windowClass->getMethod("OnDestroy", 0);
  232. if (onDestroyMethod != nullptr)
  233. mOnDestroyThunk = (OnDestroyThunkDef)onDestroyMethod->getThunk();
  234. MonoClass* modalWindowClass = windowClass->getBaseClass();
  235. mOnWindowResizedMethod = modalWindowClass->getMethod("OnWindowResized", 2);
  236. }
  237. }