BsScriptGameObjectManager.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. #include "BsScriptGameObjectManager.h"
  2. #include "BsScriptGameObject.h"
  3. #include "BsScriptComponent.h"
  4. #include "BsScriptSceneObject.h"
  5. #include "BsGameObject.h"
  6. #include "BsComponent.h"
  7. #include "BsManagedComponent.h"
  8. #include "BsSceneObject.h"
  9. #include "BsMonoManager.h"
  10. #include "BsMonoAssembly.h"
  11. #include "BsMonoClass.h"
  12. #include "BsScriptAssemblyManager.h"
  13. #include "BsScriptObjectManager.h"
  14. namespace BansheeEngine
  15. {
  16. ScriptGameObjectManager::ScriptGameObjectEntry::ScriptGameObjectEntry()
  17. :instance(nullptr), isComponent(false)
  18. { }
  19. ScriptGameObjectManager::ScriptGameObjectEntry::ScriptGameObjectEntry(ScriptGameObjectBase* instance, bool isComponent)
  20. :instance(instance), isComponent(isComponent)
  21. { }
  22. ScriptGameObjectManager::ScriptGameObjectManager()
  23. {
  24. // Calls OnReset on all components after assembly reload happens
  25. mOnAssemblyReloadDoneConn = ScriptObjectManager::instance().onRefreshComplete.connect(
  26. std::bind(&ScriptGameObjectManager::sendComponentResetEvents, this));
  27. }
  28. ScriptGameObjectManager::~ScriptGameObjectManager()
  29. {
  30. mOnAssemblyReloadDoneConn.disconnect();
  31. }
  32. ScriptSceneObject* ScriptGameObjectManager::getOrCreateScriptSceneObject(const HSceneObject& sceneObject)
  33. {
  34. Lock<> lock(mMutex);
  35. auto findIter = mScriptGameObjects.find(sceneObject.getInstanceId());
  36. if (findIter != mScriptGameObjects.end())
  37. return static_cast<ScriptSceneObject*>(findIter->second.instance);
  38. MonoClass* sceneObjectClass = ScriptAssemblyManager::instance().getSceneObjectClass();
  39. MonoObject* instance = sceneObjectClass->createInstance();
  40. ScriptSceneObject* nativeInstance = new (bs_alloc<ScriptSceneObject>()) ScriptSceneObject(instance, sceneObject);
  41. mScriptGameObjects[sceneObject.getInstanceId()] = ScriptGameObjectEntry(nativeInstance, false);
  42. return nativeInstance;
  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. Lock<> lock(mMutex);
  53. auto findIter = mScriptGameObjects.find(sceneObject.getInstanceId());
  54. if(findIter != mScriptGameObjects.end())
  55. BS_EXCEPT(InvalidStateException, "Script SceneObject for this SceneObject already exists.");
  56. ScriptSceneObject* nativeInstance = new (bs_alloc<ScriptSceneObject>()) ScriptSceneObject(existingInstance, sceneObject);
  57. mScriptGameObjects[sceneObject.getInstanceId()] = ScriptGameObjectEntry(nativeInstance, false);
  58. return nativeInstance;
  59. }
  60. ScriptComponent* ScriptGameObjectManager::createScriptComponent(MonoObject* existingInstance, const GameObjectHandle<ManagedComponent>& component)
  61. {
  62. Lock<> lock(mMutex);
  63. auto findIter = mScriptGameObjects.find(component->getInstanceId());
  64. if(findIter != mScriptGameObjects.end())
  65. BS_EXCEPT(InvalidStateException, "Script component for this Component already exists.");
  66. ScriptComponent* nativeInstance = new (bs_alloc<ScriptComponent>()) ScriptComponent(existingInstance);
  67. nativeInstance->setNativeHandle(component);
  68. mScriptGameObjects[component->getInstanceId()] = ScriptGameObjectEntry(nativeInstance, true);
  69. return nativeInstance;
  70. }
  71. ScriptComponent* ScriptGameObjectManager::getScriptComponent(const GameObjectHandle<ManagedComponent>& component) const
  72. {
  73. Lock<> lock(mMutex);
  74. auto findIter = mScriptGameObjects.find(component.getInstanceId());
  75. if(findIter != mScriptGameObjects.end())
  76. return static_cast<ScriptComponent*>(findIter->second.instance);
  77. return nullptr;
  78. }
  79. ScriptComponent* ScriptGameObjectManager::getScriptComponent(UINT64 instanceId) const
  80. {
  81. Lock<> lock(mMutex);
  82. auto findIter = mScriptGameObjects.find(instanceId);
  83. if (findIter != mScriptGameObjects.end())
  84. return static_cast<ScriptComponent*>(findIter->second.instance);
  85. return nullptr;
  86. }
  87. ScriptSceneObject* ScriptGameObjectManager::getScriptSceneObject(const HSceneObject& sceneObject) const
  88. {
  89. Lock<> lock(mMutex);
  90. auto findIter = mScriptGameObjects.find(sceneObject.getInstanceId());
  91. if(findIter != mScriptGameObjects.end())
  92. return static_cast<ScriptSceneObject*>(findIter->second.instance);
  93. return nullptr;
  94. }
  95. ScriptGameObjectBase* ScriptGameObjectManager::getScriptGameObject(UINT64 instanceId) const
  96. {
  97. Lock<> lock(mMutex);
  98. auto findIter = mScriptGameObjects.find(instanceId);
  99. if (findIter != mScriptGameObjects.end())
  100. return static_cast<ScriptSceneObject*>(findIter->second.instance);
  101. return nullptr;
  102. }
  103. void ScriptGameObjectManager::destroyScriptGameObject(ScriptGameObjectBase* gameObject)
  104. {
  105. Lock<> lock(mMutex);
  106. UINT64 idx = gameObject->getNativeHandle().getInstanceId();
  107. mScriptGameObjects.erase(idx);
  108. }
  109. void ScriptGameObjectManager::sendComponentResetEvents()
  110. {
  111. UnorderedMap<UINT64, ScriptGameObjectEntry> scriptGameObjects;
  112. {
  113. Lock<> lock(mMutex);
  114. scriptGameObjects = mScriptGameObjects;
  115. }
  116. for (auto& scriptObjectEntry : scriptGameObjects)
  117. {
  118. const ScriptGameObjectEntry& entry = scriptObjectEntry.second;
  119. if (!entry.isComponent)
  120. continue;
  121. ScriptComponent* scriptComponent = static_cast<ScriptComponent*>(entry.instance);
  122. HManagedComponent component = scriptComponent->getNativeHandle();
  123. component->triggerOnReset();
  124. }
  125. }
  126. }