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;
}
}
}