internal void UnpackRevisionDatagram(PoolRevisionPayload payload, long offsetMilliseconds) { Context.Revision = payload.Revision; Context.ConnectionTimestampOffset = offsetMilliseconds; NetBuffer buffer = payload.RevisionData; while (buffer.Remaining >= (sizeof(byte) + sizeof(ushort))) { ushort entityID = buffer.ReadUShort(); ushort typeID = buffer.ReadVWidth(); // This could fail if not enough bytes remaining. while (entityID >= SyncSlots.Length) { ResizeSyncHandleArray(); } bool skipUpdate = false; SyncHandle handle = GetHandle(entityID); if (handle == null) { if (SyncSlots[entityID].Revision > Context.Revision) { // The revision contains content for a deleted entity. skipUpdate = true; } else { // We are talking about an new entity. SpawnEntity(entityID, typeID, Context.Revision); } } else if (handle.Sync.TypeID != typeID) { // We have a type missmatch. if (handle.Sync.Revision < Context.Revision) { // Entity already exists, but is incorrect type and wrong revision // Assume it should have been deleted and recreate it. RemoveHandle(entityID, Context.Revision); SpawnEntity(entityID, typeID, Context.Revision); } else { // Entity is new type, and has a newer revision. Do not disturb it. skipUpdate = true; } } if (skipUpdate) { EntityGenerator.GetEntityFactory(typeID).SkipFromBuffer(buffer); } else { SyncSlots[entityID].Handle.Sync.ReadFromBuffer(buffer, Context); } } }
internal Payload GenerateRevisionPayload(uint revision) { Context.Revision = revision; List <uint> updatedEntities = new List <uint>(); int size = 0; foreach (SyncHandle handle in SyncHandles) { if (handle.Sync.ContainsRevision(revision)) { size += sizeof(ushort) + NetBuffer.SizeofVWidth(handle.Sync.TypeID); size += handle.Sync.WriteToBufferSize(revision); updatedEntities.Add(handle.EntityID); } } if (updatedEntities.Count > 0) { PoolRevisionPayload payload = PoolRevisionPayload.Generate(this, revision, size, false); foreach (ushort entityID in updatedEntities) { SyncHandle handle = SyncSlots[entityID].Handle; payload.RevisionData.WriteUShort(entityID); payload.RevisionData.WriteVWidth(handle.Sync.TypeID); handle.Sync.WriteToBuffer(payload.RevisionData, Context); } return(payload); } return(null); }
private void SpawnEntity(ushort entityID, ushort typeID, uint revision) { SynchronisableEntity entity = EntityGenerator.GetEntityFactory(typeID).ConstructNewEntity(revision); SyncHandle handle = new SyncHandle(entity, entity.GetValue(), entityID); newHandles.Add(handle); AddHandle(handle); }
protected void RemoveHandle(ushort entityID, uint revision) { SyncHandle handle = SyncSlots[entityID].Handle; handle.State = SyncHandle.SyncState.Deleted; SyncHandles.Remove(handle); SyncSlots[entityID].Handle = null; SyncSlots[entityID].Revision = revision; }
public SyncHandle AddEntity(object instance) { ushort entityID = GetNextEntityID(); RuntimeTypeHandle typeHandle = instance.GetType().TypeHandle; SynchronisableEntity entity = EntityGenerator.GetEntityFactory(typeHandle).ConstructForExisting(instance); SyncHandle handle = new SyncHandle(entity, instance, entityID); AddHandle(handle); return(handle); }
internal void RemoveEntity(ushort entityID, uint revision) { SyncHandle handle = GetHandle(entityID); if (handle != null && handle.Sync.Revision < revision) { // only delete if the entity is not more up to date than the deletion revision RemoveHandle(entityID, revision); removedHandles.Add(handle); } }
protected void AddHandle(SyncHandle handle) { SyncSlots[handle.EntityID].Handle = handle; SyncHandles.Add(handle); }