示例#1
0
        /// <summary>
        /// Executes all local changes on the specified pool, and automatically dispatches queued pool events
        /// </summary>
        /// <param name="pool">Pool to execute changes on</param>
        public int Execute(EntityPool pool, InconsistencyCoverage ic, EntityChange.ExecutionContext ctx)
        {
            int numErrors = 0;

            numErrors += motions.Execute(pool, ctx);
            numErrors += pool.ResolveConflictFreeOperations(ic, ctx);
            numErrors += removals.Execute(pool, ctx);
            //numErrors += pool.ResolveConflictFreeOperations(ic);	//removals don't do conflicting stuff (one removes first, and all others fail, but entity is removed regardless, so all win)
            numErrors += instantiations.Execute(pool, ctx);
            numErrors += pool.ResolveConflictFreeOperations(ic, ctx);
#if STATE_ADV
            if (advertisements.Size > 0)
            {
                pool.RequireTree();
            }
            numErrors += advertisements.Execute(pool, ic, ctx);
#endif
            numErrors += messages.Execute(pool, ctx);
            if (broadcasts.Size > 0)
            {
                pool.RequireTree();
            }
            numErrors += broadcasts.Execute(pool, ctx);
            pool.DispatchAll();
            return(numErrors);
        }
示例#2
0
            public InsertPriority(Entity destination, EntityChange.ExecutionContext ctx, InconsistencyCoverage ic)
            {
                Destination = destination;

                Score  = 1;
                Score /= (1f + ic.GetInconsistencyAtR(ctx.LocalSpace.Relativate(destination.ID.Position)));
            }
示例#3
0
 public void Include(Set <T> other, Box targetSpace, EntityChange.ExecutionContext ctx)
 {
     foreach (T el in other.bag)
     {
         if (el.Affects(targetSpace, ctx))
         {
             Add(el);
         }
     }
 }
示例#4
0
文件: SDS.cs 项目: IronFox/Shard
        public SDS MergeWith(SDS other, MergeStrategy strategy, EntityChange.ExecutionContext ctx)
        {
            if (Generation != other.Generation)
            {
                throw new IntegrityViolation("Generation mismatch: " + Generation + " != " + other.Generation);
            }

            SDS exclusiveSource = null;
            int exclusiveChoice = 0;

            if (strategy == MergeStrategy.Exclusive || strategy == MergeStrategy.ExclusiveWithPositionCorrection)
            {
                exclusiveChoice = SelectExclusiveSource(this, other);
                exclusiveSource = (exclusiveChoice == -1 ? this : other);
            }

            InconsistencyCoverage merged = InconsistencyCoverage.GetMinimum(IC, other.IC);
            EntityPool            pool   = new EntityPool(ctx);

            foreach (var e in this.FinalEntities)
            {
                if (IC.IsInconsistentR(ctx.LocalSpace.Relativate(e.ID.Position)))
                {
                    continue;                       //for now
                }
                pool.Insert(e);
            }
            foreach (var e in other.FinalEntities)
            {
                if (other.IC.IsInconsistentR(ctx.LocalSpace.Relativate(e.ID.Position)))
                {
                    continue;                       //for now
                }
                if (pool.Contains(e.ID.Guid))
                {
                    continue;
                }
                pool.Insert(e);
            }
            //at this point we merged all fully consistent entities from either. If the inconsistent areas did not overlap then the result should contain all entities in their consistent state


            if (!merged.IsFullyConsistent)
            {
                if (strategy == MergeStrategy.EntitySelective)
                {
                    MergeInconsistentEntitiesComp(pool, this, other, merged, ctx);
                }
                else
                {
                    MergeInconsistentEntitiesEx(pool, exclusiveSource, strategy == MergeStrategy.ExclusiveWithPositionCorrection, merged, ctx);
                }
            }
            return(new SDS(Generation, pool.ToArray(), merged));
        }
示例#5
0
        public void FilterByTargetLocation(Box targetSpace, EntityChange.ExecutionContext ctx)
        {
            broadcasts.FilterByTargetLocation(targetSpace, ctx);
            messages.FilterByTargetLocation(targetSpace, ctx);
            motions.FilterByTargetLocation(targetSpace, ctx);
            removals.FilterByTargetLocation(targetSpace, ctx);
            instantiations.FilterByTargetLocation(targetSpace, ctx);
#if STATE_ADV
            advertisements.FilterByTargetLocation(targetSpace, ctx);
#endif
        }
示例#6
0
        /// <summary>
        /// Duplicates all changes in the specified source affecting the specified target space
        /// </summary>
        /// <param name="source"></param>
        /// <param name="targetSpace"></param>
        public EntityChangeSet(EntityChangeSet source, Box targetSpace, EntityChange.ExecutionContext ctx)
        {
            broadcasts.Include(source.broadcasts, targetSpace, ctx);
            messages.Include(source.messages, targetSpace, ctx);
            motions.Include(source.motions, targetSpace, ctx);
            removals.Include(source.removals, targetSpace, ctx);
            instantiations.Include(source.instantiations, targetSpace, ctx);
#if STATE_ADV
            advertisements.Include(source.advertisements, targetSpace, ctx);
#endif
        }
示例#7
0
            public int Execute(EntityPool pool, EntityChange.ExecutionContext ctx)
            {
                //var ar = ToSortedArray();	//no point sorting when we're gonna execute the changes in parallel anyways
                int numErrors = 0;

                Parallel.ForEach(bag, c => { if (!c.Execute(pool, ctx))
                                             {
                                                 Interlocked.Increment(ref numErrors);
                                             }
                                 });
                return(numErrors);
            }
示例#8
0
 public EntityPool(IEnumerable <Entity> entities, EntityChange.ExecutionContext ctx)
 {
     this.ctx = ctx;
     if (entities != null)
     {
         foreach (var e in entities)
         {
             var c = InsertC(e);
             if (c == null)
             {
                 ctx.LogMessage("Failed to insert entity " + e);
             }
         }
     }
 }
示例#9
0
            public void FilterByTargetLocation(Box targetSpace, EntityChange.ExecutionContext ctx)
            {
                List <T> temp = new List <T>();
                T        el;

                while (bag.TryTake(out el))
                {
                    if (el.Affects(targetSpace, ctx))
                    {
                        temp.Add(el);
                    }
                }
                foreach (var e in temp)
                {
                    bag.Add(e);
                }
            }
示例#10
0
        public int ResolveConflictFreeOperations(InconsistencyCoverage ic, EntityChange.ExecutionContext ctx)
        {
            int errors = 0;

            Parallel.ForEach(deferredInserts.Values, bag =>
            {
                Entity e;
                InsertPriority best = new InsertPriority();
                Interlocked.Add(ref errors, bag.Count - 1);
                while (bag.TryTake(out e))
                {
                    var candidate = new InsertPriority(e, ctx, ic);
                    if (candidate > best)
                    {
                        best = candidate;
                    }
                }
                if (best.Destination == null || !Insert(best.Destination))
                {
                    Interlocked.Increment(ref errors);
                }
            });
            deferredInserts.Clear();

            Parallel.ForEach(fullMap.Values, ctr =>
            {
                if (ctr.deferredUpdates.IsEmpty)
                {
                    return;
                }
                Tuple <EntityID, Entity> tuple;
                bool inc = ic.IsInconsistentR(ctx.LocalSpace.Relativate(ctr.entity.ID.Position));
                MovementPriority best = new MovementPriority();
                Interlocked.Add(ref errors, ctr.deferredUpdates.Count - 1);
                while (ctr.deferredUpdates.TryTake(out tuple))
                {
                    bool destInc  = ic.IsInconsistentR(ctx.LocalSpace.Relativate(tuple.Item2.ID.Position));
                    var candidate = new MovementPriority(ctr.entity, tuple.Item1, tuple.Item2, ctx, inc, destInc);
                    if (candidate > best)
                    {
                        best = candidate;
                    }
                }
                if (best.Destination != null)
                {
                    ctr.entity = best.Destination;
                    tree       = null;
                }
                else
                {
                    Interlocked.Increment(ref errors);
                }
            });
            EntityID id;

            while (deferredRemovals.TryTake(out id))
            {
                if (CheckFindAndRemove(id))
                {
                    tree = null;
                }
                else
                {
                    errors++;
                }
            }


            return(errors);
        }
示例#11
0
            public MovementPriority(Entity current, EntityID presumedCurrent, Entity destination, EntityChange.ExecutionContext ctx, bool currentIsInconsistent, bool destIsInconsistent)
            {
                PresumedCurrent = presumedCurrent;
                Destination     = destination;
                CurrentMatch    = current.ID.Position == presumedCurrent.Position;


                Score = 1;
                if (CurrentMatch)
                {
                    Score += 10;
                }
                if (destIsInconsistent)
                {
                    Score *= 0.5f;
                }


                if (!CurrentMatch /*&& destIsInconsistent*/ && !currentIsInconsistent)
                {
                    Score = -1;
                }
            }
示例#12
0
 public EntityPool(EntityChange.ExecutionContext ctx)
 {
     this.ctx = ctx;
 }
示例#13
0
文件: SDS.cs 项目: IronFox/Shard
        private static void MergeInconsistentEntitiesComp(EntityPool pool, SDS s0, SDS s1, InconsistencyCoverage ic, EntityChange.ExecutionContext ctx)
        {
            var a = new EntityPool(s0.FinalEntities, ctx);
            var b = new EntityPool(s1.FinalEntities, ctx);

            const float searchScope = 0.5f;

            foreach (var e0 in a)
            {
                if (pool.Contains(e0.ID.Guid))
                {
                    continue;                       //already good
                }
                //entity is inconsistent and not in merged state yet
                var c0 = ctx.LocalSpace.Relativate(e0.ID.Position);
                var e1 = b.Find(e0.ID.Guid);
                var c1 = e1 != null?ctx.LocalSpace.Relativate(e1.ID.Position) : Vec3.Zero;

                if (!ic.IsInconsistentR(c0))
                {
                    //this is tricky. entity not merged, but would reside in consistent space (bad).
                    if (e1 != null)
                    {
                        //		ASSERT__(b.ic.IsInconsistent(c1));	//otherwise it would have been added prior, and we would not be here
                        //so this entity exists in both SDS'
                        {
                            //we now have the same entity twice, both inconsistent, residing each in the consistent space of the other SDS'
                            //let's assume the entity isn't supposed to exist here anyways

                            Entity candidate = null;
                            int    sc        = s0.IC.GetInconsistencyAtR(c0).CompareTo(s1.IC.GetInconsistencyAtR(c1));
                            if (sc < 0)
                            {
                                candidate = e0;
                            }
                            else if (sc > 0)
                            {
                                candidate = e1;
                            }
                            else if (e0.CompareTo(e1) < 0)
                            {
                                candidate = e0;
                            }
                            else
                            {
                                candidate = e1;
                            }


                            var c = ctx.LocalSpace.Relativate(candidate.ID.Position);
                            if (ic.FindInconsistentPlacementCandidateR(ref c, searchScope))
                            {
                                Entity me = candidate.Relocate(ctx.LocalSpace.DeRelativate(c));
                                pool.Insert(me);
                            }
                        }
                    }
                    else
                    {
                        //entity exists only in local SDS.
                        //let's assume the entity isn't supposed to exist here anyways

                        //TEntityCoords c = Frac(e0->coordinates);
                        //if (merged.ic.FindInconsistentPlacementCandidate(c,searchScope))
                        //{
                        //	Entity copy = *e0;
                        //	copy.coordinates = c + shardOffset;
                        //	//ASSERT__(merged.ic.IsInconsistent(Frac(copy.coordinates)));
                        //	merged.entities.InsertEntity(copy);
                        //}
                        //else
                        //	FATAL__("bad");
                    }
                }
                else
                {
                    //entity location is inconsistent in both SDS'. This is expected to be the most common case
                    if (e1 != null)
                    {
                        if (e1.Equals(e0))
                        {
                            //probably actually consistent
                            //						ASSERT__(merged.ic.IsInconsistent(Frac(e0->coordinates)));
                            pool.Insert(e0);
                        }
                        else
                        {
                            if (!ic.IsInconsistentR(c1))
                            {
                                Debug.Assert(ic.IsInconsistentR(c0));
                                pool.Insert(e0);
                            }
                            else
                            {
                                Entity candidate = null;
                                int    sc        = s0.IC.GetInconsistencyAtR(c0).CompareTo(s1.IC.GetInconsistencyAtR(c1));
                                if (sc < 0)
                                {
                                    candidate = e0;
                                }
                                else if (sc > 0)
                                {
                                    candidate = e1;
                                }
                                else if (e0.CompareTo(e1) < 0)
                                {
                                    candidate = e0;
                                }
                                else
                                {
                                    candidate = e1;
                                }

                                //common case. Choose one
                                //ASSERT__(ic.IsInconsistentR(candidate->coordinates-shardOffset));
                                pool.Insert(candidate);
                            }
                        }
                    }
                    else
                    {
                        //only e0 exists
                        int sc = s0.IC.GetInconsistencyAtR(c0).CompareTo(s1.IC.GetInconsistencyAtR(c0));
                        //ASSERT__(merged.ic.IsInconsistent(Frac(e0->coordinates)));
                        if (sc <= 0)
                        {
                            pool.Insert(e0);
                        }
                    }
                }
            }
            foreach (var e0 in b)
            {
                if (pool.Contains(e0.ID.Guid))
                {
                    continue;                           //already good
                }
                //entity is inconsistent and not in merged state yet
                var c0 = ctx.LocalSpace.Relativate(e0.ID.Position);
                //const auto c1 = e1 ? (e1->coordinates - shardOffset) : TEntityCoords();
                if (!ic.IsInconsistentR(c0))
                {
                                        #if false
                    //this is tricky. entity not merged, but would reside in consistent space (bad).
                    if (e1)
                    {
                        //case handled
                        //FATAL__("bad");
                    }
                    else
                    {
                        //entity exists only in local SDS.
                        //let's assume the entity isn't supposed to exist here anyways

                        //TEntityCoords c = Frac(e0->coordinates);
                        //if (merged.ic.FindInconsistentPlacementCandidate(c,searchScope))
                        //{
                        //	Entity copy = *e0;
                        //	copy.coordinates = c + shardOffset;
                        //	//ASSERT__(merged.ic.IsInconsistent(Frac(copy.coordinates)));
                        //	merged.entities.InsertEntity(copy);
                        //}

                        /*	else
                         *              FATAL__("bad");*/
                    }
                                        #endif
                }
                else
                {
                    var e1 = a.Find(e0.ID.Guid);
                    //entity location is inconsistent in both SDS'. This is expected to be the most common case
                    if (e1 != null)
                    {
                        //case handled
                        //FATAL__("bad");
                    }
                    else
                    {
                        //only e0 exists
                        int sc = s0.IC.GetInconsistencyAtR(c0).CompareTo(s1.IC.GetInconsistencyAtR(c0));
                        //ASSERT__(merged.ic.IsInconsistent(Frac(e0->coordinates)));
                        if (sc >= 0)
                        {
                            pool.Insert(e0);
                        }
                    }
                }
            }
        }
示例#14
0
        public List <EntityError> Evolve(IReadOnlyList <Entity> entities,
                                         Dictionary <Guid, ClientMessage[]> clientMessages,
                                         InconsistencyCoverage ic,
                                         TimeSpan budget,
                                         EntityChange.ExecutionContext ctx)
        {
            if (ic.Size != InconsistencyCoverage.CommonResolution)
            {
                throw new IntegrityViolation("Trying to evolve with an IC of size " + ic.Size + ". Should be " + InconsistencyCoverage.CommonResolution);
            }
            int numErrors = 0;

            List <Task>             tasks  = new List <Task>();
            List <Entity.TimeTrace> tables = new List <Entity.TimeTrace>();

            ClientMessage[] clientBroadcasts = null;
            if (clientMessages != null)
            {
                clientMessages.TryGetValue(Guid.Empty, out clientBroadcasts);
            }
            Stopwatch watch0 = new Stopwatch();

            object lazyLock = new object();
            bool   exceeded = false;
            var    rs       = new LazyList <EntityError>();

            Parallel.For(0, entities.Count, i =>
            {
                Entity e = entities[i];
                ClientMessage[] messages = null;
                if (clientMessages != null)
                {
                    clientMessages.TryGetValue(e.ID.Guid, out messages);
                }
                var t = new Entity.TimeTrace(watch0);

                //tables.Add(t);


                EntityLogic st = null;

                try
                {
                    if (!exceeded)
                    {
                        st = e.Evolve(t, this, Helper.Concat(clientBroadcasts, messages), ctx, ic.IsInconsistentR(ctx.LocalSpace.Relativate(e.ID.Position)));
                        if (e.transientDeserializedLogic != null)
                        {
                            throw new IntegrityViolation("Transient deserialized logic was not wiped");
                        }
                    }
                    if (exceeded || watch0.Elapsed > budget)
                    {
                        exceeded = true;
                        throw new TimeBudgetException(budget, t);
                    }
                }
                catch (AssertFailedException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    if (st == null)
                    {
                        st = (EntityLogic)Helper.Deserialize(e.SerialLogicState);
                    }
                    var error = new EntityError(e, st, ex);
                    lock (lazyLock)
                        rs.Add(error);
                    ic.FlagInconsistentR(ctx.LocalSpace.Relativate(e.ID.Position));
                    Interlocked.Increment(ref numErrors);
                }
            });

/*
 *
 *                      watch0.Start();
 *                      foreach (var e in entities)
 *                      {
 *                              EntityMessage[] messages = null;
 *                              if (clientMessages != null)
 *                              {
 *                                      clientMessages.TryGetValue(e.ID.Guid, out messages);
 *                              }
 *                              var t = new Entity.TimeTrace(watch0);
 *                              tables.Add(t);
 *                              tasks.Add(e.EvolveAsync(t,this, roundNumber, maySendMessages,Helper.Concat(clientBroadcasts, messages)));
 *                      }
 *                      int at = 0;
 *
 *                      Stopwatch watch = new Stopwatch();
 *                      watch.Start();
 *
 *                      LazyList<EntityEvolutionException> rs = new LazyList<EntityEvolutionException>();
 *
 *                      foreach (var e in entities)
 *                      {
 *                              try
 *                              {
 *                                      var remaining = (budget - watch.Elapsed).NotNegative();
 *                                      if (!tasks[at].Wait( remaining))
 *                                              throw new ExecutionException(e.ID, "Failed to execute " + (EntityLogic)Helper.Deserialize(e.SerialLogicState)+" in "+remaining.TotalMilliseconds+" ms");
 *                              }
 *                              catch (Exception ex)
 *                              {
 *                                      rs.Add(new EntityEvolutionException(e, ex, tables[at]));
 *
 *                                      ic.FlagInconsistentR(Simulation.MySpace.Relativate(e.ID.Position));
 *
 *                                      Interlocked.Increment(ref numErrors);
 *                              }
 *                              at++;
 *                      }*/

            return(rs.InternalList);
        }
示例#15
0
        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);
        }
示例#16
0
文件: SDS.cs 项目: IronFox/Shard
        private static void MergeInconsistentEntitiesEx(EntityPool pool, SDS source, bool correctLocations, InconsistencyCoverage ic, EntityChange.ExecutionContext ctx)
        {
            const float searchScope = 0.5f;

            foreach (var e0 in source.FinalEntities)
            {
                if (pool.Contains(e0.ID.Guid))
                {
                    continue;                           //already good
                }
                var c0 = ctx.LocalSpace.Relativate(e0.ID.Position);
                if (ic.IsInconsistentR(c0))
                {
                    pool.Insert(e0);
                }
                else
                {
                    if (correctLocations)
                    {
                        var c = c0;
                        if (ic.FindInconsistentPlacementCandidateR(ref c, searchScope))
                        {
                            Entity me = e0.Relocate(c);
                            pool.Insert(me);
                        }
                    }
                    //only increases overaccounted entities:
                    //if (merged.ic.FindInconsistentPlacementCandidate(c0,searchScope))
                    //{
                    //	Entity me = *e0;
                    //	me.coordinates = c0 + shardOffset;
                    //	merged.entities.InsertEntity(me);
                    //}
                }
            }
        }
示例#17
0
        public SDSComputation(DateTime applicationBeginDeadline, ExtMessagePack clientMessages, TimeSpan entityLogicTimeout, EntityChange.ExecutionContext ctx)
        {
            this.ctx   = ctx;
            generation = ctx.GenerationNumber;
            Deadline   = applicationBeginDeadline;
            SDSStack stack = Simulation.Stack;

            SDSStack.Entry input = stack.FindGeneration(generation - 1);
            if (input == null)
            {
                throw new IntegrityViolation("Unable to locate previous SDS at generation " + (generation - 1));
            }
            if (!input.IsFinished)
            {
                throw new IntegrityViolation("Previous SDS at generation " + (generation - 1) + " exists but is not finished");
            }

            //if (input.Generation != generation-1)
            //	throw new IntegrityViolation("Generation mismatch");
            old = stack.FindGeneration(generation);
            if (old == null)
            {
                throw new IntegrityViolation("Unable to locate original SDS at generation " + generation);
            }

            data = new IntermediateSDS();
            data.inputConsistent = input.IsFullyConsistent;

            {
                using (var ms = new MemoryStream())
                {
                    input.SDS.AddToStream(ms);
                    clientMessages.AddToStream(ms);
                    ms.Seek(0, SeekOrigin.Begin);
                    data.inputHash = new Digest(SHA256.Create().ComputeHash(ms), true);
                }
            }


            //old bad or dont exist, new maybe good
            if (clientMessages.HasBeenDiscarded)
            {
                throw new IntegrityViolation("Available client messages are incomplete but recorded messages have been discarded");
            }
            this.clientMessages = clientMessages.MessagePack;

            if (old.IntermediateSDS != null && old.IntermediateSDS.inputHash == data.inputHash)
            {
                data = old.IntermediateSDS;
                return;
            }



            data.entities       = new EntityPool(input.SDS.FinalEntities, ctx);
            data.localChangeSet = new EntityChangeSet();
            data.ic             = input.SDS.IC.Clone();
            if (!this.clientMessages.Completed)
            {
                Log.Message("Client messages are not complete for generation " + generation + ", setting everything inconsistent");
                data.ic.SetAllOne();
            }
            //bool doSendClientMessages = freshClientMessages != null && freshClientMessages.ArchivedGeneration == generation;
            errors = data.localChangeSet.Evolve(input.SDS.FinalEntities, this.clientMessages.Messages, data.ic, entityLogicTimeout, ctx);
            if (errors == null && input.IsFullyConsistent && data.ic.OneCount != 0 && clientMessages.MessagePack.Completed)
            {
                throw new IntegrityViolation("Input is fully consistent, and there are no errors. IC should have remaining empty");
            }

            InconsistencyCoverage untrimmed = data.ic.Grow(false);

            if (untrimmed.Size != InconsistencyCoverage.CommonResolution + 2)
            {
                throw new IntegrityViolation("IC of unsupported size: " + untrimmed.Size);
            }
            data.ic = untrimmed.Sub(new Int3(1), new Int3(InconsistencyCoverage.CommonResolution));



            foreach (var n in Simulation.Neighbors)
            {
                IntBox remoteBox = n.ICExportRegion;
                var    ic        = untrimmed.Sub(remoteBox);
                RCS    rcs       = new RCS(new EntityChangeSet(data.localChangeSet, n.WorldSpace, ctx), ic);
                var    oID       = n.GetOutboundRCSID(Generation);
                if (generation >= n.OldestGeneration)
                {
                    Log.Message("Dispatched " + oID + ", IC ones=" + ic.OneCount);
                    n.Set(oID.ToString(), new RCS.Serial(rcs, generation));
                    if (rcs.IsFullyConsistent)
                    {
                        n.UploadToDB(generation, rcs);
                    }
                }
                else
                {
                    Log.Error("Recomputed generation, but remote shard will not want generated RCS");
                }
            }
            data.localChangeSet.FilterByTargetLocation(Simulation.MySpace, ctx);
        }
示例#18
0
            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");
                }
            }