converting component storage to pack data and return refs
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
72a7f8bfbf
commit
98955f3048
|
@ -4,6 +4,11 @@ using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Encompass
|
namespace Encompass
|
||||||
{
|
{
|
||||||
|
public struct MutableComponentEntityPair<TComponent> where TComponent : struct, IComponent
|
||||||
|
{
|
||||||
|
public TComponent component;
|
||||||
|
}
|
||||||
|
|
||||||
internal class ComponentStore
|
internal class ComponentStore
|
||||||
{
|
{
|
||||||
private Dictionary<Type, TypedComponentStore> Stores = new Dictionary<Type, TypedComponentStore>(512);
|
private Dictionary<Type, TypedComponentStore> Stores = new Dictionary<Type, TypedComponentStore>(512);
|
||||||
|
@ -51,9 +56,9 @@ namespace Encompass
|
||||||
return ComponentBitSet.EntityBitArray(entityID);
|
return ComponentBitSet.EntityBitArray(entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TComponent Get<TComponent>(int entityID) where TComponent : struct, IComponent
|
public ref readonly TComponent Get<TComponent>(int entityID) where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
return Lookup<TComponent>().Get(entityID);
|
return ref Lookup<TComponent>().Get(entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Set<TComponent>(int entityID, TComponent component) where TComponent : struct, IComponent
|
public virtual void Set<TComponent>(int entityID, TComponent component) where TComponent : struct, IComponent
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace Encompass
|
namespace Encompass
|
||||||
{
|
{
|
||||||
|
@ -16,27 +17,30 @@ namespace Encompass
|
||||||
|
|
||||||
internal class TypedComponentStore<TComponent> : TypedComponentStore where TComponent : struct, IComponent
|
internal class TypedComponentStore<TComponent> : TypedComponentStore where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
private readonly Dictionary<int, TComponent> store = new Dictionary<int, TComponent>(128);
|
private readonly Dictionary<int, int> indices = new Dictionary<int, int>(512);
|
||||||
private readonly Dictionary<int, int> priorities = new Dictionary<int, int>(128);
|
private readonly Dictionary<int, int> priorities = new Dictionary<int, int>(512);
|
||||||
|
private TComponent[] components = new TComponent[512];
|
||||||
|
private readonly IDManager _idManager = new IDManager();
|
||||||
|
|
||||||
public override int Count { get => store.Count; }
|
public override int Count { get => indices.Count; }
|
||||||
|
|
||||||
public TComponent Get(int entityID)
|
public unsafe ref readonly TComponent Get(int entityID)
|
||||||
{
|
{
|
||||||
if (!store.ContainsKey(entityID)) { throw new Exceptions.NoComponentOfTypeOnEntityException("No component of type {0} exists on Entity with ID {1}", typeof(TComponent), entityID); }
|
if (!indices.ContainsKey(entityID)) { throw new Exceptions.NoComponentOfTypeOnEntityException("No component of type {0} exists on Entity with ID {1}", typeof(TComponent), entityID); }
|
||||||
return store[entityID];
|
ref var refVal = ref components[indices[entityID]];
|
||||||
|
return ref Unsafe.AsRef<TComponent>(Unsafe.AsPointer(ref refVal));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Set(int entityID, TComponent component)
|
public unsafe void Set(int entityID, TComponent component)
|
||||||
{
|
{
|
||||||
store[entityID] = component;
|
InternalSet(entityID, component);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Set(int entityID, TComponent component, int priority)
|
public unsafe bool Set(int entityID, TComponent component, int priority)
|
||||||
{
|
{
|
||||||
if (!priorities.ContainsKey(entityID) || priority < priorities[entityID])
|
if (!priorities.ContainsKey(entityID) || priority < priorities[entityID])
|
||||||
{
|
{
|
||||||
store[entityID] = component;
|
InternalSet(entityID, component);
|
||||||
priorities[entityID] = priority;
|
priorities[entityID] = priority;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -44,13 +48,22 @@ namespace Encompass
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private unsafe void InternalSet(int entityID, TComponent component)
|
||||||
|
{
|
||||||
|
var index = _idManager.NextID();
|
||||||
|
var ptr = Unsafe.AsPointer(ref component);
|
||||||
|
indices[entityID] = index;
|
||||||
|
components[index] = Unsafe.AsRef<TComponent>(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
public override bool Remove(int entityID, int priority)
|
public override bool Remove(int entityID, int priority)
|
||||||
{
|
{
|
||||||
if (!priorities.ContainsKey(entityID) || priority < priorities[entityID])
|
if (!priorities.ContainsKey(entityID) || priority < priorities[entityID])
|
||||||
{
|
{
|
||||||
priorities[entityID] = priority;
|
priorities[entityID] = priority;
|
||||||
store.Remove(entityID);
|
indices.Remove(entityID);
|
||||||
priorities.Remove(entityID);
|
priorities.Remove(entityID);
|
||||||
|
_idManager.Free(entityID);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,18 +72,19 @@ namespace Encompass
|
||||||
|
|
||||||
public override void ForceRemove(int entityID)
|
public override void ForceRemove(int entityID)
|
||||||
{
|
{
|
||||||
store.Remove(entityID);
|
indices.Remove(entityID);
|
||||||
priorities.Remove(entityID);
|
priorities.Remove(entityID);
|
||||||
|
_idManager.Free(entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Has(int entityID)
|
public override bool Has(int entityID)
|
||||||
{
|
{
|
||||||
return store.ContainsKey(entityID);
|
return indices.ContainsKey(entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Clear()
|
public override void Clear()
|
||||||
{
|
{
|
||||||
store.Clear();
|
indices.Clear();
|
||||||
priorities.Clear();
|
priorities.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,17 +95,17 @@ namespace Encompass
|
||||||
|
|
||||||
public IEnumerable<(TComponent, int)> All()
|
public IEnumerable<(TComponent, int)> All()
|
||||||
{
|
{
|
||||||
foreach (var kvp in store)
|
foreach (var kvp in indices)
|
||||||
{
|
{
|
||||||
yield return (kvp.Value, kvp.Key);
|
yield return (components[kvp.Value], kvp.Key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<(int, Type, IComponent)> AllInterfaceTyped()
|
public override IEnumerable<(int, Type, IComponent)> AllInterfaceTyped()
|
||||||
{
|
{
|
||||||
foreach (var kvp in store)
|
foreach (var kvp in indices)
|
||||||
{
|
{
|
||||||
yield return (kvp.Key, typeof(TComponent), (IComponent)kvp.Value);
|
yield return (kvp.Key, typeof(TComponent), (IComponent)components[kvp.Value]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using MoonTools.FastCollections;
|
|
||||||
|
|
||||||
namespace Encompass
|
namespace Encompass
|
||||||
{
|
{
|
||||||
|
@ -154,19 +153,19 @@ namespace Encompass
|
||||||
|
|
||||||
// component getters
|
// component getters
|
||||||
|
|
||||||
internal TComponent ReadImmediateOrExistingComponentByEntityAndType<TComponent>(int entityID) where TComponent : struct, IComponent
|
internal ref readonly TComponent ReadImmediateOrExistingComponentByEntityAndType<TComponent>(int entityID) where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
return upToDateComponentStore.Get<TComponent>(entityID);
|
return ref upToDateComponentStore.Get<TComponent>(entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal TComponent ReadExistingComponentByEntityAndType<TComponent>(int entityID) where TComponent : struct, IComponent
|
internal ref readonly TComponent ReadExistingComponentByEntityAndType<TComponent>(int entityID) where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
return existingComponentStore.Get<TComponent>(entityID);
|
return ref existingComponentStore.Get<TComponent>(entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal TComponent ReadImmediateComponentByEntityAndType<TComponent>(int entityID) where TComponent : struct, IComponent
|
internal ref readonly TComponent ReadImmediateComponentByEntityAndType<TComponent>(int entityID) where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
return immediateComponentStore.Get<TComponent>(entityID);
|
return ref immediateComponentStore.Get<TComponent>(entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
// has checkers
|
// has checkers
|
||||||
|
@ -214,9 +213,9 @@ namespace Encompass
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal TComponent GetComponentByEntityAndType<TComponent>(int entityID) where TComponent : struct, IComponent
|
internal ref readonly TComponent GetComponentByEntityAndType<TComponent>(int entityID) where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
return existingComponentStore.Get<TComponent>(entityID);
|
return ref existingComponentStore.Get<TComponent>(entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool EntityHasComponentOfType<TComponent>(int entityID) where TComponent : struct, IComponent
|
internal bool EntityHasComponentOfType<TComponent>(int entityID) where TComponent : struct, IComponent
|
||||||
|
|
|
@ -344,21 +344,21 @@ namespace Encompass
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private TComponent GetComponentHelper<TComponent>(int entityID) where TComponent : struct, IComponent
|
private ref readonly TComponent GetComponentHelper<TComponent>(int entityID) where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
var immediateRead = readImmediateTypes.Contains(typeof(TComponent));
|
var immediateRead = readImmediateTypes.Contains(typeof(TComponent));
|
||||||
var existingRead = readTypes.Contains(typeof(TComponent));
|
var existingRead = readTypes.Contains(typeof(TComponent));
|
||||||
if (existingRead && immediateRead)
|
if (existingRead && immediateRead)
|
||||||
{
|
{
|
||||||
return componentManager.ReadImmediateOrExistingComponentByEntityAndType<TComponent>(entityID);
|
return ref componentManager.ReadImmediateOrExistingComponentByEntityAndType<TComponent>(entityID);
|
||||||
}
|
}
|
||||||
else if (existingRead)
|
else if (existingRead)
|
||||||
{
|
{
|
||||||
return componentManager.ReadExistingComponentByEntityAndType<TComponent>(entityID);
|
return ref componentManager.ReadExistingComponentByEntityAndType<TComponent>(entityID);
|
||||||
}
|
}
|
||||||
else if (immediateRead)
|
else if (immediateRead)
|
||||||
{
|
{
|
||||||
return componentManager.ReadImmediateComponentByEntityAndType<TComponent>(entityID);
|
return ref componentManager.ReadImmediateComponentByEntityAndType<TComponent>(entityID);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -375,9 +375,9 @@ namespace Encompass
|
||||||
/// <exception cref="Encompass.Exceptions.IllegalReadException">
|
/// <exception cref="Encompass.Exceptions.IllegalReadException">
|
||||||
/// Thrown when the Engine does not declare that it reads the given Component Type.
|
/// Thrown when the Engine does not declare that it reads the given Component Type.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
protected TComponent GetComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
|
protected ref readonly TComponent GetComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
return GetComponentHelper<TComponent>(entity.ID);
|
return ref GetComponentHelper<TComponent>(entity.ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -57,9 +57,9 @@ namespace Encompass
|
||||||
return enumerator.Current;
|
return enumerator.Current;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected TComponent GetComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
|
protected ref readonly TComponent GetComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
return componentManager.GetComponentByEntityAndType<TComponent>(entity.ID);
|
return ref componentManager.GetComponentByEntityAndType<TComponent>(entity.ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected bool HasComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
|
protected bool HasComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.1</TargetFramework>
|
||||||
|
<LangVersion>8.0</LangVersion>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<RootNamespace>Encompass</RootNamespace>
|
<RootNamespace>Encompass</RootNamespace>
|
||||||
<PackageId>EncompassECS.Framework</PackageId>
|
<PackageId>EncompassECS.Framework</PackageId>
|
||||||
<Version>0.20.0</Version>
|
<Version>0.20.0</Version>
|
||||||
|
|
Loading…
Reference in New Issue