BsScriptGameObjectManager.cpp 6.7 KB

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