BsScriptGameObjectManager.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsScriptGameObjectManager.h"
  4. #include "BsScriptGameObject.h"
  5. #include "BsScriptComponent.h"
  6. #include "BsScriptManagedComponent.h"
  7. #include "BsScriptSceneObject.h"
  8. #include "BsGameObjectManager.h"
  9. #include "BsGameObject.h"
  10. #include "BsComponent.h"
  11. #include "BsManagedComponent.h"
  12. #include "BsSceneObject.h"
  13. #include "BsMonoManager.h"
  14. #include "BsMonoAssembly.h"
  15. #include "BsMonoClass.h"
  16. #include "BsScriptAssemblyManager.h"
  17. #include "BsScriptObjectManager.h"
  18. using namespace std::placeholders;
  19. namespace bs
  20. {
  21. ScriptGameObjectManager::ScriptGameObjectEntry::ScriptGameObjectEntry()
  22. :instance(nullptr), isComponent(false)
  23. { }
  24. ScriptGameObjectManager::ScriptGameObjectEntry::ScriptGameObjectEntry(ScriptGameObjectBase* instance, bool isComponent)
  25. :instance(instance), isComponent(isComponent)
  26. { }
  27. ScriptGameObjectManager::ScriptGameObjectManager()
  28. {
  29. // Calls OnReset on all components after assembly reload happens
  30. mOnAssemblyReloadDoneConn = ScriptObjectManager::instance().onRefreshComplete.connect(
  31. std::bind(&ScriptGameObjectManager::sendComponentResetEvents, this));
  32. onGameObjectDestroyedConn = GameObjectManager::instance().onDestroyed.connect(
  33. std::bind(&ScriptGameObjectManager::onGameObjectDestroyed, this, _1));
  34. }
  35. ScriptGameObjectManager::~ScriptGameObjectManager()
  36. {
  37. mOnAssemblyReloadDoneConn.disconnect();
  38. onGameObjectDestroyedConn.disconnect();
  39. }
  40. ScriptSceneObject* ScriptGameObjectManager::getOrCreateScriptSceneObject(const HSceneObject& sceneObject)
  41. {
  42. ScriptSceneObject* so = getScriptSceneObject(sceneObject);
  43. if (so != nullptr)
  44. return so;
  45. return createScriptSceneObject(sceneObject);
  46. }
  47. ScriptSceneObject* ScriptGameObjectManager::createScriptSceneObject(const HSceneObject& sceneObject)
  48. {
  49. MonoClass* sceneObjectClass = ScriptAssemblyManager::instance().getSceneObjectClass();
  50. MonoObject* instance = sceneObjectClass->createInstance();
  51. return createScriptSceneObject(instance, sceneObject);
  52. }
  53. ScriptSceneObject* ScriptGameObjectManager::createScriptSceneObject(MonoObject* existingInstance, const HSceneObject& sceneObject)
  54. {
  55. ScriptSceneObject* so = getScriptSceneObject(sceneObject);
  56. if (so != nullptr)
  57. BS_EXCEPT(InvalidStateException, "Script object for this SceneObject already exists.");
  58. ScriptSceneObject* nativeInstance = new (bs_alloc<ScriptSceneObject>()) ScriptSceneObject(existingInstance, sceneObject);
  59. mScriptSceneObjects[sceneObject.getInstanceId()] = nativeInstance;
  60. return nativeInstance;
  61. }
  62. ScriptManagedComponent* ScriptGameObjectManager::createManagedScriptComponent(MonoObject* existingInstance,
  63. const HManagedComponent& component)
  64. {
  65. ScriptManagedComponent* nativeInstance = new (bs_alloc<ScriptManagedComponent>()) ScriptManagedComponent(existingInstance);
  66. nativeInstance->setNativeHandle(component);
  67. UINT64 instanceId = component->getInstanceId();
  68. mScriptComponents[instanceId] = nativeInstance;
  69. return nativeInstance;
  70. }
  71. ScriptComponentBase* ScriptGameObjectManager::createBuiltinScriptComponent(const HComponent& component)
  72. {
  73. UINT32 rttiId = component->getRTTI()->getRTTIId();
  74. BuiltinComponentInfo* info = ScriptAssemblyManager::instance().getBuiltinComponentInfo(rttiId);
  75. if (info == nullptr)
  76. return nullptr;
  77. ScriptComponentBase* nativeInstance = info->createCallback(component);
  78. nativeInstance->setNativeHandle(component);
  79. UINT64 instanceId = component->getInstanceId();
  80. mScriptComponents[instanceId] = nativeInstance;
  81. return nativeInstance;
  82. }
  83. ScriptComponentBase* ScriptGameObjectManager::getBuiltinScriptComponent(const HComponent& component)
  84. {
  85. ScriptComponentBase* scriptComponent = getScriptComponent(component.getInstanceId());
  86. if (scriptComponent != nullptr)
  87. return scriptComponent;
  88. return createBuiltinScriptComponent(component);
  89. }
  90. ScriptManagedComponent* ScriptGameObjectManager::getManagedScriptComponent(const HManagedComponent& component) const
  91. {
  92. auto findIter = mScriptComponents.find(component.getInstanceId());
  93. if (findIter != mScriptComponents.end())
  94. return static_cast<ScriptManagedComponent*>(findIter->second);
  95. return nullptr;
  96. }
  97. ScriptComponentBase* ScriptGameObjectManager::getScriptComponent(UINT64 instanceId) const
  98. {
  99. auto findIter = mScriptComponents.find(instanceId);
  100. if (findIter != mScriptComponents.end())
  101. return findIter->second;
  102. return nullptr;
  103. }
  104. ScriptSceneObject* ScriptGameObjectManager::getScriptSceneObject(const HSceneObject& sceneObject) const
  105. {
  106. auto findIter = mScriptSceneObjects.find(sceneObject.getInstanceId());
  107. if (findIter != mScriptSceneObjects.end())
  108. return findIter->second;
  109. return nullptr;
  110. }
  111. ScriptSceneObject* ScriptGameObjectManager::getScriptSceneObject(UINT64 instanceId) const
  112. {
  113. auto findIter = mScriptSceneObjects.find(instanceId);
  114. if (findIter != mScriptSceneObjects.end())
  115. return findIter->second;
  116. return nullptr;
  117. }
  118. ScriptGameObjectBase* ScriptGameObjectManager::getScriptGameObject(UINT64 instanceId) const
  119. {
  120. auto findIter = mScriptSceneObjects.find(instanceId);
  121. if (findIter != mScriptSceneObjects.end())
  122. return findIter->second;
  123. auto findIter2 = mScriptComponents.find(instanceId);
  124. if (findIter2 != mScriptComponents.end())
  125. return findIter2->second;
  126. return nullptr;
  127. }
  128. void ScriptGameObjectManager::destroyScriptSceneObject(ScriptSceneObject* sceneObject)
  129. {
  130. UINT64 instanceId = sceneObject->getNativeHandle().getInstanceId();
  131. mScriptSceneObjects.erase(instanceId);
  132. bs_delete(sceneObject);
  133. }
  134. void ScriptGameObjectManager::destroyScriptComponent(ScriptComponentBase* component)
  135. {
  136. UINT64 instanceId = component->getNativeHandle().getInstanceId();
  137. mScriptComponents.erase(instanceId);
  138. bs_delete(component);
  139. }
  140. void ScriptGameObjectManager::sendComponentResetEvents()
  141. {
  142. for (auto& scriptObjectEntry : mScriptComponents)
  143. {
  144. ScriptComponentBase* scriptComponent = scriptObjectEntry.second;
  145. HComponent component = scriptComponent->getComponent();
  146. if (component->getRTTI()->getRTTIId() == TID_ManagedComponent)
  147. {
  148. HManagedComponent managedComponent = static_object_cast<ManagedComponent>(component);
  149. if (!managedComponent.isDestroyed())
  150. managedComponent->triggerOnReset();
  151. }
  152. }
  153. }
  154. void ScriptGameObjectManager::onGameObjectDestroyed(const HGameObject& go)
  155. {
  156. UINT64 instanceId = go.getInstanceId();
  157. ScriptSceneObject* so = getScriptSceneObject(instanceId);
  158. if (so != nullptr)
  159. {
  160. so->_notifyDestroyed();
  161. mScriptSceneObjects.erase(instanceId);
  162. }
  163. ScriptComponentBase* component = getScriptComponent(instanceId);
  164. if(component != nullptr)
  165. {
  166. component->_notifyDestroyed();
  167. mScriptComponents.erase(instanceId);
  168. }
  169. }
  170. }