update framework

This commit is contained in:
szy73711 committed 2022-11-13 02:16:19 +08:00
1 parent 3a1e97df6f
commit e3f449f183
31 files changed
+984 -307

No files matched your search

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3bcdf9c0cafed4d93834eace6041330f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,21 @@
using Unity.Collections.LowLevel.Unsafe;
namespace GameCore.LowLevel
{
public static class StructUtility
{
public static int OffsetOf<T, F>()
where T : struct
where F : struct
{
var fields = typeof(T).GetFields();
foreach (var f in fields)
{
if (f.DeclaringType == typeof(F))
return UnsafeUtility.GetFieldOffset(f);
}
return -1;
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: fde8ecf3379244d6885eb6d4ca9d8d31
timeCreated: 1668240297
@@ -1,5 +1,5 @@
{
"name": "TinyECS.Runtime",
"name": "nimin.lowlevel",
"rootNamespace": "",
"references": [
"Unity.Collections",
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: c2bd585c8e44341079d076e23cd9d3eb
guid: 10ae496f407b04f038c880a464f55c72
AssemblyDefinitionImporter:
externalObjects: {}
userData:
@@ -0,0 +1,15 @@
{
"name": "com.nimin.lowlevel",
"displayName": "GameCore LowLevel",
"version": "0.1.0",
"unity": "2021.3",
"description": "Low-level helper, contains custom collections",
"dependencies": {
"com.unity.collections": "1.2.4",
"com.unity.burst": "1.8.1"
},
"keywords": [
"LowLevel",
"Collections"
]
}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 5f9f2b0e6f5f7472e8088bca5daed5ee
PackageManifestImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,25 @@
using System;
namespace GameCore.TinyECS
{
public struct ComponentId
{
struct Inner<T> where T : unmanaged
{
public int id;
private Inner(int i) => id = i;
public static Inner<T> Instance = default;
}
static int currentId;
public static int Get<T>() where T : unmanaged
{
if (Inner<T>.Instance.id == 0)
{
Inner<T>.Instance.id = ++currentId;
}
return Inner<T>.Instance.id;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 27dc063854d0042ba9329b5bf058f2a6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -15,34 +15,12 @@ namespace GameCore.TinyECS
this.generation = generation;
}
public override string ToString()
{
return $"Entity<{type}>({index},{generation})";
}
public override string ToString() => $"Entity<{type}>({index},{generation})";
public bool Equals(Entity<TEnum> other) => type.Equals(other.type) && index == other.index && generation == other.generation;
public override bool Equals(object obj) => obj is Entity<TEnum> other && Equals(other);
public override int GetHashCode() => HashCode.Combine(type, index, generation);
public static bool operator ==(Entity<TEnum> lhs, Entity<TEnum> rhs) => lhs.Equals(rhs);
public static bool operator !=(Entity<TEnum> lhs, Entity<TEnum> rhs) => !(lhs == rhs);
public bool Equals(Entity<TEnum> other)
{
return type.Equals(other.type) && index == other.index && generation == other.generation;
}
public override bool Equals(object obj)
{
return obj is Entity<TEnum> other && Equals(other);
}
public override int GetHashCode()
{
return HashCode.Combine(type, index, generation);
}
public static bool operator ==(Entity<TEnum> lhs, Entity<TEnum> rhs)
{
return lhs.Equals(rhs);
}
public static bool operator !=(Entity<TEnum> lhs, Entity<TEnum> rhs)
{
return !(lhs == rhs);
}
}
}
@@ -0,0 +1,201 @@
using System;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using System.Diagnostics;
namespace GameCore.TinyECS
{
public partial struct EntityDataBlockMeta
{
public FixedList64Bytes<byte> componentIdToIndex;
public FixedList128Bytes<short> componentIdToOffset;
public int elementSize;
public int elementAlign;
}
public unsafe struct EntityDataBlockChain : IDisposable
{
public readonly EntityDataBlockMeta blockMeta;
private FixedList512Bytes<IntPtr> blockPtrList;
private int maxElementCountPerBlock;
private int elementCount;
public int BlockCount => blockPtrList.Length;
public int BlockCapacity => blockPtrList.Capacity;
public int ElementCount => elementCount;
public int MaxElementCount => MaxElementCountPerBlock * BlockCapacity;
public int MaxElementCountPerBlock => maxElementCountPerBlock;
public bool IsFull => elementCount == MaxElementCount;
public bool IsEmpty => elementCount == 0;
public EntityDataBlockChain(EntityDataBlockMeta blockMeta, int maxElementCountPerBlock)
{
this.blockMeta = blockMeta;
blockPtrList = default;
this.maxElementCountPerBlock = maxElementCountPerBlock;
elementCount = 0;
}
public void Dispose()
{
for (var i = BlockCount - 1; i >= 0; --i)
{
ReleaseBlock(i);
}
}
void AllocBlock()
{
var bufferSize = blockMeta.elementSize * maxElementCountPerBlock;
var ptr = UnsafeUtility.Malloc(bufferSize, blockMeta.elementAlign, Allocator.Persistent);
blockPtrList.Add((IntPtr)ptr);
}
void ReleaseBlock(int blockIndex)
{
var pBlock = (void*)blockPtrList[blockIndex];
if (pBlock != null)
{
UnsafeUtility.Free(pBlock, Allocator.Persistent);
blockPtrList.RemoveAt(blockIndex);
}
}
void* ElementPtrAt(int elementIndex)
{
var blockIndex = elementIndex / maxElementCountPerBlock;
var pBlock = blockPtrList[blockIndex];
return (byte*)pBlock + elementIndex * blockMeta.elementSize;
}
void* ComponentPtrAt<T>(int elementIndex) where T : unmanaged
{
var componentId = ComponentId.Get<T>();
var componentIndex = blockMeta.componentIdToIndex[componentId];
if (componentIndex > 0)
{
var pElement = ElementPtrAt(elementIndex);
return (byte*)pElement + blockMeta.componentIdToOffset[componentId];
}
return null;
}
[Conditional("DEBUG")]
void CheckElementIndex(int index)
{
if (index < 0 || index >= elementCount)
throw new IndexOutOfRangeException($"Invalid index: {index}");
}
[Conditional("DEBUG")]
void CheckBlockIndex(int index)
{
if (index < 0 || index > (elementCount / maxElementCountPerBlock))
throw new IndexOutOfRangeException($"Invalid index: {index}");
}
public void Clear()
{
elementCount = 0;
}
public void Add()
{
if (elementCount % maxElementCountPerBlock == 0)
{
if (IsFull)
throw new OutOfMemoryException("Block chain is full!");
var blockIndex = elementCount / maxElementCountPerBlock;
if (blockIndex >= BlockCount)
AllocBlock();
}
void* ptr = ElementPtrAt(elementCount);
UnsafeUtility.MemClear(ptr, blockMeta.elementSize);
elementCount++;
}
public void Remove(int index)
{
CheckElementIndex(index);
if (index != elementCount - 1)
{
var src = ElementPtrAt(elementCount - 1);
var dst = ElementPtrAt(index);
UnsafeUtility.MemCpy(dst, src, blockMeta.elementSize);
}
elementCount--;
}
public ref T GetData<T>(int index) where T : unmanaged
{
CheckElementIndex(index);
var pComponent = ComponentPtrAt<T>(index);
if (pComponent == null)
throw new Exception($"Invalid component type: {typeof(T)}");
return ref UnsafeUtility.AsRef<T>(pComponent);
}
public EntityDataBlockView AsBlockView(int blockIndex)
{
CheckBlockIndex(blockIndex);
var ptr = (void*)blockPtrList[blockIndex];
return new(ptr, blockMeta, maxElementCountPerBlock * blockIndex, elementCount);
}
}
public unsafe readonly struct EntityDataBlockView
{
private readonly void* ptr;
public readonly EntityDataBlockMeta meta;
public readonly int elementStartIndex;
public readonly int elementCount;
public EntityDataBlockView(void* ptr, EntityDataBlockMeta meta, int elementStartIndex, int elementCount)
{
this.ptr = ptr;
this.meta = meta;
this.elementStartIndex = elementStartIndex;
this.elementCount = elementCount;
}
void* ElementPtrAt(int elementIndex)
{
return (byte*)ptr + elementIndex * meta.elementSize;
}
void* ComponentPtrAt<T>(int elementIndex) where T : unmanaged
{
var componentId = ComponentId.Get<T>();
var componentIndex = meta.componentIdToIndex[componentId];
if (componentIndex > 0)
{
var pElement = ElementPtrAt(elementIndex);
return (byte*)pElement + meta.componentIdToOffset[componentId];
}
return null;
}
[Conditional("DEBUG")]
void CheckIndex(int index)
{
if (index < elementStartIndex || index >= elementStartIndex + elementCount)
throw new IndexOutOfRangeException($"Invalid index: {index}");
}
public ref T GetData<T>(int index) where T : unmanaged
{
var pComponent = ComponentPtrAt<T>(index);
if (pComponent == null)
throw new Exception($"Invalid component type: {typeof(T)}");
return ref UnsafeUtility.AsRef<T>(pComponent);
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 24392c1216204b6ea64acd57bb43441b
timeCreated: 1668251924
@@ -0,0 +1,45 @@
using System;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using System.Diagnostics;
using GameCore.LowLevel;
namespace GameCore.TinyECS
{
public partial struct EntityDataBlockMeta
{
public static EntityDataBlockMeta Create<T1>()
where T1 : unmanaged
{
var meta = new EntityDataBlockMeta();
meta.componentIdToIndex.Length = meta.componentIdToIndex.Capacity;
meta.componentIdToOffset.Length = meta.componentIdToOffset.Capacity;
var id1 = ComponentId.Get<T1>();
meta.componentIdToIndex[id1] = 1;
meta.componentIdToOffset[id1] = 0;
meta.elementSize = UnsafeUtility.SizeOf<T1>();
meta.elementAlign = UnsafeUtility.AlignOf<T1>();
return meta;
}
public static EntityDataBlockMeta Create<T1, T2>()
where T1 : unmanaged
where T2 : unmanaged
{
var meta = new EntityDataBlockMeta();
meta.componentIdToIndex.Length = meta.componentIdToIndex.Capacity;
meta.componentIdToOffset.Length = meta.componentIdToOffset.Capacity;
var id1 = ComponentId.Get<T1>();
var id2 = ComponentId.Get<T2>();
meta.componentIdToIndex[id1] = 1;
meta.componentIdToIndex[id2] = 2;
meta.componentIdToOffset[id1] = (short)StructUtility.OffsetOf<(T1, T2), T1>();
meta.componentIdToOffset[id2] = (short)StructUtility.OffsetOf<(T1, T2), T2>();
meta.elementSize = UnsafeUtility.SizeOf<(T1, T2)>();
meta.elementAlign = UnsafeUtility.AlignOf<(T2, T2)>();
return meta;
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c9227b743e78463b8df770cefc98fb18
timeCreated: 1668274486
@@ -0,0 +1,14 @@
using System;
using Unity.Collections;
using Unity.Mathematics;
namespace GameCore.TinyECS
{
public struct EntityDataSet : IDisposable
{
public void Dispose()
{
//TODO
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 842aeb285b0ae4d48af690621927f619
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,34 @@
{
"name": "nimin.tinyecs",
"rootNamespace": "",
"references": [
"Unity.Collections",
"Unity.Mathematics",
"nimin.lowlevel"
],
"includePlatforms": [
"Android",
"Editor",
"iOS",
"LinuxStandalone64",
"Lumin",
"macOSStandalone",
"PS4",
"Stadia",
"Switch",
"tvOS",
"WSA",
"WebGL",
"WindowsStandalone32",
"WindowsStandalone64",
"XboxOne"
],
"excludePlatforms": [],
"allowUnsafeCode": true,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 9cf4bf50619414a2296aa8fb1643a952
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+5 -5
View File
@@ -1,14 +1,14 @@
{
"name": "com.nimin.tinyecs",
"displayName": "Tiny ECS",
"displayName": "GameCore TinyECS",
"version": "0.1.0",
"unity": "2021.3",
"description": "Data oriented ECS famework",
"dependencies": {
"com.unity.collections": "1.2.4",
"com.unity.burst": "1.8.1"
"com.nimin.lowlevel": "0.1.0"
},
"keywords": [
"ECS", "JobSystem"
"ECS",
"JobSystem"
]
}
}