GWorld = LoadedWorld; //特征 if (!LoadedWorld->bIsWorldInitialized) { LoadedWorld->InitWorld(); } bWorldChanged = true; // Track session change on seamless travel. NETWORK_PROFILER(GNetworkProfiler.TrackSessionChange(true, LoadedWorld->URL)); checkSlow((LoadedWorld->GetNetMode() == NM_Client) == bIsClient); if (bCreateNewGameMode) { LoadedWorld->SetGameMode(PendingTravelURL); } // if we've already switched to entry before and this is the transition to the new map, re-create the gameinfo if (bSwitchedToDefaultMap && !bIsClient) { if (FAudioDevice* AudioDevice = LoadedWorld->GetAudioDeviceRaw()) { AudioDevice->SetDefaultBaseSoundMix(LoadedWorld->GetWorldSettings()->DefaultBaseSoundMix); } // Copy cheat flags if the game info is present // @todo UE4 FIXMELH - see if this exists, it should not since it's created in GameMode or it's garbage info if (LoadedWorld->NetworkManager != nullptr) { LoadedWorld->NetworkManager->bHasStandbyCheatTriggered = bHasStandbyCheatTriggered; } } // Make sure "always loaded" sub-levels are fully loaded { SCOPE_LOG_TIME_IN_SECONDS(TEXT(" SeamlessTravel FlushLevelStreaming "), nullptr) //特征 LoadedWorld->FlushLevelStreaming(EFlushLevelStreamingType::Visibility); }
classUObject { /** virtual function table */ void* vtf; /** Flags used to track and report various object states. This needs to be 8 byte aligned on 32-bit platforms to reduce memory waste */ EObjectFlags ObjectFlags; /** Index into GObjectArray...very private. */ int32 InternalIndex; //表明该对象在GObjectArray中的第几个 /** Class the object belongs to. */ UClass* ClassPrivate; /** Name of this object */ FName NamePrivate; /** Object this object resides in. */ UObject* OuterPrivate; }
classFUObjectItem { // Pointer to the allocated object classUObjectBase* Object; // Internal flags int32 Flags; // UObject Owner Cluster Index int32 ClusterRootIndex; // Weak Object Pointer Serial number associated with the object int32 SerialNumber; } classTUObjectArray { enum { NumElementsPerChunk = 64 * 1024, }; /** Master table to chunks of pointers **/ FUObjectItem** Objects; /** If requested, a contiguous memory where all objects are allocated **/ FUObjectItem* PreAllocatedObjects; /** Maximum number of elements **/ int32 MaxElements; /** Number of elements we currently have **/ int32 NumElements; /** Maximum number of chunks **/ int32 MaxChunks; /** Number of chunks we currently have **/ int32 NumChunks; } classFUObjectArray { int32 ObjFirstGCIndex; /** Index pointing to last object created in range disregarded for GC. */ int32 ObjLastNonGCIndex; /** Maximum number of objects in the disregard for GC Pool */ int32 MaxObjectsNotConsideredByGC; /** If true this is the intial load and we should load objects int the disregarded for GC range. */ bool OpenForDisregardForGC; /** Array of all live objects. */ TUObjectArray ObjObjects; }