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
|
||||
{
|
||||
public struct MutableComponentEntityPair<TComponent> where TComponent : struct, IComponent
|
||||
{
|
||||
public TComponent component;
|
||||
}
|
||||
|
||||
internal class ComponentStore
|
||||
{
|
||||
private Dictionary<Type, TypedComponentStore> Stores = new Dictionary<Type, TypedComponentStore>(512);
|
||||
|
@ -51,9 +56,9 @@ namespace Encompass
|
|||
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
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Encompass
|
||||
{
|
||||
|
@ -16,27 +17,30 @@ namespace Encompass
|
|||
|
||||
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> priorities = new Dictionary<int, int>(128);
|
||||
private readonly Dictionary<int, int> indices = new Dictionary<int, int>(512);
|
||||
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); }
|
||||
return store[entityID];
|
||||
if (!indices.ContainsKey(entityID)) { throw new Exceptions.NoComponentOfTypeOnEntityException("No component of type {0} exists on Entity with ID {1}", typeof(TComponent), 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])
|
||||
{
|
||||
store[entityID] = component;
|
||||
InternalSet(entityID, component);
|
||||
priorities[entityID] = priority;
|
||||
return true;
|
||||
}
|
||||
|
@ -44,13 +48,22 @@ namespace Encompass
|
|||
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)
|
||||
{
|
||||
if (!priorities.ContainsKey(entityID) || priority < priorities[entityID])
|
||||
{
|
||||
priorities[entityID] = priority;
|
||||
store.Remove(entityID);
|
||||
indices.Remove(entityID);
|
||||
priorities.Remove(entityID);
|
||||
_idManager.Free(entityID);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -59,18 +72,19 @@ namespace Encompass
|
|||
|
||||
public override void ForceRemove(int entityID)
|
||||
{
|
||||
store.Remove(entityID);
|
||||
indices.Remove(entityID);
|
||||
priorities.Remove(entityID);
|
||||
_idManager.Free(entityID);
|
||||
}
|
||||
|
||||
public override bool Has(int entityID)
|
||||
{
|
||||
return store.ContainsKey(entityID);
|
||||
return indices.ContainsKey(entityID);
|
||||
}
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
store.Clear();
|
||||
indices.Clear();
|
||||
priorities.Clear();
|
||||
}
|
||||
|
||||
|
@ -81,17 +95,17 @@ namespace Encompass
|
|||
|
||||
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()
|
||||
{
|
||||
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.Collections.Generic;
|
||||
using MoonTools.FastCollections;
|
||||
|
||||
namespace Encompass
|
||||
{
|
||||
|
@ -154,19 +153,19 @@ namespace Encompass
|
|||
|
||||
// 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
|
||||
|
@ -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
|
||||
|
|
|
@ -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 existingRead = readTypes.Contains(typeof(TComponent));
|
||||
if (existingRead && immediateRead)
|
||||
{
|
||||
return componentManager.ReadImmediateOrExistingComponentByEntityAndType<TComponent>(entityID);
|
||||
return ref componentManager.ReadImmediateOrExistingComponentByEntityAndType<TComponent>(entityID);
|
||||
}
|
||||
else if (existingRead)
|
||||
{
|
||||
return componentManager.ReadExistingComponentByEntityAndType<TComponent>(entityID);
|
||||
return ref componentManager.ReadExistingComponentByEntityAndType<TComponent>(entityID);
|
||||
}
|
||||
else if (immediateRead)
|
||||
{
|
||||
return componentManager.ReadImmediateComponentByEntityAndType<TComponent>(entityID);
|
||||
return ref componentManager.ReadImmediateComponentByEntityAndType<TComponent>(entityID);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -375,9 +375,9 @@ namespace Encompass
|
|||
/// <exception cref="Encompass.Exceptions.IllegalReadException">
|
||||
/// Thrown when the Engine does not declare that it reads the given Component Type.
|
||||
/// </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>
|
||||
|
|
|
@ -57,9 +57,9 @@ namespace Encompass
|
|||
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
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<RootNamespace>Encompass</RootNamespace>
|
||||
<PackageId>EncompassECS.Framework</PackageId>
|
||||
<Version>0.20.0</Version>
|
||||
|
|
Loading…
Reference in New Issue