public virtual ICodecService CreateCodecService(string codecsPath, string schemaFileName) { var _codecService = new CodecService(schemaFileName); var result = _codecService.LoadXmlCodecs(codecsPath); if (result.Value is MagitekResults.Failed fail) { _logger.LogError(string.Join(Environment.NewLine, fail.Reasons)); } return(_codecService); }
public static bool WriteWorldToFile(World world, FileInfo outputFile) { // TODO need to bring this back #if false // Check for missing assembly references var unresolvedComponentTypes = GetAllUsedComponentTypes(world).Where(t => !DomainCache.IsIncludedInProject(project, t.GetManagedType())).ToArray(); if (unresolvedComponentTypes.Length > 0) { foreach (var unresolvedComponentType in unresolvedComponentTypes) { var type = unresolvedComponentType.GetManagedType(); Debug.LogError($"Could not resolve component type '{type.FullName}' while exporting {scenePath.ToHyperLink()}. Are you missing an assembly reference to '{type.Assembly.GetName().Name}' ?"); } return(false); } #endif var directoryName = Path.GetDirectoryName(outputFile.FullName); if (string.IsNullOrEmpty(directoryName)) { throw new ArgumentException($"Invalid output file directory: {directoryName}", nameof(outputFile)); } if (!Directory.Exists(directoryName)) { Directory.CreateDirectory(directoryName); } // Merges the entities and shared component streams, (optionally) compresses them, and finally serializes to disk with a small header in front using (var fileStream = new StreamBinaryWriter(outputFile.FullName)) using (var entitiesWriter = new MemoryBinaryWriter()) { var entityRemapInfos = new NativeArray <EntityRemapUtility.EntityRemapInfo>(world.EntityManager.EntityCapacity, Allocator.Temp); SerializeUtility.SerializeWorldInternal(world.EntityManager, entitiesWriter, out var referencedObjects, entityRemapInfos, isDOTSRuntime: true); entityRemapInfos.Dispose(); if (referencedObjects != null) { throw new ArgumentException("We are serializing a world that contains UnityEngine.Object references which are not supported in Dots Runtime."); } #if TINY_SCENE_DEP unsafe { var worldHeader = new SceneHeader(); worldHeader.DecompressedSize = entitiesWriter.Length; worldHeader.Codec = Codec.LZ4; worldHeader.SerializeHeader(fileStream); if (worldHeader.Codec != Codec.None) { int compressedSize = CodecService.Compress(worldHeader.Codec, entitiesWriter.Data, entitiesWriter.Length, out var compressedData); fileStream.WriteBytes(compressedData, compressedSize); } else { fileStream.WriteBytes(entitiesWriter.Data, entitiesWriter.Length); } } #endif } return(true); }
protected override unsafe void OnUpdate() { { var ecb = new EntityCommandBuffer(Allocator.Temp); Entities .WithAll <SceneData, RequestSceneLoaded>() .WithNone <SceneLoadRequest>() .ForEach((Entity e) => { if (m_currentRequestTotal >= kMaxRequestsInFlight) { return; } var sceneData = EntityManager.GetComponentData <SceneData>(e); var sceneGuid = sceneData.Scene.SceneGuid; var path = "Data/" + sceneGuid.Guid.ToString("N"); // Fire async reads for scene data SceneLoadRequest request = new SceneLoadRequest(); request.SceneOpHandle = IOService.RequestAsyncRead(path); ecb.AddComponent(e, request); ecb.RemoveComponent <RequestSceneLoaded>(e); sceneData.Status = SceneStatus.Loading; ecb.SetComponent(e, sceneData); m_currentRequestTotal++; }); ecb.Playback(EntityManager); ecb.Dispose(); } if (m_PendingRequestsQuery.CalculateLength() > 0) { var ecb = new EntityCommandBuffer(Allocator.Temp); var pendingRequests = m_PendingRequestsQuery.ToEntityArray(Allocator.Temp); Entity requestEntity = pendingRequests[0]; SceneData sceneData = EntityManager.GetComponentData <SceneData>(requestEntity); SceneLoadRequest request = EntityManager.GetComponentData <SceneLoadRequest>(requestEntity); var opStatus = request.SceneOpHandle.GetStatus(); if (opStatus <= Status.InProgress) { ecb.Playback(EntityManager); ecb.Dispose(); return; } if (opStatus == Status.Failure) { request.SceneOpHandle.Dispose(); ecb.RemoveComponent <SceneLoadRequest>(requestEntity); sceneData.Status = SceneStatus.FailedToLoad; ecb.SetComponent(requestEntity, sceneData); ecb.Playback(EntityManager); ecb.Dispose(); m_currentRequestTotal--; return; } Assert.IsTrue(opStatus == Status.Success); request.SceneOpHandle.GetData(out var data, out var sceneDataSize); SceneHeader header = *(SceneHeader *)data; int headerSize = UnsafeUtility.SizeOf <SceneHeader>(); if (header.Version != SceneHeader.CurrentVersion) { throw new Exception($"Scene serialization version mismatch. Reading version '{header.Version}', expected '{SceneHeader.CurrentVersion}'"); } byte *decompressedScene = data + headerSize; if (header.Codec != Codec.Codec.None) { decompressedScene = (byte *)UnsafeUtility.Malloc(header.DecompressedSize, 16, Allocator.Temp); if (!CodecService.Decompress(header.Codec, data + headerSize, sceneDataSize - headerSize, decompressedScene, header.DecompressedSize)) { throw new Exception($"Failed to decompress compressed scene using codec '{header.Codec}'"); } } using (var sceneReader = new MemoryBinaryReader(decompressedScene)) { var loadingEM = m_LoadingWorld.EntityManager; var transaction = loadingEM.BeginExclusiveEntityTransaction(); if (header.SharedComponentCount > 0) { int numSharedComponentsLoaded = SerializeUtility.DeserializeSharedComponents(loadingEM, sceneReader); // Chunks have now taken over ownership of the shared components (reference counts have been added) // so remove the ref that was added on deserialization for (int i = 0; i < numSharedComponentsLoaded; ++i) { transaction.ManagedComponentStore.RemoveReference(i + 1); } Assert.IsTrue(numSharedComponentsLoaded == header.SharedComponentCount, $"Number of loaded SharedComponents for '{sceneData.Scene.SceneGuid.Guid}' loaded ({numSharedComponentsLoaded }) does not match what we expect ({header.SharedComponentCount})"); } SerializeUtility.DeserializeWorld(transaction, sceneReader, header.SharedComponentCount); loadingEM.EndExclusiveEntityTransaction(); } var scene = sceneData.Scene; World.Active.EntityManager.MoveEntitiesFrom(out var movedEntities, m_LoadingWorld.EntityManager); foreach (var e in movedEntities) { World.Active.EntityManager.AddSharedComponentData(e, scene.SceneGuid); World.Active.EntityManager.AddSharedComponentData(e, scene.SceneInstanceId); } // Fixup Entity references now that the entities have moved EntityManager.World.GetOrCreateSystem <EntityReferenceRemapSystem>().Update(); EntityManager.World.GetOrCreateSystem <RemoveRemapInformationSystem>().Update(); if (header.Codec != Codec.Codec.None) { UnsafeUtility.Free(decompressedScene, Allocator.Temp); } sceneData.Status = SceneStatus.Loaded; ecb.SetComponent(requestEntity, sceneData); ecb.AddSharedComponent(requestEntity, scene.SceneGuid); ecb.AddSharedComponent(requestEntity, scene.SceneInstanceId); request.SceneOpHandle.Dispose(); ecb.RemoveComponent <SceneLoadRequest>(requestEntity); ecb.Playback(EntityManager); ecb.Dispose(); m_LoadingWorld.EntityManager.PrepareForDeserialize(); movedEntities.Dispose(); pendingRequests.Dispose(); m_currentRequestTotal--; } }
protected override unsafe void OnUpdate() { var ecb = new EntityCommandBuffer(Allocator.TempJob); Entities .WithAll <SceneData, RequestSceneLoaded>() .WithNone <SceneLoadRequest>() .ForEach((Entity e) => { var sceneData = EntityManager.GetComponentData <SceneData>(e); var sceneGuid = sceneData.Scene.SceneGuid; var path = DataRootPath + sceneGuid.Guid.ToString("N"); #if IO_ENABLE_TRACE Debug.Log($"SceneStreamingSystem: starting load for {DebugSceneGuid(sceneData)} from {path}"); #endif // Fire async reads for scene data SceneLoadRequest request = new SceneLoadRequest(); request.SceneOpHandle = IOService.RequestAsyncRead(path); ecb.AddComponent(e, request); ecb.RemoveComponent <RequestSceneLoaded>(e); sceneData.Status = SceneStatus.Loading; ecb.SetComponent(e, sceneData); }); ecb.Playback(EntityManager); ecb.Dispose(); var pendingRequests = m_PendingRequestsQuery.ToEntityArray(Allocator.TempJob); ecb = new EntityCommandBuffer(Allocator.TempJob); foreach (var requestEntity in pendingRequests) { SceneData sceneData = EntityManager.GetComponentData <SceneData>(requestEntity); SceneLoadRequest request = EntityManager.GetComponentData <SceneLoadRequest>(requestEntity); var opStatus = request.SceneOpHandle.GetStatus(); if (opStatus <= Status.InProgress) { continue; } if (opStatus == Status.Failure) { request.SceneOpHandle.Dispose(); ecb.RemoveComponent <SceneLoadRequest>(requestEntity); Debug.Log($"SceneStreamingSystem: Failed to load {DebugSceneGuid(sceneData)}"); sceneData.Status = SceneStatus.FailedToLoad; ecb.SetComponent(requestEntity, sceneData); continue; } Assert.IsTrue(opStatus == Status.Success); request.SceneOpHandle.GetData(out var data, out var sceneDataSize); SceneHeader header = *(SceneHeader *)data; int headerSize = UnsafeUtility.SizeOf <SceneHeader>(); if (header.Version != SceneHeader.CurrentVersion) { throw new Exception($"Scene serialization version mismatch in {DebugSceneGuid(sceneData)}. Reading version '{header.Version}', expected '{SceneHeader.CurrentVersion}'"); } byte *decompressedScene = data + headerSize; if (header.Codec != Codec.Codec.None) { decompressedScene = (byte *)UnsafeUtility.Malloc(header.DecompressedSize, 16, Allocator.Temp); if (!CodecService.Decompress(header.Codec, data + headerSize, sceneDataSize - headerSize, decompressedScene, header.DecompressedSize)) { throw new Exception($"Failed to decompress compressed scene {DebugSceneGuid(sceneData)} using codec '{header.Codec}'"); } } using (var sceneReader = new MemoryBinaryReader(decompressedScene)) { var loadingEM = m_LoadingWorld.EntityManager; var transaction = loadingEM.BeginExclusiveEntityTransaction(); SerializeUtility.DeserializeWorld(transaction, sceneReader); loadingEM.EndExclusiveEntityTransaction(); } var scene = sceneData.Scene; var activeEM = EntityManager; activeEM.MoveEntitiesFrom(out var movedEntities, m_LoadingWorld.EntityManager); foreach (var e in movedEntities) { ecb.AddSharedComponent(e, scene.SceneGuid); ecb.AddSharedComponent(e, scene.SceneInstanceId); } // Fixup Entity references now that the entities have moved EntityManager.World.GetExistingSystem <EntityReferenceRemapSystem>().Update(); EntityManager.World.GetExistingSystem <RemoveRemapInformationSystem>().Update(); if (header.Codec != Codec.Codec.None) { UnsafeUtility.Free(decompressedScene, Allocator.Temp); } #if IO_ENABLE_TRACE Debug.Log($"SceneStreamingSystem: Loaded scene {DebugSceneGuid(sceneData)}"); #endif sceneData.Status = SceneStatus.Loaded; ecb.SetComponent(requestEntity, sceneData); request.SceneOpHandle.Dispose(); ecb.RemoveComponent <SceneLoadRequest>(requestEntity); m_LoadingWorld.EntityManager.PrepareForDeserialize(); movedEntities.Dispose(); } ecb.Playback(EntityManager); ecb.Dispose(); pendingRequests.Dispose(); }
private static bool ExportWorld(FileInfo outputFile, Project project, string scenePath, World world, bool performConversion = true) { if (performConversion) { SceneConversion.Convert(world); } // Null out any references to avoid the SerializeUtility from trying to patch asset entities. world.GetOrCreateSystem <ClearRemappedEntityReferenceSystem>().Update(); // Check for missing assembly references var unresolvedComponentTypes = GetAllUsedComponentTypes(world).Where(t => !DomainCache.IsIncludedInProject(project, t.GetManagedType())).ToArray(); if (unresolvedComponentTypes.Length > 0) { foreach (var unresolvedComponentType in unresolvedComponentTypes) { var type = unresolvedComponentType.GetManagedType(); Debug.LogError($"Could not resolve component type '{type.FullName}' while exporting {scenePath.HyperLink()}. Are you missing an assembly reference to '{type.Assembly.GetName().Name}' ?"); } return(false); } // Remove non-exported components var nonExportedComponentTypes = UnityEditor.TypeCache.GetTypesWithAttribute <NonExportedAttribute>().Select(t => new ComponentType(t)); world.EntityManager.RemoveComponent(world.EntityManager.UniversalQuery, new ComponentTypes(nonExportedComponentTypes.ToArray())); // Merges the entities and shared component streams, (optionally) compresses them, and finally serializes to disk with a small header in front using (var fileStream = new StreamBinaryWriter(outputFile.FullName)) using (var entitiesWriter = new MemoryBinaryWriter()) using (var sharedComponentWriter = new MemoryBinaryWriter()) using (var combinedDataWriter = new MemoryBinaryWriter()) { SerializeUtility.SerializeWorld(world.EntityManager, entitiesWriter, out var sharedComponentsToSerialize); if (sharedComponentsToSerialize.Length > 0) { SerializeUtility.SerializeSharedComponents(world.EntityManager, sharedComponentWriter, sharedComponentsToSerialize); } unsafe { combinedDataWriter.WriteBytes(sharedComponentWriter.Data, sharedComponentWriter.Length); combinedDataWriter.WriteBytes(entitiesWriter.Data, entitiesWriter.Length); var worldHeader = new SceneHeader(); worldHeader.SharedComponentCount = sharedComponentsToSerialize.Length; worldHeader.DecompressedSize = entitiesWriter.Length + sharedComponentWriter.Length; worldHeader.Codec = Codec.LZ4; worldHeader.SerializeHeader(fileStream); if (worldHeader.Codec != Codec.None) { int compressedSize = CodecService.Compress(worldHeader.Codec, combinedDataWriter.Data, combinedDataWriter.Length, out var compressedData); fileStream.WriteBytes(compressedData, compressedSize); } else { fileStream.WriteBytes(combinedDataWriter.Data, combinedDataWriter.Length); } } } return(true); }