BsScriptGameObjectManager.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. #include "BsScriptGameObjectManager.h"
  2. #include "BsScriptGameObject.h"
  3. #include "BsScriptComponent.h"
  4. #include "BsScriptSceneObject.h"
  5. #include "BsGameObjectManager.h"
  6. #include "BsGameObject.h"
  7. #include "BsComponent.h"
  8. #include "BsManagedComponent.h"
  9. #include "BsSceneObject.h"
  10. #include "BsMonoManager.h"
  11. #include "BsMonoAssembly.h"
  12. #include "BsMonoClass.h"
  13. #include "BsScriptAssemblyManager.h"
  14. #include "BsScriptObjectManager.h"
  15. using namespace std::placeholders;
  16. namespace BansheeEngine
  17. {
  18. ScriptGameObjectManager::ScriptGameObjectEntry::ScriptGameObjectEntry()
  19. :instance(nullptr), isComponent(false)
  20. { }
  21. ScriptGameObjectManager::ScriptGameObjectEntry::ScriptGameObjectEntry(ScriptGameObjectBase* instance, bool isComponent)
  22. :instance(instance), isComponent(isComponent)
  23. { }
  24. ScriptGameObjectManager::ScriptGameObjectManager()
  25. {
  26. // Calls OnReset on all components after assembly reload happens
  27. mOnAssemblyReloadDoneConn = ScriptObjectManager::instance().onRefreshComplete.connect(
  28. std::bind(&ScriptGameObjectManager::sendComponentResetEvents, this));
  29. onGameObjectDestroyedConn = GameObjectManager::instance().onDestroyed.connect(
  30. std::bind(&ScriptGameObjectManager::onGameObjectDestroyed, this, _1));
  31. }
  32. ScriptGameObjectManager::~ScriptGameObjectManager()
  33. {
  34. mOnAssemblyReloadDoneConn.disconnect();
  35. onGameObjectDestroyedConn.disconnect();
  36. }
  37. ScriptSceneObject* ScriptGameObjectManager::getOrCreateScriptSceneObject(const HSceneObject& sceneObject)
  38. {
  39. ScriptSceneObject* so = getScriptSceneObject(sceneObject);
  40. if (so != nullptr)
  41. return so;
  42. return createScriptSceneObject(sceneObject);
  43. }
  44. ScriptSceneObject* ScriptGameObjectManager::createScriptSceneObject(const HSceneObject& sceneObject)
  45. {
  46. MonoClass* sceneObjectClass = ScriptAssemblyManager::instance().getSceneObjectClass();
  47. MonoObject* instance = sceneObjectClass->createInstance();
  48. return createScriptSceneObject(instance, sceneObject);
  49. }
  50. ScriptSceneObject* ScriptGameObjectManager::createScriptSceneObject(MonoObject* existingInstance, const HSceneObject& sceneObject)
  51. {
  52. ScriptSceneObject* so = getScriptSceneObject(sceneObject);
  53. if (so != nullptr)
  54. BS_EXCEPT(InvalidStateException, "Script object for this SceneObject already exists.");
  55. ScriptSceneObject* nativeInstance = new (bs_alloc<ScriptSceneObject>()) ScriptSceneObject(existingInstance, sceneObject);
  56. mScriptSceneObjects[sceneObject.getInstanceId()] = nativeInstance;
  57. return nativeInstance;
  58. }
  59. ScriptComponent* ScriptGameObjectManager::createScriptComponent(MonoObject* existingInstance, const GameObjectHandle<ManagedComponent>& component)
  60. {
  61. ScriptGameObjectBase* comp = getScriptComponent(component.getInstanceId());
  62. if (comp != nullptr)
  63. BS_EXCEPT(InvalidStateException, "Script object for this Component already exists.");
  64. ScriptComponent* nativeInstance = new (bs_alloc<ScriptComponent>()) ScriptComponent(existingInstance);
  65. nativeInstance->setNativeHandle(component);
  66. UINT64 instanceId = component->getInstanceId();
  67. mScriptComponents[instanceId] = nativeInstance;
  68. mUninitializedScriptComponents[instanceId] = nativeInstance;
  69. return nativeInstance;
  70. }
  71. ScriptComponent* ScriptGameObjectManager::getScriptComponent(const GameObjectHandle<ManagedComponent>& component) const
  72. {
  73. auto findIter = mScriptComponents.find(component.getInstanceId());
  74. if (findIter != mScriptComponents.end())
  75. return findIter->second;
  76. return nullptr;
  77. }
  78. ScriptComponent* ScriptGameObjectManager::getScriptComponent(UINT64 instanceId) const
  79. {
  80. auto findIter = mScriptComponents.find(instanceId);
  81. if (findIter != mScriptComponents.end())
  82. return findIter->second;
  83. return nullptr;
  84. }
  85. ScriptSceneObject* ScriptGameObjectManager::getScriptSceneObject(const HSceneObject& sceneObject) const
  86. {
  87. auto findIter = mScriptSceneObjects.find(sceneObject.getInstanceId());
  88. if (findIter != mScriptSceneObjects.end())
  89. return findIter->second;
  90. return nullptr;
  91. }
  92. ScriptSceneObject* ScriptGameObjectManager::getScriptSceneObject(UINT64 instanceId) const
  93. {
  94. auto findIter = mScriptSceneObjects.find(instanceId);
  95. if (findIter != mScriptSceneObjects.end())
  96. return findIter->second;
  97. return nullptr;
  98. }
  99. ScriptGameObjectBase* ScriptGameObjectManager::getScriptGameObject(UINT64 instanceId) const
  100. {
  101. auto findIter = mScriptSceneObjects.find(instanceId);
  102. if (findIter != mScriptSceneObjects.end())
  103. return findIter->second;
  104. auto findIter2 = mScriptComponents.find(instanceId);
  105. if (findIter2 != mScriptComponents.end())
  106. return findIter2->second;
  107. return nullptr;
  108. }
  109. void ScriptGameObjectManager::destroyScriptSceneObject(ScriptSceneObject* sceneObject)
  110. {
  111. UINT64 instanceId = sceneObject->getNativeHandle().getInstanceId();
  112. mScriptSceneObjects.erase(instanceId);
  113. bs_delete(sceneObject);
  114. }
  115. void ScriptGameObjectManager::destroyScriptComponent(ScriptComponent* component)
  116. {
  117. UINT64 instanceId = component->getNativeHandle().getInstanceId();
  118. mScriptComponents.erase(instanceId);
  119. mUninitializedScriptComponents(instanceId);
  120. bs_delete(component);
  121. }
  122. void ScriptGameObjectManager::notifyComponentInitialized(UINT64 instanceId)
  123. {
  124. mUninitializedScriptComponents.erase(instanceId);
  125. }
  126. void ScriptGameObjectManager::sendComponentResetEvents()
  127. {
  128. for (auto& scriptObjectEntry : mScriptComponents)
  129. {
  130. ScriptComponent* scriptComponent = scriptObjectEntry.second;
  131. HManagedComponent component = scriptComponent->getNativeHandle();
  132. component->triggerOnReset();
  133. }
  134. }
  135. void ScriptGameObjectManager::sendComponentInitializeEvents()
  136. {
  137. // Need to make a copy since successful calls will remove entries from mScriptComponents
  138. UnorderedMap<UINT64, ScriptComponent*> componentsToInitialize = mScriptComponents;
  139. for (auto& scriptObjectEntry : componentsToInitialize)
  140. {
  141. ScriptComponent* scriptComponent = scriptObjectEntry.second;
  142. HManagedComponent component = scriptComponent->getNativeHandle();
  143. component->triggerOnInitialize();
  144. }
  145. }
  146. void ScriptGameObjectManager::onGameObjectDestroyed(const HGameObject& go)
  147. {
  148. UINT64 instanceId = go.getInstanceId();
  149. ScriptSceneObject* so = getScriptSceneObject(instanceId);
  150. if (so == nullptr)
  151. return;
  152. so->_notifyDestroyed();
  153. mScriptSceneObjects.erase(instanceId);
  154. }
  155. }