BsScriptObjectManager.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsScriptObjectManager.h"
  4. #include "BsScriptObject.h"
  5. #include "BsMonoManager.h"
  6. #include "Serialization/BsScriptAssemblyManager.h"
  7. #include "Scene/BsGameObjectManager.h"
  8. #include "BsMonoAssembly.h"
  9. namespace bs
  10. {
  11. ScriptObjectManager::ScriptObjectManager()
  12. :mFinalizedQueueIdx(0)
  13. {
  14. }
  15. ScriptObjectManager::~ScriptObjectManager()
  16. {
  17. processFinalizedObjects();
  18. }
  19. void ScriptObjectManager::registerScriptObject(ScriptObjectBase* instance)
  20. {
  21. mScriptObjects.insert(instance);
  22. }
  23. void ScriptObjectManager::unregisterScriptObject(ScriptObjectBase* instance)
  24. {
  25. mScriptObjects.erase(instance);
  26. }
  27. void ScriptObjectManager::refreshAssemblies(const Vector<std::pair<String, Path>>& assemblies)
  28. {
  29. Map<ScriptObjectBase*, ScriptObjectBackup> backupData;
  30. onRefreshStarted();
  31. // Make sure any managed game objects are properly destroyed so their OnDestroy callbacks fire before unloading the domain
  32. GameObjectManager::instance().destroyQueuedObjects();
  33. for (auto& scriptObject : mScriptObjects)
  34. backupData[scriptObject] = scriptObject->beginRefresh();
  35. MonoManager::instance().unloadScriptDomain();
  36. // Unload script domain should trigger finalizers on everything, but since we usually delay
  37. // their processing we need to manually trigger it here.
  38. processFinalizedObjects();
  39. for (auto& scriptObject : mScriptObjects)
  40. assert(scriptObject->isPersistent() && "Non-persistent ScriptObject alive after domain unload.");
  41. for (auto& scriptObject : mScriptObjects)
  42. scriptObject->_clearManagedInstance();
  43. ScriptAssemblyManager::instance().clearAssemblyInfo();
  44. for (auto& assemblyPair : assemblies)
  45. {
  46. MonoManager::instance().loadAssembly(assemblyPair.second.toWString(), assemblyPair.first);
  47. ScriptAssemblyManager::instance().loadAssemblyInfo(assemblyPair.first);
  48. }
  49. Vector<ScriptObjectBase*> scriptObjCopy(mScriptObjects.size()); // Store originals as we could add new objects during the next iteration
  50. UINT32 idx = 0;
  51. for (auto& scriptObject : mScriptObjects)
  52. scriptObjCopy[idx++] = scriptObject;
  53. onRefreshDomainLoaded();
  54. for (auto& scriptObject : scriptObjCopy)
  55. scriptObject->_restoreManagedInstance();
  56. for (auto& scriptObject : scriptObjCopy)
  57. scriptObject->endRefresh(backupData[scriptObject]);
  58. onRefreshComplete();
  59. }
  60. void ScriptObjectManager::notifyObjectFinalized(ScriptObjectBase* instance)
  61. {
  62. assert(instance != nullptr);
  63. Lock lock(mMutex);
  64. mFinalizedObjects[mFinalizedQueueIdx].push_back(instance);
  65. }
  66. void ScriptObjectManager::update()
  67. {
  68. processFinalizedObjects();
  69. }
  70. void ScriptObjectManager::processFinalizedObjects()
  71. {
  72. UINT32 readQueueIdx = 0;
  73. {
  74. Lock lock(mMutex);
  75. readQueueIdx = mFinalizedQueueIdx;
  76. mFinalizedQueueIdx = (mFinalizedQueueIdx + 1) % 2;
  77. }
  78. for (auto& finalizedObj : mFinalizedObjects[readQueueIdx])
  79. finalizedObj->_onManagedInstanceDeleted();
  80. mFinalizedObjects[readQueueIdx].clear();
  81. }
  82. }