void ResolveScene(Entity sceneEntity, ref SceneReference scene, RequestSceneLoaded requestSceneLoaded, Hash128 artifactHash) { // Resolve first (Even if the file doesn't exist we want to stop continously trying to load the section) EntityManager.AddBuffer <ResolvedSectionEntity>(sceneEntity); EntityManager.AddComponentData(sceneEntity, new ResolvedSceneHash { ArtifactHash = artifactHash }); var sceneHeaderPath = EntityScenesPaths.GetLiveLinkCachePath(artifactHash, EntityScenesPaths.PathType.EntitiesHeader, -1); if (!File.Exists(sceneHeaderPath)) { Debug.LogError($"Loading Entity Scene failed because the entity header file could not be found: {scene.SceneGUID}\n{sceneHeaderPath}"); return; } if (!BlobAssetReference <SceneMetaData> .TryRead(sceneHeaderPath, SceneMetaDataSerializeUtility.CurrentFileFormatVersion, out var sceneMetaDataRef)) { Debug.LogError("Loading Entity Scene failed because the entity header file was an old version: " + scene.SceneGUID); return; } LogResolving("ResolveScene (success)", scene.SceneGUID); ref var sceneMetaData = ref sceneMetaDataRef.Value;
//TODO: There is too much code duplication here, refactor this to receive general artifacts from the editor unsafe void ReceiveSubSceneRefGUIDs(MessageEventArgs args) { fixed(byte *ptr = args.data) { var reader = new UnsafeAppendBuffer.Reader(ptr, args.data.Length); var subSceneAsset = reader.ReadNext <ResolvedSubSceneID>(); var sectionIndex = reader.ReadNext <int>(); reader.ReadNext(out NativeArray <RuntimeGlobalObjectId> objRefGUIDs, Allocator.Persistent); var refObjGUIDsPath = EntityScenesPaths.GetLiveLinkCachePath(subSceneAsset.TargetHash, EntityScenesPaths.PathType.EntitiesUnityObjectReferences, sectionIndex); // Not printing error because this can happen when running the same player multiple times on the same machine if (File.Exists(refObjGUIDsPath)) { LiveLinkMsg.LogInfo($"Received {subSceneAsset.SubSceneGUID} | {subSceneAsset.TargetHash} but it already exists on disk"); } else { LiveLinkMsg.LogInfo($"ReceieveSubSceneRefGUIDs => {subSceneAsset.SubSceneGUID} | {subSceneAsset.TargetHash},"); var tempCachePath = GetTempCachePath(); using (var writer = new StreamBinaryWriter(tempCachePath)) { writer.Write(objRefGUIDs.Length); writer.WriteArray(objRefGUIDs); } try { File.Move(tempCachePath, refObjGUIDsPath); } catch (Exception e) { File.Delete(tempCachePath); if (!File.Exists(refObjGUIDsPath)) { Debug.LogError($"Failed to move temporary file. Exception: {e.Message}"); LiveLinkMsg.LogInfo($"Failed to move temporary file. Exception: {e.Message}"); } } } if (!_WaitingForSubScenes.ContainsKey(subSceneAsset.SubSceneGUID)) { Debug.LogError($"Received {subSceneAsset.SubSceneGUID} | {subSceneAsset.TargetHash} without requesting it"); LiveLinkMsg.LogInfo($"Received {subSceneAsset.SubSceneGUID} | {subSceneAsset.TargetHash} without requesting it"); return; } var waitingSubScene = _WaitingForSubScenes[subSceneAsset.SubSceneGUID]; waitingSubScene.SubSections.Add(objRefGUIDs); _WaitingForSubScenes[subSceneAsset.SubSceneGUID] = waitingSubScene; } }
unsafe void ReceiveResponseSubSceneTargetHash(MessageEventArgs args) { using (var subSceneAssets = args.ReceiveArray <ResolvedSubSceneID>()) { foreach (var subSceneAsset in subSceneAssets) { if (_WaitingForSubScenes.ContainsKey(subSceneAsset.SubSceneGUID)) { return; } var headerPath = EntityScenesPaths.GetLiveLinkCachePath(subSceneAsset.TargetHash, EntityScenesPaths.PathType.EntitiesHeader, -1); if (File.Exists(headerPath)) { LiveLinkMsg.LogInfo($"ReceiveResponseSubSceneTargetHash => {subSceneAsset.SubSceneGUID} | {subSceneAsset.TargetHash}, File.Exists => 'True', {Path.GetFullPath(headerPath)}"); //TODO: This is a hack to make sure assets are managed by asset manifest when loading from cache for first run if (!BlobAssetReference <SceneMetaData> .TryRead(headerPath, SceneMetaDataSerializeUtility.CurrentFileFormatVersion, out var sceneMetaDataRef)) { Debug.LogError("Loading Entity Scene failed because the entity header file was an old version: " + subSceneAsset.SubSceneGUID); return; } ref var sceneMetaData = ref sceneMetaDataRef.Value; var waitingSubScene = new WaitingSubScene { TargetHash = subSceneAsset.TargetHash, SubSections = new List <NativeArray <RuntimeGlobalObjectId> >(), SubSectionCount = sceneMetaData.Sections.Length }; for (int i = 0; i < sceneMetaData.Sections.Length; i++) { if (sceneMetaData.Sections[i].ObjectReferenceCount != 0) { var refObjGUIDsPath = EntityScenesPaths.GetLiveLinkCachePath(subSceneAsset.TargetHash, EntityScenesPaths.PathType.EntitiesUnityObjectReferences, i); using (var reader = new StreamBinaryReader(refObjGUIDsPath)) { var numObjRefGUIDs = reader.ReadInt(); NativeArray <RuntimeGlobalObjectId> objRefGUIDs = new NativeArray <RuntimeGlobalObjectId>(numObjRefGUIDs, Allocator.Persistent); reader.ReadArray(objRefGUIDs, numObjRefGUIDs); waitingSubScene.SubSections.Add(objRefGUIDs); } } else { waitingSubScene.SubSections.Add(new NativeArray <RuntimeGlobalObjectId>(0, Allocator.Persistent)); } } _WaitingForSubScenes[subSceneAsset.SubSceneGUID] = waitingSubScene; }
unsafe void ReceiveSubSceneHeader(MessageEventArgs args) { fixed(byte *ptr = args.data) { var reader = new UnsafeAppendBuffer.Reader(ptr, args.data.Length); var subSceneAsset = reader.ReadNext <ResolvedSubSceneID>(); var subSectionCount = reader.ReadNext <int>(); var headerPath = EntityScenesPaths.GetLiveLinkCachePath(subSceneAsset.TargetHash, EntityScenesPaths.PathType.EntitiesHeader, -1); // Not printing error because this can happen when running the same player multiple times on the same machine if (File.Exists(headerPath)) { LiveLinkMsg.LogInfo($"Received {subSceneAsset.SubSceneGUID} | {subSceneAsset.TargetHash} but it already exists on disk"); } else { var tempCachePath = GetTempCachePath(); LiveLinkMsg.LogInfo($"ReceiveSubSceneHeader => {subSceneAsset.SubSceneGUID} | {subSceneAsset.TargetHash}, '{tempCachePath}' => '{headerPath}'"); var stream = File.OpenWrite(tempCachePath); stream.Write(args.data, reader.Offset, args.data.Length - reader.Offset); stream.Close(); stream.Dispose(); try { File.Move(tempCachePath, headerPath); } catch (Exception e) { File.Delete(tempCachePath); if (!File.Exists(headerPath)) { Debug.LogError($"Failed to move temporary file. Exception: {e.Message}"); LiveLinkMsg.LogInfo($"Failed to move temporary file. Exception: {e.Message}"); } } } if (!_WaitingForSubScenes.ContainsKey(subSceneAsset.SubSceneGUID)) { Debug.LogError($"Received {subSceneAsset.SubSceneGUID} | {subSceneAsset.TargetHash} without requesting it"); LiveLinkMsg.LogInfo($"Received {subSceneAsset.SubSceneGUID} | {subSceneAsset.TargetHash} without requesting it"); return; } var waitingSubScene = _WaitingForSubScenes[subSceneAsset.SubSceneGUID]; waitingSubScene.TargetHash = subSceneAsset.TargetHash; waitingSubScene.SubSectionCount = subSectionCount; _WaitingForSubScenes[subSceneAsset.SubSceneGUID] = waitingSubScene; } }