update world meta/update mask debuging

This commit is contained in:
Mikhail 2023-05-27 22:15:25 +08:00
parent 1b8cf0f0e9
commit 77286fc00c
2 changed files with 87 additions and 15 deletions

View File

@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
@ -134,6 +136,7 @@ namespace DCFApixels.DragonECS
#endregion
#region Mask
[DebuggerTypeProxy(typeof(DebuggerProxy))]
public sealed class EcsMask
{
internal readonly Type _worldType;
@ -145,9 +148,36 @@ namespace DCFApixels.DragonECS
_inc = inc;
_exc = exc;
}
public override string ToString()
public override string ToString() => CreateLogString(_worldType, _inc, _exc);
private static string CreateLogString(Type worldType, int[] inc, int[] exc)
{
return $"Inc({string.Join(", ", _inc)}) Exc({string.Join(", ", _exc)})";
#if DEBUG
int worldID = WorldMetaStorage.GetWorldID(worldType);
string converter(int o) => EcsDebugUtility.GetGenericTypeName(WorldMetaStorage.GetComponentType(worldID, o), 1);
return $"Inc({string.Join(", ", inc.Select(converter))}) Exc({string.Join(", ", exc.Select(converter))})";
#else
return $"Inc({string.Join(", ", inc)}) Exc({string.Join(", ", exc)})"; // Release optimization
#endif
}
internal class DebuggerProxy
{
public readonly Type worldType;
public readonly int[] inc;
public readonly int[] exc;
public readonly Type[] incTypes;
public readonly Type[] excTypes;
public DebuggerProxy(EcsMask mask)
{
worldType = mask._worldType;
int worldID = WorldMetaStorage.GetWorldID(worldType);
inc = mask._inc;
exc = mask._exc;
Type converter(int o) => WorldMetaStorage.GetComponentType(worldID, o);
incTypes = inc.Select(converter).ToArray();
excTypes = exc.Select(converter).ToArray();
}
public override string ToString() => CreateLogString(worldType, inc, exc);
}
}
#endregion

View File

@ -72,7 +72,7 @@ namespace DCFApixels.DragonECS
Worlds[uniqueID] = this;
}
_worldTypeID = WorldMetaStorage.GetWorldId(Archetype);
_worldTypeID = WorldMetaStorage.GetWorldID(Archetype);
_entityDispenser = new IntDispenser(0);
_nullPool = EcsNullPool.instance;
@ -376,31 +376,33 @@ namespace DCFApixels.DragonECS
internal EcsWorld(bool isIndexable) : base(isIndexable) { }
}
#region Utils
#region WorldMetaStorage
public static class WorldMetaStorage
{
private static List<Resizer> _resizer = new List<Resizer>();
private static int _tokenCount = 0;
private static int[] _componentCounts = new int[0];
private static int[] _subjectsCounts = new int[0];
private static WorldMeta[] _metas = new WorldMeta[0];
private static Dictionary<Type, int> _worldIds = new Dictionary<Type, int>();
private static class WorldIndex<TWorldArchetype>
{
public static int id = GetWorldId(typeof(TWorldArchetype));
public static int id = GetWorldID(typeof(TWorldArchetype));
}
private static int GetToken()
{
_tokenCount++;
Array.Resize(ref _componentCounts, _tokenCount);
Array.Resize(ref _subjectsCounts, _tokenCount);
WorldMeta meta = new WorldMeta();
meta.id = _tokenCount;
Array.Resize(ref _metas, ++_tokenCount);
_metas[_tokenCount - 1] = meta;
foreach (var item in _resizer)
item.Resize(_tokenCount);
return _tokenCount - 1;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int GetWorldId(Type archetype)
public static int GetWorldID(Type archetype)
{
if(_worldIds.TryGetValue(archetype, out int id) == false)
if(!_worldIds.TryGetValue(archetype, out int id))
{
id = GetToken();
_worldIds.Add(archetype, id);
@ -415,6 +417,11 @@ namespace DCFApixels.DragonECS
public static int GetSubjectId<T>(int worldID) => Subject<T>.Get(worldID);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int GetExecutorId<T>(int worldID) => Executor<T>.Get(worldID);
public static bool IsComponentTypeDeclared(int worldID, Type type) => _metas[worldID].IsDeclaredType(type);
public static Type GetComponentType(int worldID, int componentID) => _metas[worldID].GetComponentType(componentID);
#region Resizer
private abstract class Resizer
{
public abstract void Resize(int size);
@ -428,6 +435,7 @@ namespace DCFApixels.DragonECS
Array.Resize(ref Executor<T>.ids, size);
}
}
#endregion
private static class Component<T>
{
public static int[] ids;
@ -443,7 +451,11 @@ namespace DCFApixels.DragonECS
{
ref int id = ref ids[token];
if (id < 0)
id = _componentCounts[token]++;
{
var meta = _metas[token];
id = meta.componentCount++;
meta.AddType(id, typeof(T));
}
return id;
}
}
@ -462,7 +474,7 @@ namespace DCFApixels.DragonECS
{
ref int id = ref ids[token];
if (id < 0)
id = _subjectsCounts[token]++;
id = _metas[token].subjectsCount++;
return id;
}
}
@ -481,10 +493,40 @@ namespace DCFApixels.DragonECS
{
ref int id = ref ids[token];
if (id < 0)
id = _subjectsCounts[token]++;
id = _metas[token].executorsCount++;
return id;
}
}
private class WorldMeta
{
public int id;
public int componentCount;
public int subjectsCount;
public int executorsCount;
private Type[] types;
private HashSet<Type> declaredComponentTypes;
public void AddType(int id, Type type)
{
if(types.Length <= id)
Array.Resize(ref types, id + 10);
types[id] = type;
declaredComponentTypes.Add(type);
}
public Type GetComponentType(int componentID) => types[componentID];
public bool IsDeclaredType(Type type) => declaredComponentTypes.Contains(type);
public WorldMeta()
{
types = new Type[10];
declaredComponentTypes = new HashSet<Type>();
}
}
}
#endregion