public void ApplyTo(EntityChangeSet outChangeSet, EntityLogic logic, byte[] serialLogic, EntityChange.ExecutionContext ctx) { Vec3 dest = ctx.ClampDestination("Motion", NewPosition, id, #if STATE_ADV SuppressAdvertisements ? ctx.Ranges.R : ctx.Ranges.Motion #else ctx.Ranges.Motion #endif ); var newID = id.Relocate(dest); outChangeSet.Add(new EntityChange.Motion(id, dest, #if STATE_ADV newAppearances, #endif logic, serialLogic)); //motion doubles as logic-state-update #if STATE_ADV if (!SuppressAdvertisements) { outChangeSet.Add(new EntityChange.StateAdvertisement(new EntityContact(newID, newAppearances, dest - id.Position))); } #endif foreach (var inst in instantiations) { outChangeSet.Add(new EntityChange.Instantiation(newID, ctx.ClampDestination("Instantiation", inst.targetLocation, newID, ctx.Ranges.Motion), #if STATE_ADV inst.appearances, #endif inst.logic, Helper.SerializeToArray(inst.logic))); } foreach (var rem in removals) { if (ctx.CheckT("Removal", rem.Position, newID)) { outChangeSet.Add(new EntityChange.Removal(newID, rem)); } } int messageID = 0; var messageOriginID = ctx.Ranges.DisplacedTransmission ? newID : id; foreach (var m in messages) { if (m.IsDirectedToClient) { ctx.RelayClientMessage(id.Guid, m.receiver.Guid, m.channel, m.data); } else { outChangeSet.Add(new EntityChange.Message(messageOriginID, messageID++, m.receiver.Guid, m.channel, m.data)); } } foreach (var b in broadcasts) { outChangeSet.Add(new EntityChange.Broadcast(messageOriginID, messageID++, b.maxRange, b.channel, b.data)); } if (nowInconsistent) { throw new ExecutionException(id, "Inconsistency by logic request"); } }
public EntityLogic Evolve(TimeTrace evolutionState, EntityChangeSet outChangeSet, ICollection <ClientMessage> clientMessages, EntityChange.ExecutionContext ctx, bool locationIsInconsistent) { EntityLogic state = null; evolutionState.Begin(); if (Helper.Length(SerialLogicState) > 0) { try { state = MyLogic; transientDeserializedLogic = null; evolutionState.SignalDeserializationDone(); if (state == null) { throw new ExecutionException(ID, "Unable to deserialize logic"); } var actions = new EntityLogic.Actions(this); #if DRY_RUN Debug.Assert(transientDeserializedLogic == null, "Should be null"); #endif state.Execute(ref actions, AddClientMessages(clientMessages), ctx.GenerationNumber, new EntityRandom(this, ctx.GenerationNumber), ctx.Ranges, locationIsInconsistent); evolutionState.SignalEvolutionDone(); byte[] serialLogic = Helper.SerializeToArray(state); evolutionState.SignalReserializationDone(); actions.ApplyTo(outChangeSet, state, serialLogic, ctx); } catch { #if STATE_ADV outChangeSet.Add(new EntityChange.StateAdvertisement(new EntityContact(ID, Appearances, Vec3.Zero))); #endif transientDeserializedLogic = null; throw; } } else { transientDeserializedLogic = null; } evolutionState.End(); return(state); }