Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Arch/Arch.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

<PackageId>Arch</PackageId>
<Title>Arch</Title>
<Version>2.0.0</Version>
<Version>2.1.0</Version>
<Authors>genaray</Authors>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<Description>A high performance c# net.7 and net.8 archetype based ECS ( Entity component system ).</Description>
Expand Down
7 changes: 3 additions & 4 deletions src/Arch/Buffer/SparseSet.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using Arch.Core;
using Arch.Core.Utils;
using Arch.Core.Extensions.Internal;

namespace Arch.Buffer;

Expand Down Expand Up @@ -88,9 +88,8 @@ public void Add(int index)
if (index >= Capacity)
{
// Calculate new array size that fits the passed index
var amountOfMultiplications = (int)Math.Ceiling(Math.Log((index+1) / (float)Capacity, 2.0f));
var newLength = (int)Math.Pow(2, amountOfMultiplications) * Capacity;
newLength = Math.Max(Capacity, newLength+1);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic was failing when trying to grow from capacity = 0 to anything different than capacity = 1.

Because capacity was being used as a denominator it was causing a division by 0 and amountOfMultiplications was undeflowing. Then the multiplication by Capacity neutralized that and made it 0 again, and newLength+1 made it work only for the case where the desired capacity was 1.

var newCapacity = MathExtensions.NextPowerOfTwo(index + 1);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new code uses bit shifting to find the next pow2 size without any floating point arithmetic.

var newLength = Math.Max(Capacity, newCapacity); // keep existing capacity if already larger

// Resize entities array
Array.Resize(ref Entities, newLength);
Expand Down
5 changes: 2 additions & 3 deletions src/Arch/Core/ComponentRegistry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,9 @@ private static ComponentType Add(Type type, int typeSize)
}

// Register and assign component id
var id = Size + 1;
meta = new ComponentType(id, typeSize);
meta = new ComponentType(Size, typeSize);
_typeToComponentType.Add(type, meta);
_types = _types.Add(id, type);
_types = _types.Add(Size, type);

Size++;
return meta;
Expand Down
4 changes: 2 additions & 2 deletions src/Arch/Core/Edges/World.Edges.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public partial class World
private Archetype GetOrCreateArchetypeByAddEdge(in ComponentType type, Archetype oldArchetype)
{
Archetype archetype;
var edgeIndex = type.Id - 1;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These -1 were compensating for the off-by-one error on ComponentRegistry.

var edgeIndex = type.Id;

if (!oldArchetype.HasAddEdge(edgeIndex))
{
Expand All @@ -42,7 +42,7 @@ private Archetype GetOrCreateArchetypeByAddEdge(in ComponentType type, Archetype
private Archetype GetOrCreateArchetypeByRemoveEdge(in ComponentType type, Archetype oldArchetype)
{
Archetype archetype;
var edgeIndex = type.Id - 1;
var edgeIndex = type.Id;

if (!oldArchetype.HasRemoveEdge(edgeIndex))
{
Expand Down
18 changes: 18 additions & 0 deletions src/Arch/Core/Extensions/Internal/MathExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,22 @@ public static int Max(int a, int b)
{
return a - ((a - b) & ((a - b) >> 31));
}


public static int NextPowerOfTwo(int x)
{
if (x <= 1)
{
return 1;
}

x--;
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
x++;
return x;
}
}
Loading