Example #1
0
        public void RequestControlUpdate(RailEntityClient entity, RailStateDelta delta)
        {
            // Can't infer anything if the delta is an empty frozen update
            if (delta.IsFrozen)
            {
                return;
            }

            if (delta.IsRemoving)
            {
                if (entity.Controller != null)
                {
                    localPeer.RevokeControlInternal(entity);
                }
            }
            else if (delta.HasControllerData)
            {
                if (entity.Controller == null)
                {
                    localPeer.GrantControlInternal(entity);
                }
            }
            else
            {
                if (entity.Controller != null)
                {
                    localPeer.RevokeControlInternal(entity);
                }
            }
        }
Example #2
0
        /// <summary>
        ///     Returns true iff we stored the delta.
        /// </summary>
        public bool ProcessDelta(RailStateDelta delta)
        {
            if (knownEntities.TryGetValue(delta.EntityId, out RailEntityClient entity) == false)
            {
                RailDebug.Assert(delta.IsFrozen == false, "Frozen unknown entity");
                if (delta.IsFrozen || delta.IsRemoving)
                {
                    return(false);
                }

                entity = delta.ProduceEntity(Resource) as RailEntityClient;
                if (entity == null)
                {
                    throw new TypeAccessException(
                              "Got unexpected instance from RailResource. Internal error in type RailRegistry and/or RailResource.");
                }

                entity.AssignId(delta.EntityId);
                entity.PrimeState(delta);
                pendingEntities.Add(entity.Id, entity);
                knownEntities.Add(entity.Id, entity);
            }

            // If we're already removing the entity, we don't care about other deltas
            bool stored = false;

            if (entity.IsRemoving == false)
            {
                stored = entity.ReceiveDelta(delta);
            }
            return(stored);
        }
Example #3
0
        internal static void EncodeDelta(
            RailBitBuffer buffer,
            RailStateDelta delta)
        {
            // Write: [EntityId]
            buffer.WriteEntityId(delta.EntityId);

            // Write: [IsFrozen]
            buffer.WriteBool(delta.IsFrozen);

            if (delta.IsFrozen == false)
            {
                // Write: [FactoryType]
                RailState state = delta.State;
                buffer.WriteInt(RailState.FactoryTypeCompressor, state.factoryType);

                // Write: [IsRemoved]
                buffer.WriteBool(state.RemovedTick.IsValid);

                if (state.RemovedTick.IsValid)
                {
                    // Write: [RemovedTick]
                    buffer.WriteTick(state.RemovedTick);

                    // End Write
                }
                else
                {
                    // Write: [HasControllerData]
                    buffer.WriteBool(state.HasControllerData);

                    // Write: [HasImmutableData]
                    buffer.WriteBool(state.HasImmutableData);

                    // Write: [Flags]
                    buffer.Write(state.FlagBits, state.Flags);

                    // Write: [Mutable Data]
                    state.EncodeMutableData(buffer, state.Flags);

                    if (state.HasControllerData)
                    {
                        // Write: [Controller Data]
                        state.EncodeControllerData(buffer);

                        // Write: [Command Ack]
                        buffer.WriteTick(state.CommandAck);
                    }

                    if (state.HasImmutableData)
                    {
                        // Write: [Immutable Data]
                        state.EncodeImmutableData(buffer);
                    }
                }
            }
        }
Example #4
0
        private void ProduceScoped(Tick serverTick, IEnumerable <RailEntityServer> activeEntities)
        {
            // TODO: should be doable without the copy using a LINQ expression.
            entryList.Clear();

            foreach (RailEntityServer entity in activeEntities)
            {
                if (entity.IsRemoving)
                {
                }
                // Controlled entities are always in scope to their controller
                else if (entity.Controller == owner)
                {
                    entryList.Add(new KeyValuePair <float, RailEntityBase>(float.MinValue, entity));
                }
                else if (GetPriority(entity, serverTick, out float priority))
                {
                    entryList.Add(new KeyValuePair <float, RailEntityBase>(priority, entity));
                }
                else if (RailEntityBase.CanFreeze)
                {
                    // We only want to send a freeze state if we aren't already frozen
                    RailViewEntry latest = ackedByClient.GetLatest(entity.Id);
                    if (latest.IsFrozen == false)
                    {
                        frozenList.Add(
                            RailStateDelta.CreateFrozen(stateCreator, serverTick, entity.Id));
                    }
                }
            }

            entryList.Sort(priorityComparer);
            foreach (KeyValuePair <float, RailEntityBase> entry in entryList)
            {
                RailViewEntry    latest = ackedByClient.GetLatest(entry.Value.Id);
                RailEntityServer entity = entry.Value as RailEntityServer;

                // Force a complete update if the entity is frozen so it unfreezes
                // TODO: Currently if we're unfreezing we force the server to send a
                //       delta with the FULL mutable dataset. There is probably a
                //       less wasteful option, like having clients send back
                //       what tick they last received a non-frozen packetToClient on.
                //       However, this would cause some tedious tick comparison.
                //       Should investigate a smarter way to handle this later.
                RailStateDelta delta = entity.ProduceDelta(
                    stateCreator,
                    latest.LastReceivedTick,
                    owner,
                    latest.IsFrozen);

                if (delta != null)
                {
                    activeList.Add(delta);
                }
            }
        }
Example #5
0
        /// <summary>
        /// Creates a delta between a state and a record. If forceUpdate is set
        /// to false, this function will return null if there is no change between
        /// the current and basis.
        /// </summary>
        internal static RailStateDelta CreateDelta(
            EntityId entityId,
            RailState current,
            RailStateRecord basisRecord,
            bool includeControllerData,
            bool includeImmutableData,
            Tick commandAck,
            Tick removedTick)
        {
            bool shouldReturn =
                includeControllerData ||
                includeImmutableData ||
                removedTick.IsValid;

            uint flags = RailState.FLAGS_ALL;

            if ((basisRecord != null) && (basisRecord.State != null))
            {
                flags = current.CompareMutableData(basisRecord.State);
            }
            if ((flags == 0) && (shouldReturn == false))
            {
                return(null);
            }

            RailState deltaState = RailState.Create(current.factoryType);

            deltaState.Flags = flags;
            deltaState.ApplyMutableFrom(current, deltaState.Flags);

            deltaState.HasControllerData = includeControllerData;
            if (includeControllerData)
            {
                deltaState.ApplyControllerFrom(current);
            }

            deltaState.HasImmutableData = includeImmutableData;
            if (includeImmutableData)
            {
                deltaState.ApplyImmutableFrom(current);
            }

            deltaState.RemovedTick = removedTick;
            deltaState.CommandAck  = commandAck;

            // We don't need to include a tick when sending -- it's in the packet
            RailStateDelta delta = RailResource.Instance.CreateDelta();

            delta.Initialize(Tick.INVALID, entityId, deltaState, false);
            return(delta);
        }
Example #6
0
        public void ApplyDelta(RailStateDelta delta)
        {
            RailState deltaState = delta.State;

            HasImmutableData = delta.HasImmutableData || HasImmutableData;
            if (deltaState.HasImmutableData)
            {
                DataSerializer.ApplyImmutableFrom(deltaState.DataSerializer);
            }

            DataSerializer.ApplyMutableFrom(deltaState.DataSerializer, deltaState.Flags);

            DataSerializer.ResetControllerData();
            if (deltaState.HasControllerData)
            {
                DataSerializer.ApplyControllerFrom(deltaState.DataSerializer);
            }

            HasControllerData = delta.HasControllerData;
        }
Example #7
0
        internal void ApplyDelta(RailStateDelta delta)
        {
            RailState deltaState = delta.State;

            this.ApplyMutableFrom(deltaState, deltaState.Flags);

            this.ResetControllerData();
            if (deltaState.HasControllerData)
            {
                this.ApplyControllerFrom(deltaState);
            }
            this.HasControllerData = delta.HasControllerData;

            this.HasImmutableData =
                delta.HasImmutableData || this.HasImmutableData;
            if (deltaState.HasImmutableData)
            {
                this.ApplyImmutableFrom(deltaState);
            }
        }
Example #8
0
    private void UpdateControlStatus(RailEntity entity, RailStateDelta delta)
    {
      // Can't infer anything if the delta is an empty frozen update
      if (delta.IsFrozen)
        return;

      if (delta.HasControllerData)
      {
        if (entity.Controller == null)
          this.serverPeer.GrantControl(entity);
      }
      else
      {
        if (entity.Controller != null)
          this.serverPeer.RevokeControl(entity);
      }
    }
Example #9
0
    private void ProcessDelta(RailStateDelta delta)
    {
      RailEntity entity;
      if (this.knownEntities.TryGetValue(delta.EntityId, out entity) == false)
      {
        RailDebug.Assert(delta.IsFrozen == false, "Frozen unknown entity");
        if (delta.IsFrozen)
          return;
          
        entity = delta.ProduceEntity();
        entity.AssignId(delta.EntityId);
        this.pendingEntities.Add(entity.Id, entity);
        this.knownEntities.Add(entity.Id, entity);
      }

      entity.ReceiveDelta(delta);
      this.UpdateControlStatus(entity, delta);
    }
Example #10
0
        internal static RailStateDelta DecodeDelta(
            RailBitBuffer buffer,
            Tick packetTick)
        {
            RailStateDelta delta = RailResource.Instance.CreateDelta();
            RailState      state = null;

            // Read: [EntityId]
            EntityId entityId = buffer.ReadEntityId();

            // Read: [IsFrozen]
            bool isFrozen = buffer.ReadBool();

            if (isFrozen == false)
            {
                // Read: [FactoryType]
                int factoryType = buffer.ReadInt(RailState.FactoryTypeCompressor);
                state = RailState.Create(factoryType);

                // Read: [IsRemoved]
                bool isRemoved = buffer.ReadBool();

                if (isRemoved)
                {
                    // Read: [DestroyedTick]
                    state.RemovedTick = buffer.ReadTick();

                    // End Read
                }
                else
                {
                    // Read: [HasControllerData]
                    state.HasControllerData = buffer.ReadBool();

                    // Read: [HasImmutableData]
                    state.HasImmutableData = buffer.ReadBool();

                    // Read: [Flags]
                    state.Flags = buffer.Read(state.FlagBits);

                    // Read: [Mutable Data]
                    state.DecodeMutableData(buffer, state.Flags);

                    if (state.HasControllerData)
                    {
                        // Read: [Controller Data]
                        state.DecodeControllerData(buffer);

                        // Read: [Command Ack]
                        state.CommandAck = buffer.ReadTick();
                    }

                    if (state.HasImmutableData)
                    {
                        // Read: [Immutable Data]
                        state.DecodeImmutableData(buffer);
                    }
                }
            }

            delta.Initialize(packetTick, entityId, state, isFrozen);
            return(delta);
        }