Skip to content

Commit

Permalink
Fixed an bug where CommandBuffer did not clear correctly. Added a `…
Browse files Browse the repository at this point in the history
…AddOrGet` method to ensure the existance of an component.
  • Loading branch information
genaray committed Apr 23, 2023
1 parent 3da792f commit 5a2937f
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 8 deletions.
2 changes: 1 addition & 1 deletion src/Arch/Core/CommandBuffer/SparseSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public ref T Get<T>(int index)
/// </summary>
public void Clear()
{
for (var index = 0; index < Size; index++)
for (var index = 0; index < Entities.Length; index++)
{
Entities[index] = -1;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Arch/Core/CommandBuffer/StructuralSparseSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public bool Contains(int index)
/// </summary>
public void Clear()
{
for (var index = 0; index < Size; index++)
for (var index = 0; index < Entities.Length; index++)
{
Entities[index] = -1;
}
Expand Down
14 changes: 14 additions & 0 deletions src/Arch/Core/Extensions/EntityExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,20 @@ public static ref T TryGetRef<T>(this in Entity entity, out bool exists)
return ref world.TryGetRef<T>(entity, out exists);
}

/// <summary>
/// Ensures the existance of an component on an <see cref="Entity"/>.
/// </summary>
/// <typeparam name="T">The component type.</typeparam>
/// <param name="entity">The <see cref="Entity"/>.</param>
/// <param name="cmp">The component value used if its being added.</param>
/// <returns>A reference to the component.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref T AddOrGet<T>(this in Entity entity, T cmp = default)
{
var world = World.Worlds[entity.WorldId];
return ref world.AddOrGet(entity, cmp);
}

/// <summary>
/// Adds an new component to the <see cref="Entity"/> and moves it to the new <see cref="Archetype"/>.
/// </summary>
Expand Down
35 changes: 29 additions & 6 deletions src/Arch/Core/World.cs
Original file line number Diff line number Diff line change
Expand Up @@ -929,13 +929,15 @@ public ref T Get<T>(Entity entity)
public bool TryGet<T>(Entity entity, out T component)
{
component = default;
if (!Has<T>(entity))

var slot = EntityInfo.GetSlot(entity.Id);
var archetype = EntityInfo.GetArchetype(entity.Id);

if (!archetype.Has<T>())
{
return false;
}

var slot = EntityInfo.GetSlot(entity.Id);
var archetype = EntityInfo.GetArchetype(entity.Id);
component = archetype.Get<T>(ref slot);
return true;
}
Expand All @@ -950,16 +952,37 @@ public bool TryGet<T>(Entity entity, out T component)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref T TryGetRef<T>(Entity entity, out bool exists)
{
if (!(exists = Has<T>(entity)))
var slot = EntityInfo.GetSlot(entity.Id);
var archetype = EntityInfo.GetArchetype(entity.Id);

if (!(exists = archetype.Has<T>()))
{
return ref Unsafe.NullRef<T>();
}

var slot = EntityInfo.GetSlot(entity.Id);
var archetype = EntityInfo.GetArchetype(entity.Id);
return ref archetype.Get<T>(ref slot);
}

/// <summary>
/// Ensures the existence of an component on an <see cref="Entity"/>.
/// </summary>
/// <typeparam name="T">The component type.</typeparam>
/// <param name="entity">The <see cref="Entity"/>.</param>
/// <param name="cmp">The component value used if its being added.</param>
/// <returns>A reference to the component.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref T AddOrGet<T>(Entity entity, T cmp = default)
{
ref var component = ref TryGetRef<T>(entity, out var exists);
if (exists)
{
return ref component;
}

Add(entity, cmp);
return ref Get<T>(entity);
}

/// <summary>
/// Adds an new component to the <see cref="Entity"/> and moves it to the new <see cref="Archetype"/>.
/// </summary>
Expand Down

0 comments on commit 5a2937f

Please sign in to comment.