//@TODO: Support some sort of transaction like API so we can reload all changed things in batch.
        unsafe void ReceiveAssetBundle(MessageEventArgs args)
        {
            LiveLinkMsg.LogReceived($"AssetBundle: '{args.data.Length}' bytes");

            fixed(byte *ptr = args.data)
            {
                var reader = new UnsafeAppendBuffer.Reader(ptr, args.data.Length);
                var asset  = reader.ReadNext <ResolvedAssetID>();

                var assetBundleCachePath = GetCachePath(asset.TargetHash);
                var tempCachePath        = GetTempCachePath();

                // cache: look up asset by target hash to see if the version we want is already on the target device

                //if we already have the asset bundle revision we want, then just put that in the resolver as the active revision of the asset
                // cache: if not in cache, write actual file to Application.persistentDatapath
                var stream = File.OpenWrite(tempCachePath);

                stream.Write(args.data, reader.Offset, args.data.Length - reader.Offset);
                stream.Close();
                stream.Dispose();

                LiveLinkMsg.LogInfo($"ReceiveAssetBundle => {asset.GUID} | {asset.TargetHash}, '{tempCachePath}' => '{assetBundleCachePath}'");

                if (File.Exists(assetBundleCachePath))
                {
                    Debug.LogError($"Received {asset.GUID} | {asset.TargetHash} but it already exists on disk");
                    LiveLinkMsg.LogInfo($"Received {asset.GUID} | {asset.TargetHash} but it already exists on disk");
                    File.Delete(tempCachePath);
                }
                else
                {
                    try
                    {
                        File.Move(tempCachePath, assetBundleCachePath);
                    }
                    catch (Exception e)
                    {
                        File.Delete(tempCachePath);
                        if (!File.Exists(assetBundleCachePath))
                        {
                            Debug.LogError($"Failed to move temporary file. Exception: {e.Message}");
                            LiveLinkMsg.LogInfo($"Failed to move temporary file. Exception: {e.Message}");
                        }
                    }
                }


                if (!_WaitingForAssets.ContainsKey(asset.GUID))
                {
                    Debug.LogError($"Received {asset.GUID} | {asset.TargetHash} without requesting it");
                    LiveLinkMsg.LogInfo($"Received {asset.GUID} | {asset.TargetHash} without requesting it");
                }

                _WaitingForAssets[asset.GUID] = asset.TargetHash;
            }
        }
コード例 #2
0
        unsafe static NativeArray <T> DeserializeUnmanagedArray <T>(byte[] buffer, Allocator allocator = Allocator.Temp) where T : unmanaged
        {
            fixed(byte *ptr = buffer)
            {
                var buf = new UnsafeAppendBuffer.Reader(ptr, buffer.Length);

                buf.ReadNext <T>(out var array, allocator);
                return(array);
            }
        }
コード例 #3
0
        //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 public static LiveLinkSceneMsg FromMsg(byte[] buffer, Allocator allocator)
        {
            fixed(byte *ptr = buffer)
            {
                var reader           = new UnsafeAppendBuffer.Reader(ptr, buffer.Length);
                LiveLinkSceneMsg msg = default;

                msg.Deserialize(ref reader, allocator);
                return(msg);
            }
        }
コード例 #5
0
        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;
            }
        }
コード例 #6
0
            public ResourcePacket(byte[] buffer)
            {
                fixed(byte *ptr = buffer)
                {
                    var bufferReader = new UnsafeAppendBuffer.Reader(ptr, buffer.Length);

                    bufferReader.ReadNext(out GlobalObjectIds, Allocator.Persistent);

                    var entityChangeSetSourcePtr  = bufferReader.Ptr + bufferReader.Offset;
                    var entityChangeSetSourceSize = bufferReader.Size - bufferReader.Offset;

                    ChangeSet = new UnsafeAppendBuffer(entityChangeSetSourceSize, 16, Allocator.Persistent);
                    ChangeSet.Add(entityChangeSetSourcePtr, entityChangeSetSourceSize);
                }
            }
コード例 #7
0
        unsafe void ReceiveBuildArtifact(MessageEventArgs args)
        {
            fixed(byte *ptr = args.data)
            {
                LiveLinkMsg.LogInfo($"ReceiveBuildArtifact => Buffer Size: {args.data.Length}");
                var reader = new UnsafeAppendBuffer.Reader(ptr, args.data.Length);

                reader.ReadNext(out string artifactFileName);
                string artifactPath = EntityScenesPaths.ComposeLiveLinkCachePath(artifactFileName);

                if (!File.Exists(artifactPath))
                {
                    LiveLinkMsg.LogInfo($"ReceiveBuildArtifact => {artifactPath}");

                    var tempCachePath = GetTempCachePath();

                    try
                    {
                        var stream = File.OpenWrite(tempCachePath);
                        stream.Write(args.data, reader.Offset, args.data.Length - reader.Offset);
                        stream.Close();
                        stream.Dispose();

                        File.Move(tempCachePath, artifactPath);

                        LiveLinkMsg.LogInfo($"ReceiveBuildArtifact => Successfully written to disc.");
                    }
                    catch (Exception e)
                    {
                        if (File.Exists(tempCachePath))
                        {
                            File.Delete(tempCachePath);
                        }

                        if (!File.Exists(artifactPath))
                        {
                            Debug.LogError($"Failed to move temporary file. Exception: {e.Message}");
                        }
                    }
                }
            }
        }
コード例 #8
0
        unsafe void ReceiveSubScene(MessageEventArgs args)
        {
            fixed(byte *ptr = args.data)
            {
                var reader = new UnsafeAppendBuffer.Reader(ptr, args.data.Length);

                reader.ReadNext(out ResolvedSubSceneID subSceneId);
                reader.ReadNext(out NativeArray <RuntimeGlobalObjectId> runtimeGlobalObjectIds, Allocator.Persistent);

                LiveLinkMsg.LogInfo($"ReceiveSubScene => SubScene received {subSceneId} | Asset Dependencies {runtimeGlobalObjectIds.Length}");

                if (!IsSubSceneAvailable(subSceneId))
                {
                    Debug.LogError("SubScene is missing artifacts!");
                    return;
                }

                AddWaitForSubScene(subSceneId, runtimeGlobalObjectIds);
            }
        }
 void Deserialize(ref UnsafeAppendBuffer.Reader buffer, Allocator allocator)
 {
     buffer.ReadNext(out LoadedScenes, allocator);
     buffer.ReadNext(out RemovedScenes, allocator);
 }
コード例 #10
0
        public void Playback(ref ManagedDeferredCommands managedDeferredCommands)
        {
            var reader = new UnsafeAppendBuffer.Reader(ref managedDeferredCommands.CommandBuffer);

            while (!reader.EndOfBuffer)
            {
                var cmd = reader.ReadNext <int>();
                switch ((ManagedDeferredCommands.Command)cmd)
                {
                case (ManagedDeferredCommands.Command.IncrementSharedComponentVersion):
                {
                    var sharedIndex = reader.ReadNext <int>();
                    IncrementSharedComponentVersion(sharedIndex);
                }
                break;

                case (ManagedDeferredCommands.Command.CopyManagedObjects):
                {
                    var srcArchetype         = (Archetype *)reader.ReadNext <IntPtr>();
                    var srcManagedArrayIndex = reader.ReadNext <int>();
                    var srcChunkCapacity     = reader.ReadNext <int>();
                    var srcStartIndex        = reader.ReadNext <int>();
                    var dstArchetype         = (Archetype *)reader.ReadNext <IntPtr>();
                    var dstManagedArrayIndex = reader.ReadNext <int>();
                    var dstChunkCapacity     = reader.ReadNext <int>();
                    var dstStartIndex        = reader.ReadNext <int>();
                    var count = reader.ReadNext <int>();

                    CopyManagedObjects(this, srcArchetype, srcManagedArrayIndex, srcChunkCapacity, srcStartIndex,
                                       this, dstArchetype, dstManagedArrayIndex, dstChunkCapacity, dstStartIndex, count);
                }
                break;

                case (ManagedDeferredCommands.Command.ReplicateManagedObjects):
                {
                    var srcArchetype         = (Archetype *)reader.ReadNext <IntPtr>();
                    var srcManagedArrayIndex = reader.ReadNext <int>();
                    var srcChunkCapacity     = reader.ReadNext <int>();
                    var srcIndex             = reader.ReadNext <int>();
                    var dstArchetype         = (Archetype *)reader.ReadNext <IntPtr>();
                    var dstManagedArrayIndex = reader.ReadNext <int>();
                    var dstChunkCapacity     = reader.ReadNext <int>();
                    var dstBaseStartIndex    = reader.ReadNext <int>();
                    var count = reader.ReadNext <int>();

                    var srcEntity = reader.ReadNext <Entity>();
                    reader.ReadNext <Entity>(out var dstEntities, Allocator.Temp);

                    ReplicateManagedObjects(this, srcArchetype, srcManagedArrayIndex, srcChunkCapacity, srcIndex,
                                            this, dstArchetype, dstManagedArrayIndex, dstChunkCapacity, dstBaseStartIndex, count, srcEntity, dstEntities);
                }
                break;

                case (ManagedDeferredCommands.Command.ClearManagedObjects):
                {
                    var archetype         = (Archetype *)reader.ReadNext <IntPtr>();
                    var managedArrayIndex = reader.ReadNext <int>();
                    var chunkCapacity     = reader.ReadNext <int>();
                    var index             = reader.ReadNext <int>();
                    var count             = reader.ReadNext <int>();

                    ClearManagedObjects(archetype, managedArrayIndex, chunkCapacity, index, count);
                }
                break;

                case (ManagedDeferredCommands.Command.AddReference):
                {
                    var index   = reader.ReadNext <int>();
                    var numRefs = reader.ReadNext <int>();
                    AddReference(index, numRefs);
                }
                break;

                case (ManagedDeferredCommands.Command.RemoveReference):
                {
                    var index   = reader.ReadNext <int>();
                    var numRefs = reader.ReadNext <int>();
                    RemoveReference(index, numRefs);
                }
                break;

                case (ManagedDeferredCommands.Command.DeallocateManagedArrayStorage):
                {
                    var index = reader.ReadNext <int>();
                    DeallocateManagedArrayStorage(index);
                }
                break;

                case (ManagedDeferredCommands.Command.AllocateManagedArrayStorage):
                {
                    var index  = reader.ReadNext <int>();
                    var length = reader.ReadNext <int>();
                    AllocateManagedArrayStorage(index, length);
                }
                break;

                case (ManagedDeferredCommands.Command.ReserveManagedArrayStorage):
                {
                    var count = reader.ReadNext <int>();
                    ReserveManagedArrayStorage(count);
                }
                break;

                case (ManagedDeferredCommands.Command.MoveChunksManagedObjects):
                {
                    var oldArchetype         = (Archetype *)reader.ReadNext <IntPtr>();
                    var oldManagedArrayIndex = reader.ReadNext <int>();
                    var newArchetype         = (Archetype *)reader.ReadNext <IntPtr>();
                    var newManagedArrayIndex = reader.ReadNext <int>();
                    var chunkCapacity        = reader.ReadNext <int>();
                    var count = reader.ReadNext <int>();

                    CopyManagedObjects(this, oldArchetype, oldManagedArrayIndex, chunkCapacity, 0,
                                       this, newArchetype, newManagedArrayIndex, chunkCapacity, 0, count);
                }
                break;

                case (ManagedDeferredCommands.Command.PatchManagedEntities):
                {
                    var archetype   = (Archetype *)reader.ReadNext <IntPtr>();
                    var chunk       = (Chunk *)reader.ReadNext <IntPtr>();
                    var entityCount = reader.ReadNext <int>();
                    var remapping   = (EntityRemapUtility.EntityRemapInfo *)reader.ReadNext <IntPtr>();
                    var allocator   = (Allocator)reader.ReadNext <int>();

                    PatchEntities(this, archetype, chunk, entityCount, remapping, allocator);
                }
                break;

                case (ManagedDeferredCommands.Command.PatchManagedEntitiesForPrefabs):
                {
                    var archetype      = (Archetype *)reader.ReadNext <IntPtr>();
                    var chunk          = (Chunk *)reader.ReadNext <IntPtr>();
                    var indexInChunk   = reader.ReadNext <int>();
                    var entityCount    = reader.ReadNext <int>();
                    var remapping      = (EntityRemapUtility.SparseEntityRemapInfo *)reader.ReadNext <IntPtr>();
                    var remappingCount = reader.ReadNext <int>();
                    var allocator      = (Allocator)reader.ReadNext <int>();

                    PatchEntitiesForPrefab(this, archetype, chunk, indexInChunk, entityCount, remapping, remappingCount, allocator);
                }
                break;
                }
            }

            managedDeferredCommands.Reset();
        }
コード例 #11
0
        public void Playback(ref ManagedDeferredCommands managedDeferredCommands)
        {
            var reader = new UnsafeAppendBuffer.Reader(ref managedDeferredCommands.CommandBuffer);

            while (!reader.EndOfBuffer)
            {
                var cmd = reader.ReadNext <int>();
                switch ((ManagedDeferredCommands.Command)cmd)
                {
                case (ManagedDeferredCommands.Command.IncrementSharedComponentVersion):
                {
                    var sharedIndex = reader.ReadNext <int>();
                    IncrementSharedComponentVersion(sharedIndex);
                }
                break;

                case (ManagedDeferredCommands.Command.AddReference):
                {
                    var index   = reader.ReadNext <int>();
                    var numRefs = reader.ReadNext <int>();
                    AddReference(index, numRefs);
                }
                break;

                case (ManagedDeferredCommands.Command.RemoveReference):
                {
                    var index   = reader.ReadNext <int>();
                    var numRefs = reader.ReadNext <int>();
                    RemoveReference(index, numRefs);
                }
                break;

                case (ManagedDeferredCommands.Command.PatchManagedEntities):
                {
                    var archetype   = (Archetype *)reader.ReadNext <IntPtr>();
                    var chunk       = (Chunk *)reader.ReadNext <IntPtr>();
                    var entityCount = reader.ReadNext <int>();
                    var remapping   = (EntityRemapUtility.EntityRemapInfo *)reader.ReadNext <IntPtr>();

                    PatchEntities(archetype, chunk, entityCount, remapping);
                }
                break;

                case (ManagedDeferredCommands.Command.PatchManagedEntitiesForPrefabs):
                {
                    var remapSrc             = (byte *)reader.ReadNext <IntPtr>();
                    var allocatedCount       = reader.ReadNext <int>();
                    var remappingCount       = reader.ReadNext <int>();
                    var numManagedComponents = reader.ReadNext <int>();
                    var allocator            = (Allocator)reader.ReadNext <int>();


                    var remapSrcSize = UnsafeUtility.SizeOf <Entity>() * remappingCount;
                    var remapDstSize = UnsafeUtility.SizeOf <Entity>() * remappingCount * allocatedCount;

                    var remapDst          = remapSrc + remapSrcSize;
                    var managedComponents = remapDst + remapDstSize;

                    PatchEntitiesForPrefab((int *)managedComponents, numManagedComponents, allocatedCount, remappingCount, (Entity *)remapSrc, (Entity *)remapDst);
                    UnsafeUtility.Free(remapSrc, allocator);
                }
                break;

                case (ManagedDeferredCommands.Command.CloneManagedComponents):
                {
                    var srcArray      = (int *)reader.ReadNextArray <int>(out var componentCount);
                    var instanceCount = reader.ReadNext <int>();
                    var dstArray      = (int *)reader.ReadNextArray <int>(out _);
                    CloneManagedComponents(srcArray, componentCount, dstArray, instanceCount);
                }
                break;

                case (ManagedDeferredCommands.Command.CloneHybridComponents):
                {
                    var srcArray = (int *)reader.ReadNextArray <int>(out var componentCount);
                    var entities = (Entity *)reader.ReadNextArray <Entity>(out var instanceCount);
                    var dstArray = (int *)reader.ReadNextArray <int>(out _);

                    if (InstantiateHybridComponent != null)
                    {
                        InstantiateHybridComponent(srcArray, componentCount, entities, dstArray, instanceCount, this);
                    }
                    else
                    {
                        // InstantiateHybridComponent was not injected just copy the reference to the object and dont clone it
                        for (int src = 0; src < componentCount; ++src)
                        {
                            object sourceComponent = m_ManagedComponentData[srcArray[src]];
                            for (int i = 0; i < instanceCount; ++i)
                            {
                                m_ManagedComponentData[dstArray[i]] = sourceComponent;
                            }
                            dstArray += instanceCount;
                        }
                    }
                }
                break;

                case (ManagedDeferredCommands.Command.FreeManagedComponents):
                {
                    var count = reader.ReadNext <int>();
                    for (int i = 0; i < count; ++i)
                    {
                        var managedComponentIndex = reader.ReadNext <int>();
                        m_ManagedComponentData[managedComponentIndex] = null;
                    }
                }
                break;

                case (ManagedDeferredCommands.Command.SetManagedComponentCapacity):
                {
                    var capacity = reader.ReadNext <int>();
                    SetManagedComponentCapacity(capacity);
                }
                break;
                }
            }

            managedDeferredCommands.Reset();
        }