Пример #1
0
    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);
    }
Пример #2
0
        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);
        }
Пример #3
0
        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--;
            }
        }
Пример #4
0
        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();
        }
Пример #5
0
        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);
        }