using System.Collections.Generic; using DotRecast.Core.Collections; using JNGame.Math; using JNGame.Sync.Entity; using JNGame.Sync.Frame.Entity.Components; using JNGame.Sync.State.Tile; using JNGame.Sync.State.Tile.Entity; using NotImplementedException = System.NotImplementedException; namespace JNGame.Sync.System.Data { public interface ISTileDataSystem { /// /// 清除指定区域数据 /// public void ClearTileData(int index); /// /// 获取有权限的全部字节 /// public Dictionary GetHostDataBytes(); /// /// 获取指定区块的全部字节 /// public Dictionary GetTileDataBytes(int index); } public abstract class ISTileData : ISStateData { public abstract bool IsHost { get; } public JNTileEntity Entity; /// /// 绑定实体到数据 (销毁数据时顺带销毁实体) /// /// public void BindEntity(JNTileEntity entity) { Entity = entity; } /// /// 获取数据位置(用于区块清除) /// public abstract LVector3 GetDataPosition(); } /// /// 支持区块的数据类 /// public abstract class STileDataSystem : SStateDataSystem,ISTileDataSystem where T : ISTileData,new() where E : JNTileEntity, new() { public abstract JNTileContext NodeContext { get; } protected STileDataSystem(SStateDataEnum type) : base(type) { } public override void OnUByteUpdate(Dictionary bytes) { base.OnUByteUpdate(bytes); if (isServer) { OnDataSyncContext(); } } /// /// 将数据Data同步到Context /// protected virtual void OnDataSyncContext() { Dictionary lIsTileData; lock (Data) { lIsTileData = new Dictionary(Data); } NodeContext.GetEntities().ForEach(child => { //如果有则删除 if (lIsTileData.Remove(child.Id,out var data)) { //同步不属于自己的实体 if (!child.IsHost) { //并且同步属性到实体中 child.TileSyncData(data); } } }); //将数据同步到实体中 foreach (var keyValue in lIsTileData) { var entity = NodeContext.TileSyncCreate(keyValue.Key); entity?.TileSyncData(keyValue.Value); //将实体绑定到数据中 keyValue.Value.BindEntity(entity); } } //只更新有权限的实体 public override void Update(T data) { if (!data.IsHost) return; base.Update(data); } public override void Add(T data) { if (!data.IsHost) return; base.Add(data); } /// /// 判断数据是否在区块内 /// public bool IsTileInside(int tileId,T data) { var index = -1; if (Sync is JNSSTileClientService clientService) { index = clientService.GetTileIndex(data.GetDataPosition()); } if (Sync is JNSSTileServerService serverService) { index = serverService.GetTileIndex(data.GetDataPosition()); } return index == tileId; } public void ClearTileData(int index) { lock (Data) { //需要删除的数据Id var ids = new List(); Data.ForEach(child => { if (IsTileInside(index,child.Value)) ids.Add(child.Key); }); //删除数据和实体 ids.ForEach(child => { //销毁实体 Data[child].Entity?.Destroy(); //销毁数据 Data.Remove(child); }); } } public Dictionary GetHostDataBytes() { var data = new Dictionary(); lock (Data) { Data.ForEach(child => { if (child.Value.IsHost) { data[child.Key] = child.Value.GetByte(); } }); } return data; } public Dictionary GetTileDataBytes(int index) { var data = new Dictionary(); lock (Data) { Data.ForEach(child => { if (IsTileInside(index,child.Value)) { data[child.Key] = child.Value.GetByte(); } }); } return data; } } }