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);
}
ref DelayedOp delayedOd = ref _delayedOps[_delayedOpsCount];
ref DelayedOp delayedOd = ref _delayedOps[_delayedOpsCount++];
delayedOd.Entity = entityID;
delayedOd.Added = isAdd;
}
@ -108,6 +108,7 @@ namespace DCFApixels.DragonECS
Remove(op.Entity);
}
}
_delayedOpsCount = 0;
}
}
public Enumerator GetEnumerator()

View File

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

View File

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

View File

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

View File

@ -14,33 +14,41 @@ namespace DCFApixels.DragonECS
public void Init(EcsSession session)
{
var x1 = _world.GetFilter<Inc<TransfromCom, Velocity>>();
var x2 = _world.GetFilter<Inc<TransfromCom, View>>();
var x3 = _world.GetFilter<Inc<TransfromCom, Velocity>>();
var x4 = _world.GetFilter<Inc<TransfromCom, Velocity>>();
var x5 = _world.GetFilter<Inc<Velocity, TransfromCom>>();
int has1 = x1.GetHashCode();
int has2 = x2.GetHashCode();
int has3 = x3.GetHashCode();
int has4 = x4.GetHashCode();
int has5 = x5.GetHashCode();
Debug.Log("1 " + has1);
Debug.Log("2 " + has2);
Debug.Log("3 " + has3);
Debug.Log("4 " + has4);
Debug.Log("5 " + has5);
//var x1 = _world.GetFilter<Inc<TransfromCom, Velocity>>();
//var x2 = _world.GetFilter<Inc<TransfromCom, View>>();
//var x3 = _world.GetFilter<Inc<TransfromCom, Velocity>>();
//var x4 = _world.GetFilter<Inc<TransfromCom, Velocity>>();
//var x5 = _world.GetFilter<Inc<Velocity, TransfromCom>>();
//
//int has1 = x1.GetHashCode();
//int has2 = x2.GetHashCode();
//int has3 = x3.GetHashCode();
//int has4 = x4.GetHashCode();
//int has5 = x5.GetHashCode();
//
//Debug.Log("1 " + has1);
//Debug.Log("2 " + has2);
//Debug.Log("3 " + has3);
//Debug.Log("4 " + has4);
//Debug.Log("5 " + has5);
var e = _world.NewEntity();
e.Write<TransfromCom>().position = Vector3.zero;
e.Write<Velocity>().value = Vector3.one;
e.Write<View>().Ref = _sharedData.view1;
e.Write<EnemyTag>();
e = _world.NewEntity();
e.Write<TransfromCom>().position = Vector3.zero;
e.Write<Velocity>().value = Vector3.one;
e.Write<View>().Ref = _sharedData.view2;
e.Write<PlayerTag>();
var e2 = _world.NewEntity();
e2.Write<TransfromCom>().position = Vector3.zero;
e2.Write<Velocity>().value = Vector3.zero;
e2.Write<View>().Ref = _sharedData.view2;
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)
{
var x = _world.GetFilter<Inc<TransfromCom, Velocity>>();
foreach (var item in _world.GetFilter<Inc<TransfromCom, Velocity>>().Entities)
{
item.Write<TransfromCom>().position += item.Read<Velocity>().value * Time.deltaTime;