public void Depacketize(IReadablePacket packet) { // Read the list of commands for the next frame. Commands.Clear(); foreach (var command in packet.ReadPacketizablesWithTypeInfo <Command>()) { PushCommand(command); } }
/// <summary> /// Reads an entity from the specified packet, meaning all its components. This will create a new entity, with an id /// that may differ from the id the entity had when it was written. /// <para/> /// In particular, all re-created components will likely have different different ids as well, so this method is not /// suited for storing components that reference other components, even if just by their ID. /// <para/> /// This will act as though all of the written components were added, i.e. for each restored component a /// <see cref="ComponentAdded"/> message will be sent. /// <para/> /// This uses the components' serialization facilities. /// </summary> /// <param name="packet">The packet to read the entity from.</param> /// <param name="componentIdMap">A mapping of how components' ids changed due to serialization, mapping old id to new id.</param> /// <returns>The id of the read entity.</returns> public int DepacketizeEntity(IReadablePacket packet, Dictionary <int, int> componentIdMap = null) { // Keep track of what we already did, to allow unwinding if something // bad happens. Then get an entity id and try to read the components. var undo = new Stack <Action>(); var entity = AddEntity(); undo.Push(() => RemoveEntity(entity)); try { // Read all components that were written for this entity. This // does not yet mess with our internal state. var components = packet.ReadPacketizablesWithTypeInfo <Component>(); // Now we need to inject the components into our system, so we assign // an id to each one and link it to our entity id. foreach (var component in components) { // Link stuff together. var id = _componentIds.GetId(); if (componentIdMap != null) { componentIdMap.Add(component.Id, id); } component.Id = id; component.Entity = entity; component.Manager = this; _components[component.Id] = component; // Add to entity index. _entities[entity].Add(component); // Push to undo queue in case a message handler throws. undo.Push(() => RemoveComponent(id)); // Send a message to all systems. ComponentAdded message; message.Component = component; SendMessage(message); } // Yay, all went well. Return the id of the read entity. return(entity); } catch (Exception) { // Undo all we did. while (undo.Count > 0) { undo.Pop()(); } throw; } }
public void Depacketize(IReadablePacket packet) { // Unwrap the trailing state and mirror it to all the newer ones. packet.ReadPacketizableInto(_simulations[_simulations.Length - 1]); MirrorSimulation(_simulations[_simulations.Length - 1], _simulations.Length - 2); // Find adds / removes / commands that our out of date now, but keep // newer ones (that might be locally generated). PrunePastEvents(); // Continue with reading the list of removes. var removeCount = packet.ReadInt32(); for (var removeIndex = 0; removeIndex < removeCount; ++removeIndex) { var key = packet.ReadInt64(); if (!_removes.ContainsKey(key)) { _removes.Add(key, new List <int>()); } var valueCount = packet.ReadInt32(); for (var valueIndex = 0; valueIndex < valueCount; ++valueIndex) { _removes[key].Add(packet.ReadInt32()); } } // And finally the commands. var commandCount = packet.ReadInt32(); for (var commandIndex = 0; commandIndex < commandCount; ++commandIndex) { var key = packet.ReadInt64(); if (!_commands.ContainsKey(key)) { _commands.Add(key, new List <Command>()); } _commands[key].AddRange(packet.ReadPacketizablesWithTypeInfo <Command>()); } // Got a valid state. WaitingForSynchronization = false; }