BsScriptObjectManager.cpp 2.7 KB

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