Skip to content

Commit 6b5f5e6

Browse files
committed
Updated EntityLayout component storage for better memory usage.
1 parent ee38dc2 commit 6b5f5e6

5 files changed

Lines changed: 64 additions & 37 deletions

File tree

EntitiesDb/Data/Boxed.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace EntitiesDb;
2+
3+
internal sealed class Boxed<T> where T : unmanaged
4+
{
5+
public T Value;
6+
}

EntitiesDb/Data/ComponentMetaData.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,8 @@ public void SetComponent(Chunk chunk, int listOffset, int listIndex, object valu
6868
SetComponent(chunk.GetComponent(listOffset, listIndex, Size), value);
6969
}
7070

71+
public abstract void SetBuffer(Chunk chunk, int listOffset, int listIndex, object list, bool overwrite);
7172
public abstract void SetComponent(void* destination, object component);
72-
73-
public abstract void SetComponentBuffer(Chunk chunk, int listOffset, int listIndex, object list, bool overwrite);
7473
}
7574

7675
internal unsafe sealed class ComponentMetaData<T> : ComponentMetaData where T : unmanaged
@@ -114,7 +113,13 @@ public override void OnRemoveComponent(EventDispatcher eventDispatcher, uint ent
114113
eventDispatcher.OnRemoveComponent(entityId, ref component);
115114
}
116115

117-
public override unsafe void SetComponent(void* destination, object component) => *(T*)destination = (T)component;
116+
public override unsafe void SetComponent(void* destination, object component)
117+
{
118+
T value;
119+
if (component is Boxed<T> boxed) value = boxed.Value;
120+
else value = (T)component;
121+
*(T*)destination = value;
122+
}
118123

119124
private static int? GetInternalCapacity(Type type)
120125
{
@@ -132,7 +137,7 @@ private static bool IsZeroSize(Type type)
132137
return zeroSize;
133138
}
134139

135-
public override void SetComponentBuffer(Chunk chunk, int listOffset, int listIndex, object list, bool overwrite)
140+
public override void SetBuffer(Chunk chunk, int listOffset, int listIndex, object list, bool overwrite)
136141
{
137142
var typedList = (List<T>)list;
138143
ref var buffer = ref chunk.GetComponent<ComponentBuffer<T>>(listOffset, listIndex, Stride);

EntitiesDb/EntitiesDb.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<PackageLicenseExpression>MIT</PackageLicenseExpression>
1010
<Copyright>2022, Unnamed Studios, LLC</Copyright>
1111
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
12-
<VersionPrefix>2.1.1</VersionPrefix>
12+
<VersionPrefix>2.1.2</VersionPrefix>
1313
<Version>$(VersionPrefix)</Version>
1414
<AssemblyVersion>$(VersionPrefix)</AssemblyVersion>
1515
<FileVersion>$(VersionPrefix)</FileVersion>

EntitiesDb/EntityDatabase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1340,7 +1340,7 @@ private void SetComponentData(EntityReference entityReference, EntityLayout enti
13401340
if (metaData.Bufferable)
13411341
{
13421342
var overwrite = sourceArchetype?.ContainsType(pair.Key) ?? false;
1343-
metaData.SetComponentBuffer(chunk, listOffset, entityReference.Indices.ListIndex, pair.Value, overwrite);
1343+
metaData.SetBuffer(chunk, listOffset, entityReference.Indices.ListIndex, pair.Value, overwrite);
13441344
}
13451345
else
13461346
{

EntitiesDb/EntityLayout.cs

Lines changed: 47 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,6 @@ public sealed class EntityLayout
1111
public IEnumerable<KeyValuePair<Type, object>> Added => _added;
1212
public IEnumerable<Type> Removed => _removed;
1313

14-
/// <summary>
15-
/// Defines a component to be added.
16-
/// Overwrites any previous Add or Remove of the same type.
17-
/// </summary>
18-
/// <typeparam name="T">Component type</typeparam>
19-
/// <param name="component">The component to add</param>
20-
/// <exception cref="BufferableException"></exception>
21-
public void AddComponent<T>(T? component = default) where T : unmanaged
22-
{
23-
var metaData = ComponentMetaData<T>.Instance;
24-
if (metaData.Bufferable) throw new BufferableException(typeof(T));
25-
_removed.Remove(typeof(T));
26-
_added[typeof(T)] = component;
27-
}
28-
2914
/// <summary>
3015
/// Defines a buffer component to be added.
3116
/// Overwrites any previous buffer Add or Remove of the same type.
@@ -40,31 +25,32 @@ public void AddBuffer<T>(ReadOnlySpan<T> components) where T : unmanaged
4025
if (metaData.ZeroSize) throw new ZeroSizeBufferException(typeof(T));
4126
if (!metaData.Bufferable) throw new InvalidBufferableException(typeof(T));
4227
_removed.Remove(typeof(T));
43-
SetBufferComponents(metaData.Type, components);
28+
SetBuffer(metaData.Type, components);
4429
}
4530

46-
/// <summary>
47-
/// Clears Added and Removed components
48-
/// </summary>
49-
public void Clear()
50-
{
51-
_added.Clear();
52-
_removed.Clear();
53-
}
54-
5531
/// <summary>
56-
/// Defines a component to be removed.
32+
/// Defines a component to be added.
5733
/// Overwrites any previous Add or Remove of the same type.
5834
/// </summary>
5935
/// <typeparam name="T">Component type</typeparam>
36+
/// <param name="component">The component to add</param>
6037
/// <exception cref="BufferableException"></exception>
61-
public void RemoveComponent<T>() where T : unmanaged
38+
public void AddComponent<T>(T component = default) where T : unmanaged
6239
{
6340
var metaData = ComponentMetaData<T>.Instance;
6441
if (metaData.Bufferable) throw new BufferableException(typeof(T));
65-
_added.Remove(typeof(T));
66-
_removed.Add(typeof(T));
67-
}
42+
_removed.Remove(typeof(T));
43+
SetComponent(metaData.Type, component);
44+
}
45+
46+
/// <summary>
47+
/// Clears Added and Removed components
48+
/// </summary>
49+
public void Clear()
50+
{
51+
_added.Clear();
52+
_removed.Clear();
53+
}
6854

6955
/// <summary>
7056
/// Defines a buffer component to be removed.
@@ -83,7 +69,21 @@ public void RemoveBuffer<T>() where T : unmanaged
8369
_removed.Add(bufferType);
8470
}
8571

86-
private void SetBufferComponents<T>(Type componentType, ReadOnlySpan<T> components) where T : unmanaged
72+
/// <summary>
73+
/// Defines a component to be removed.
74+
/// Overwrites any previous Add or Remove of the same type.
75+
/// </summary>
76+
/// <typeparam name="T">Component type</typeparam>
77+
/// <exception cref="BufferableException"></exception>
78+
public void RemoveComponent<T>() where T : unmanaged
79+
{
80+
var metaData = ComponentMetaData<T>.Instance;
81+
if (metaData.Bufferable) throw new BufferableException(typeof(T));
82+
_added.Remove(typeof(T));
83+
_removed.Add(typeof(T));
84+
}
85+
86+
private void SetBuffer<T>(Type componentType, ReadOnlySpan<T> components) where T : unmanaged
8787
{
8888
// re-use existing list if available
8989
List<T> list;
@@ -103,6 +103,22 @@ private void SetBufferComponents<T>(Type componentType, ReadOnlySpan<T> componen
103103
list.Add(components[i]);
104104
}
105105
}
106+
107+
private void SetComponent<T>(Type componentType, T component) where T : unmanaged
108+
{
109+
// re-use existing boxed if available
110+
Boxed<T> boxed;
111+
if (!_added.TryGetValue(componentType, out var boxedObject))
112+
{
113+
boxed = (Boxed<T>)boxedObject;
114+
}
115+
else
116+
{
117+
boxed = new Boxed<T>();
118+
_added.Add(typeof(T), boxed);
119+
}
120+
boxed.Value = component;
121+
}
106122
}
107123
}
108124

0 commit comments

Comments
 (0)