Fixes / First working version

This commit is contained in:
Mikhail 2023-03-13 04:32:24 +08:00
parent c3e55cb10b
commit 94dc93d7fa
6 changed files with 112 additions and 62 deletions

View File

@ -61,7 +61,7 @@ namespace DCFApixels.DragonECS
{ {
Array.Resize(ref _delayedOps, _delayedOps.Length << 1); Array.Resize(ref _delayedOps, _delayedOps.Length << 1);
} }
ref DelayedOp delayedOd = ref _delayedOps[_delayedOpsCount]; ref DelayedOp delayedOd = ref _delayedOps[_delayedOpsCount++];
delayedOd.Entity = entityID; delayedOd.Entity = entityID;
delayedOd.Added = isAdd; delayedOd.Added = isAdd;
} }
@ -108,6 +108,7 @@ namespace DCFApixels.DragonECS
Remove(op.Entity); Remove(op.Entity);
} }
} }
_delayedOpsCount = 0;
} }
} }
public Enumerator GetEnumerator() public Enumerator GetEnumerator()

View File

@ -23,6 +23,23 @@ namespace DCFApixels.DragonECS
public ref readonly T Read(int entity); public ref readonly T Read(int entity);
public new ref T Write(int entity); public new ref T Write(int entity);
} }
public class EcsNullPool : IEcsPool
{
private readonly IEcsWorld _source;
public EcsNullPool(IEcsWorld source)
{
_source = source;
}
public IEcsWorld World => _source;
public int ID => -1;
public void Del(int index) { }
public bool Has(int index) => false;
public void Write(int index) { }
}
public class EcsPool<T> : IEcsPool<T> public class EcsPool<T> : IEcsPool<T>
where T : struct where T : struct
{ {
@ -37,9 +54,10 @@ namespace DCFApixels.DragonECS
#endregion #endregion
#region Constructors #region Constructors
public EcsPool(IEcsWorld source, int capacity) public EcsPool(IEcsWorld source, int id, int capacity)
{ {
_source = source; _source = source;
_id = id;
_sparseSet = new SparseSet(capacity, capacity); _sparseSet = new SparseSet(capacity, capacity);
_denseItems =new T[capacity]; _denseItems =new T[capacity];
@ -50,28 +68,29 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref readonly T Read(int entity) public ref readonly T Read(int entity)
{ {
return ref _denseItems[_sparseSet[entity]]; return ref _denseItems[_sparseSet.IndexOf(entity)];
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref T Write(int entity) public ref T Write(int entity)
{ {
if (_sparseSet.Contains(entity)) if (_sparseSet.Contains(entity))
{ {
return ref _denseItems[_sparseSet[entity]]; return ref _denseItems[_sparseSet.IndexOf(entity)];
} }
else else
{ {
_sparseSet.Add(entity); _sparseSet.Add(entity);
_sparseSet.Normalize(ref _denseItems); _sparseSet.Normalize(ref _denseItems);
_source.OnEntityComponentAdded(entity, _id); _source.OnEntityComponentAdded(entity, _id);
return ref _denseItems[_sparseSet.IndexOf(entity)]; int indexof = _sparseSet.IndexOf(entity);
return ref _denseItems[indexof];
} }
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Has(int entity) public bool Has(int entity)
{ {
return _sparseSet.IndexOf(entity) > 0; return _sparseSet.IndexOf(entity) >= 0;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Del(int entity) public void Del(int entity)
@ -81,7 +100,7 @@ namespace DCFApixels.DragonECS
} }
#endregion #endregion
#region IEcsFieldPool #region IEcsPool
void IEcsPool.Write(int index) void IEcsPool.Write(int index)
{ {
Write(index); Write(index);

View File

@ -1,9 +1,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Text; using System.Text;
using System.Threading.Tasks;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {
@ -24,6 +24,7 @@ namespace DCFApixels.DragonECS
public EcsFilter GetFilter<TInc>() where TInc : struct, IInc; public EcsFilter GetFilter<TInc>() where TInc : struct, IInc;
public EcsFilter GetFilter<TInc, TExc>() where TInc : struct, IInc where TExc : struct, IExc; public EcsFilter GetFilter<TInc, TExc>() where TInc : struct, IInc where TExc : struct, IExc;
public ent NewEntity(); public ent NewEntity();
public void DelEntity(int entityID);
public void Destroy(); public void Destroy();
public bool IsMaskCompatible(EcsMask mask, int entity); public bool IsMaskCompatible(EcsMask mask, int entity);
@ -33,6 +34,14 @@ namespace DCFApixels.DragonECS
internal void OnEntityComponentRemoved(int entityID, int changedPoolID); internal void OnEntityComponentRemoved(int entityID, int changedPoolID);
} }
public static class IEcsWorldExt
{
public static void DelEntity(this IEcsWorld self, ent entity)
{
self.DelEntity(entity.id);
}
}
public abstract class EcsWorld public abstract class EcsWorld
{ {
@ -58,6 +67,7 @@ namespace DCFApixels.DragonECS
private short[] _componentCounts; private short[] _componentCounts;
private IEcsPool[] _pools; private IEcsPool[] _pools;
private EcsNullPool _nullPool;
private List<EcsFilter>[] _filtersByIncludedComponents; private List<EcsFilter>[] _filtersByIncludedComponents;
private List<EcsFilter>[] _filtersByExcludedComponents; private List<EcsFilter>[] _filtersByExcludedComponents;
@ -74,7 +84,9 @@ namespace DCFApixels.DragonECS
public EcsWorld() public EcsWorld()
{ {
_entityDispenser = new IntDispenser(); _entityDispenser = new IntDispenser();
_nullPool = new EcsNullPool(this);
_pools = new IEcsPool[512]; _pools = new IEcsPool[512];
Array.Fill(_pools, _nullPool);
_gens = new short[512]; _gens = new short[512];
_filters = new EcsFilter[64]; _filters = new EcsFilter[64];
_entities = new EcsGroup(this, 512); _entities = new EcsGroup(this, 512);
@ -90,17 +102,21 @@ namespace DCFApixels.DragonECS
if (uniqueID >= _pools.Length) if (uniqueID >= _pools.Length)
{ {
int oldCapacity = _pools.Length;
Array.Resize(ref _pools, ComponentType.Capacity); Array.Resize(ref _pools, ComponentType.Capacity);
Array.Fill(_pools, _nullPool, oldCapacity, oldCapacity - _pools.Length);
Array.Resize(ref _filtersByIncludedComponents, ComponentType.Capacity); Array.Resize(ref _filtersByIncludedComponents, ComponentType.Capacity);
Array.Resize(ref _filtersByExcludedComponents, ComponentType.Capacity); Array.Resize(ref _filtersByExcludedComponents, ComponentType.Capacity);
} }
if (_pools[uniqueID] == null) if (_pools[uniqueID] == _nullPool)
{ {
_pools[uniqueID] = new EcsPool<T>(this, 512); _pools[uniqueID] = new EcsPool<T>(this, ComponentType<T>.uniqueID, 512);
} }
return (EcsPool<T>)_pools[uniqueID]; return (EcsPool<T>)_pools[uniqueID];
} }
#endregion #endregion
#region GetFilter #region GetFilter
@ -124,33 +140,42 @@ namespace DCFApixels.DragonECS
private EcsFilter NewFilter(EcsMask mask, int capacirty = 512) private EcsFilter NewFilter(EcsMask mask, int capacirty = 512)
{ {
var newFilter = new EcsFilter(this, mask, capacirty); var filter = new EcsFilter(this, mask, capacirty);
for (int i = 0; i < mask.IncCount; i++) for (int i = 0; i < mask.IncCount; i++)
{ {
int poolid = mask.Inc[i]; int componentID = mask.Inc[i];
var list = _filtersByIncludedComponents[poolid]; var list = _filtersByIncludedComponents[componentID];
if (list == null) if (list == null)
{ {
list = new List<EcsFilter>(8); list = new List<EcsFilter>(8);
_filtersByIncludedComponents[poolid] = list; _filtersByIncludedComponents[componentID] = list;
} }
list.Add(newFilter); list.Add(filter);
} }
for (int i = 0; i < mask.ExcCount; i++) for (int i = 0; i < mask.ExcCount; i++)
{ {
int poolid = mask.Exc[i]; int componentID = mask.Exc[i];
var list = _filtersByExcludedComponents[poolid]; var list = _filtersByExcludedComponents[componentID];
if (list == null) if (list == null)
{ {
list = new List<EcsFilter>(8); list = new List<EcsFilter>(8);
_filtersByExcludedComponents[poolid] = list; _filtersByExcludedComponents[componentID] = list;
}
list.Add(filter);
}
// scan exist entities for compatibility with new filter.
foreach (var item in _entities)
{
if (IsMaskCompatible(mask, item.id))
{
filter.Add(item.id);
} }
list.Add(newFilter);
} }
return newFilter;
return filter;
} }
#endregion #endregion
@ -164,21 +189,17 @@ namespace DCFApixels.DragonECS
for (int i = 0, iMax = mask.IncCount; i < iMax; i++) for (int i = 0, iMax = mask.IncCount; i < iMax; i++)
{ {
if (!_pools[mask.Inc[i]].Has(entity)) if (!_pools[mask.Inc[i]].Has(entity))
{
return false; return false;
}
} }
for (int i = 0, iMax = mask.ExcCount; i < iMax; i++) for (int i = 0, iMax = mask.ExcCount; i < iMax; i++)
{ {
if (_pools[mask.Exc[i]].Has(entity)) if (_pools[mask.Exc[i]].Has(entity))
{
return false; return false;
}
} }
return true; return true;
} }
public bool IsMaskCompatibleWithout(EcsMask mask, int entity, int otherPoolID) public bool IsMaskCompatibleWithout(EcsMask mask, int entity, int otherComponentID)
{ {
#if DEBUG || !DCFAECS_NO_SANITIZE_CHECKS #if DEBUG || !DCFAECS_NO_SANITIZE_CHECKS
if (mask.WorldArchetypeType != typeof(TArchetype)) if (mask.WorldArchetypeType != typeof(TArchetype))
@ -186,29 +207,25 @@ namespace DCFApixels.DragonECS
#endif #endif
for (int i = 0, iMax = mask.IncCount; i < iMax; i++) for (int i = 0, iMax = mask.IncCount; i < iMax; i++)
{ {
int poolID = mask.Inc[i]; int componentID = mask.Inc[i];
if (poolID == otherPoolID || !_pools[poolID].Has(entity)) if (componentID == otherComponentID || !_pools[componentID].Has(entity))
{
return false; return false;
}
} }
for (int i = 0, iMax = mask.ExcCount; i < iMax; i++) for (int i = 0, iMax = mask.ExcCount; i < iMax; i++)
{ {
int poolID = mask.Exc[i]; int poolID = mask.Exc[i];
if (poolID != otherPoolID && _pools[poolID].Has(entity)) if (poolID != otherComponentID && _pools[poolID].Has(entity))
{
return false; return false;
}
} }
return true; return true;
} }
#endregion #endregion
#region EntityChangedReact #region EntityChangedReact
void IEcsWorld.OnEntityComponentAdded(int entityID, int changedPoolID) void IEcsWorld.OnEntityComponentAdded(int entityID, int componentID)
{ {
var includeList = _filtersByIncludedComponents[changedPoolID]; var includeList = _filtersByIncludedComponents[componentID];
var excludeList = _filtersByExcludedComponents[changedPoolID]; var excludeList = _filtersByExcludedComponents[componentID];
if (includeList != null) if (includeList != null)
{ {
@ -224,7 +241,7 @@ namespace DCFApixels.DragonECS
{ {
foreach (var filter in excludeList) foreach (var filter in excludeList)
{ {
if (IsMaskCompatibleWithout(filter.Mask, entityID, changedPoolID)) if (IsMaskCompatibleWithout(filter.Mask, entityID, componentID))
{ {
filter.Remove(entityID); filter.Remove(entityID);
} }
@ -260,13 +277,19 @@ namespace DCFApixels.DragonECS
} }
#endregion #endregion
#region NewEntity #region NewEntity/DelEntity
public ent NewEntity() public ent NewEntity()
{ {
int entid = _entityDispenser.GetFree(); int entid = _entityDispenser.GetFree();
if(_gens.Length < entid) Array.Resize(ref _gens, _gens.Length << 1); _entities.Add(entid);
if (_gens.Length < entid) Array.Resize(ref _gens, _gens.Length << 1);
return new ent(entid, _gens[entid]++, id); return new ent(entid, _gens[entid]++, id);
} }
public void DelEntity(int entityID)
{
_entityDispenser.Release(entityID);
_entities.Remove(entityID);
}
#endregion #endregion
#region Destroy #region Destroy

View File

@ -1,8 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine; using UnityEngine;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS

View File

@ -14,33 +14,41 @@ namespace DCFApixels.DragonECS
public void Init(EcsSession session) public void Init(EcsSession session)
{ {
var x1 = _world.GetFilter<Inc<TransfromCom, Velocity>>(); //var x1 = _world.GetFilter<Inc<TransfromCom, Velocity>>();
var x2 = _world.GetFilter<Inc<TransfromCom, View>>(); //var x2 = _world.GetFilter<Inc<TransfromCom, View>>();
var x3 = _world.GetFilter<Inc<TransfromCom, Velocity>>(); //var x3 = _world.GetFilter<Inc<TransfromCom, Velocity>>();
var x4 = _world.GetFilter<Inc<TransfromCom, Velocity>>(); //var x4 = _world.GetFilter<Inc<TransfromCom, Velocity>>();
var x5 = _world.GetFilter<Inc<Velocity, TransfromCom>>(); //var x5 = _world.GetFilter<Inc<Velocity, TransfromCom>>();
//
int has1 = x1.GetHashCode(); //int has1 = x1.GetHashCode();
int has2 = x2.GetHashCode(); //int has2 = x2.GetHashCode();
int has3 = x3.GetHashCode(); //int has3 = x3.GetHashCode();
int has4 = x4.GetHashCode(); //int has4 = x4.GetHashCode();
int has5 = x5.GetHashCode(); //int has5 = x5.GetHashCode();
//
Debug.Log("1 " + has1); //Debug.Log("1 " + has1);
Debug.Log("2 " + has2); //Debug.Log("2 " + has2);
Debug.Log("3 " + has3); //Debug.Log("3 " + has3);
Debug.Log("4 " + has4); //Debug.Log("4 " + has4);
Debug.Log("5 " + has5); //Debug.Log("5 " + has5);
var e = _world.NewEntity(); var e = _world.NewEntity();
e.Write<TransfromCom>().position = Vector3.zero; e.Write<TransfromCom>().position = Vector3.zero;
e.Write<Velocity>().value = Vector3.one;
e.Write<View>().Ref = _sharedData.view1; e.Write<View>().Ref = _sharedData.view1;
e.Write<EnemyTag>(); e.Write<EnemyTag>();
e = _world.NewEntity(); var e2 = _world.NewEntity();
e.Write<TransfromCom>().position = Vector3.zero; e2.Write<TransfromCom>().position = Vector3.zero;
e.Write<Velocity>().value = Vector3.one; e2.Write<Velocity>().value = Vector3.zero;
e.Write<View>().Ref = _sharedData.view2; e2.Write<View>().Ref = _sharedData.view2;
e.Write<PlayerTag>(); e2.Write<PlayerTag>();
var x1 = _world.GetFilter<Inc<TransfromCom, Velocity>>();
bool bb = _world.IsMaskCompatible(x1.Mask, e.id);
//has1 = x1.GetHashCode();
} }
} }
} }

View File

@ -12,6 +12,7 @@ namespace DCFApixels.DragonECS
public void Run(EcsSession session) public void Run(EcsSession session)
{ {
var x = _world.GetFilter<Inc<TransfromCom, Velocity>>();
foreach (var item in _world.GetFilter<Inc<TransfromCom, Velocity>>().Entities) foreach (var item in _world.GetFilter<Inc<TransfromCom, Velocity>>().Entities)
{ {
item.Write<TransfromCom>().position += item.Read<Velocity>().value * Time.deltaTime; item.Write<TransfromCom>().position += item.Read<Velocity>().value * Time.deltaTime;