| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
- //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
- #include "BsScriptObjectManager.h"
- #include "BsScriptObject.h"
- #include "BsMonoManager.h"
- #include "Serialization/BsScriptAssemblyManager.h"
- #include "Scene/BsGameObjectManager.h"
- #include "BsMonoAssembly.h"
- namespace bs
- {
- ScriptObjectManager::ScriptObjectManager()
- :mFinalizedQueueIdx(0)
- {
- }
- ScriptObjectManager::~ScriptObjectManager()
- {
- processFinalizedObjects();
- }
- void ScriptObjectManager::registerScriptObject(ScriptObjectBase* instance)
- {
- mScriptObjects.insert(instance);
- }
- void ScriptObjectManager::unregisterScriptObject(ScriptObjectBase* instance)
- {
- mScriptObjects.erase(instance);
- }
- void ScriptObjectManager::refreshAssemblies(const Vector<std::pair<String, Path>>& assemblies)
- {
- Map<ScriptObjectBase*, ScriptObjectBackup> backupData;
- onRefreshStarted();
- // Make sure any managed game objects are properly destroyed so their OnDestroy callbacks fire before unloading the domain
- GameObjectManager::instance().destroyQueuedObjects();
- for (auto& scriptObject : mScriptObjects)
- backupData[scriptObject] = scriptObject->beginRefresh();
- for (auto& scriptObject : mScriptObjects)
- scriptObject->_clearManagedInstance();
- MonoManager::instance().unloadScriptDomain();
- // Unload script domain should trigger finalizers on everything, but since we usually delay
- // their processing we need to manually trigger it here.
- processFinalizedObjects(true);
- for (auto& scriptObject : mScriptObjects)
- assert(scriptObject->isPersistent() && "Non-persistent ScriptObject alive after domain unload.");
- ScriptAssemblyManager::instance().clearAssemblyInfo();
- for (auto& assemblyPair : assemblies)
- {
- MonoManager::instance().loadAssembly(assemblyPair.second.toWString(), assemblyPair.first);
- ScriptAssemblyManager::instance().loadAssemblyInfo(assemblyPair.first);
- }
- Vector<ScriptObjectBase*> scriptObjCopy(mScriptObjects.size()); // Store originals as we could add new objects during the next iteration
- UINT32 idx = 0;
- for (auto& scriptObject : mScriptObjects)
- scriptObjCopy[idx++] = scriptObject;
- onRefreshDomainLoaded();
- for (auto& scriptObject : scriptObjCopy)
- scriptObject->_restoreManagedInstance();
- for (auto& scriptObject : scriptObjCopy)
- scriptObject->endRefresh(backupData[scriptObject]);
- onRefreshComplete();
- }
- void ScriptObjectManager::notifyObjectFinalized(ScriptObjectBase* instance)
- {
- assert(instance != nullptr);
- Lock lock(mMutex);
- mFinalizedObjects[mFinalizedQueueIdx].push_back(instance);
- }
- void ScriptObjectManager::update()
- {
- processFinalizedObjects();
- }
- void ScriptObjectManager::processFinalizedObjects(bool assemblyRefresh)
- {
- UINT32 readQueueIdx = 0;
- {
- Lock lock(mMutex);
- readQueueIdx = mFinalizedQueueIdx;
- mFinalizedQueueIdx = (mFinalizedQueueIdx + 1) % 2;
- }
-
- for (auto& finalizedObj : mFinalizedObjects[readQueueIdx])
- finalizedObj->_onManagedInstanceDeleted(assemblyRefresh);
- mFinalizedObjects[readQueueIdx].clear();
- }
- }
|