From 15740faf9fe9fe4be08965098bbf2947e096aeeb Mon Sep 17 00:00:00 2001 From: chai Date: Wed, 14 Aug 2019 22:50:43 +0800 Subject: +Unity Runtime code --- Runtime/BaseClasses/ManagerContextLoading.cpp | 285 ++++++++++++++++++++++++++ 1 file changed, 285 insertions(+) create mode 100644 Runtime/BaseClasses/ManagerContextLoading.cpp (limited to 'Runtime/BaseClasses/ManagerContextLoading.cpp') diff --git a/Runtime/BaseClasses/ManagerContextLoading.cpp b/Runtime/BaseClasses/ManagerContextLoading.cpp new file mode 100644 index 0000000..76345d3 --- /dev/null +++ b/Runtime/BaseClasses/ManagerContextLoading.cpp @@ -0,0 +1,285 @@ +#include "UnityPrefix.h" +#include "ManagerContextLoading.h" +#include "Runtime/Profiler/Profiler.h" +#include "Runtime/Serialize/PersistentManager.h" +#include "Runtime/Serialize/SerializedFile.h" +#include "Runtime/Misc/GameObjectUtility.h" +#include "Runtime/BaseClasses/ManagerContext.h" +#include "Runtime/Serialize/AwakeFromLoadQueue.h" +#include "Runtime/BaseClasses/GameManager.h" +#include "Runtime/Utilities/vector_map.h" +#include "Runtime/Core/Callbacks/GlobalCallbacks.h" + + +PROFILER_INFORMATION(gCollectGameManagers, "CollectGameManagers", kProfilerLoading) + +void CollectLevelGameManagers (InstanceIDArray& outputObjects) +{ + PROFILER_AUTO(gCollectGameManagers,NULL); + const ManagerContext& context = GetManagerContext (); + for (int i=0;iIsPersistent ()); + DestroyObjectHighLevel (o); + } +} + + +/// Setup all managers to be called for a given mode. +/// When we're in edit mode, the Input, Dynamics, Fixed, Animation & Behaviour managers don't get +/// Updated. In Play mode, everything runs. +/// @param mode kPlayMode or kEditMode + + + +void RemoveDuplicateGameManagers () +{ + const ManagerContext& context = GetManagerContext (); + + for (int i=0;i managers; + Object::FindObjectsOfType (&managers); + + // Remove all managers that are not in the manager context! + for (int m=0;mIsPersistent ()); + ErrorString (Format("Removing duplicate game manager (%s)!", obj->GetClassName().c_str())); + FatalErrorIf (PPtr (managers[m])->IsPersistent ()); + DestroyObjectHighLevel (managers[m]); + } + } + + ErrorIf (Object::FindAllDerivedObjects (ClassID (GameManager), NULL) != ManagerContext::kManagerCount); +} + + +typedef vector_map ClassIDToInstanceID; +static void ExtractGlobalManagers (const std::string& path, ClassIDToInstanceID& managers) +{ + GetPersistentManager ().Lock(); + SerializedFile* stream = GetPersistentManager ().GetSerializedFileInternal(path); + if (stream == NULL) + { + GetPersistentManager ().Unlock(); + return; + } + + vector sourceFileIDs; + stream->GetAllFileIDs(&sourceFileIDs); + + for (int i=0;iGetClassID (fileID); + + if (Object::IsDerivedFromClassID (classID, ClassID (GlobalGameManager))) + { + SInt32 instanceID = GetPersistentManager().GetInstanceIDFromPathAndFileID (path, fileID); + managers.push_unsorted (classID, instanceID); + } + } + + managers.sort(); + + GetPersistentManager ().Unlock(); +} + +static Object* LoadManager (const ClassIDToInstanceID& managers, int classID) +{ + ClassIDToInstanceID::const_iterator i = managers.find(classID); + if (i == managers.end()) + return NULL; + + Object* obj = dynamic_instanceID_cast (i->second); + Assert(dynamic_pptr_cast (obj) != NULL); + + return obj; +} + + +string PlayerLoadSettingsAndInput(const std::string& dataFile) +{ + ClassIDToInstanceID managers; + ExtractGlobalManagers (dataFile, managers); + + ManagerContext::Managers loadManagers[] = + { + ManagerContext::kPlayerSettings, + ManagerContext::kInputManager, + ManagerContext::kBuildSettings, + ManagerContext::kGraphicsSettings, + ManagerContext::kQualitySettings, + }; + + const ManagerContext& ctx = GetManagerContext(); + for( int i = 0; i < sizeof(loadManagers)/sizeof(loadManagers[0]); ++i ) + { + int index = loadManagers[i]; + int classID = ctx.m_ManagerClassIDs[index]; + SetManagerPtrInContext(index, LoadManager(managers, classID)); + if (ctx.m_Managers[index] == NULL || !ctx.m_Managers[index]->IsDerivedFrom(classID)) + return Format("Could..... not preload global game manager #%i i=%i", index,i); + } + + return string(); +} + +string PlayerLoadGlobalManagers (const char* dataFile) +{ + ClassIDToInstanceID managers; + ExtractGlobalManagers (dataFile, managers); + + // Load all game managers! All global game managers are coming first in the main data + // (Global game managers have to be loaded before selecting the screen resolution. + // ProjectSettings i used by screen selector and RenderManager, InputManager by screen switching) + for (int i=0;i allManagers; + Object::FindObjectsOfType (&allManagers); + + for (int i=0;i specificManagers; + for (int j=0;jIsDerivedFrom(context.m_ManagerClassIDs[i])) + { + specificManagers.push_back(allManagers[j]); + } + } + + if (specificManagers.size () == 1) + SetManagerPtrInContext(i, specificManagers[0]); + else if (specificManagers.size () == 0) + { + // missing global managers are serious errors + if( i < ManagerContext::kGlobalManagerCount ) + error += " Missing " + Object::ClassIDToString (context.m_ManagerClassIDs[i]); + } + else + { + // missing global managers are serious errors + if( i < ManagerContext::kGlobalManagerCount ) + error += " Too many instances of " + Object::ClassIDToString (context.m_ManagerClassIDs[i]); + } + } + return error; +} + +void LoadManagers (AwakeFromLoadQueue& awakeFromLoadQueue) +{ + AwakeFromLoadMode awakeMode = (AwakeFromLoadMode)(kDidLoadFromDisk | kDidLoadThreaded); + + awakeFromLoadQueue.PersistentManagerAwakeFromLoad(kManagersQueue, awakeMode, NULL); + awakeFromLoadQueue.ClearQueue(kManagersQueue); + + // Get all managers that are in memory + map > managers; + vector temp; + Object::FindObjectsOfType (&temp); + for (int i=0;iGetClassID ()].insert (temp[i]); + + const ManagerContext& context = GetManagerContext(); + // Load the managers in the order defined by the context. + // Create new managers if necessary. + for (int i=0;i& manager = managers[context.m_ManagerClassIDs[i]]; + + if (manager.size () == 1) + SetManagerPtrInContext(i, *manager.begin ()); + else if (manager.size () == 0) + SetManagerPtrInContext(i, CreateGameManager (context.m_ManagerClassIDs[i])); + else + { + ErrorString("Multiple managers are loaded of type: " + Object::ClassIDToString(context.m_ManagerClassIDs[i])); + SetManagerPtrInContext(i, *manager.begin ()); + } + } +} -- cgit v1.1-26-g67d0