// src/AcDream.Core/Plugins/WorldGameState.cs using AcDream.Plugin.Abstractions; namespace AcDream.Core.Plugins; public sealed class WorldGameState : IGameState { private readonly List _entities = new(); private readonly Dictionary _indexById = new(); public IReadOnlyList Entities => _entities; /// /// Publish the current projection for an entity. Re-hydration replaces the /// prior snapshot instead of turning the current-state API into history. /// public void Add(WorldEntitySnapshot snapshot) { if (_indexById.TryGetValue(snapshot.Id, out int index)) { _entities[index] = snapshot; return; } _indexById.Add(snapshot.Id, _entities.Count); _entities.Add(snapshot); } /// /// Remove any snapshot with the given local Id. Used when the /// server re-sends CreateObject for an entity already known to /// acdream — the host deletes the old snapshot before adding the new /// one so plugins don't see stale duplicates. /// public bool RemoveById(uint id) { if (!_indexById.Remove(id, out int index)) return false; int lastIndex = _entities.Count - 1; if (index != lastIndex) { WorldEntitySnapshot moved = _entities[lastIndex]; _entities[index] = moved; _indexById[moved.Id] = index; } _entities.RemoveAt(lastIndex); return true; } public void Clear() { _entities.Clear(); _indexById.Clear(); } }