2019-12-05 22:59:55 +00:00
using System ;
using System.Collections.Generic ;
2020-03-19 22:44:04 +00:00
using System.Runtime.CompilerServices ;
2019-12-05 22:59:55 +00:00
namespace Encompass
{
internal abstract class TypedComponentStore
{
public abstract int Count { get ; }
2019-12-24 02:45:49 +00:00
public abstract IEnumerable < ( int , Type , IComponent ) > AllInterfaceTyped ( ) ;
public abstract bool Has ( int entity ) ;
public abstract bool Remove ( int entity , int priority ) ;
public abstract void ForceRemove ( int entity ) ;
2019-12-05 22:59:55 +00:00
public abstract void Clear ( ) ;
2019-12-30 03:43:05 +00:00
public abstract void ClearPriorities ( ) ;
2019-12-05 22:59:55 +00:00
}
internal class TypedComponentStore < TComponent > : TypedComponentStore where TComponent : struct , IComponent
{
2020-03-19 22:44:04 +00:00
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 ( ) ;
2019-12-05 22:59:55 +00:00
2020-03-19 22:44:04 +00:00
public override int Count { get = > indices . Count ; }
2019-12-05 22:59:55 +00:00
2020-03-19 22:44:04 +00:00
public unsafe ref readonly TComponent Get ( int entityID )
2019-12-05 22:59:55 +00:00
{
2020-03-19 22:44:04 +00:00
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 ) ) ;
2019-12-05 22:59:55 +00:00
}
2020-03-19 22:44:04 +00:00
public unsafe void Set ( int entityID , TComponent component )
2019-12-05 22:59:55 +00:00
{
2020-03-19 22:44:04 +00:00
InternalSet ( entityID , component ) ;
2019-12-05 22:59:55 +00:00
}
2020-03-19 22:44:04 +00:00
public unsafe bool Set ( int entityID , TComponent component , int priority )
2019-12-05 22:59:55 +00:00
{
2019-12-24 02:45:49 +00:00
if ( ! priorities . ContainsKey ( entityID ) | | priority < priorities [ entityID ] )
{
2020-03-19 22:44:04 +00:00
InternalSet ( entityID , component ) ;
2019-12-24 02:45:49 +00:00
priorities [ entityID ] = priority ;
2019-12-05 22:59:55 +00:00
return true ;
}
return false ;
}
2020-03-19 22:44:04 +00:00
private unsafe void InternalSet ( int entityID , TComponent component )
{
2020-03-20 00:26:22 +00:00
if ( ! indices . ContainsKey ( entityID ) )
{
indices [ entityID ] = _idManager . NextID ( ) ;
}
2020-03-19 22:44:04 +00:00
var ptr = Unsafe . AsPointer ( ref component ) ;
2020-03-20 00:26:22 +00:00
components [ indices [ entityID ] ] = Unsafe . AsRef < TComponent > ( ptr ) ;
2020-03-19 22:44:04 +00:00
}
2019-12-24 02:45:49 +00:00
public override bool Remove ( int entityID , int priority )
2019-12-24 02:01:49 +00:00
{
2019-12-24 02:45:49 +00:00
if ( ! priorities . ContainsKey ( entityID ) | | priority < priorities [ entityID ] )
2019-12-24 02:01:49 +00:00
{
2019-12-24 02:45:49 +00:00
priorities [ entityID ] = priority ;
2020-03-19 22:44:04 +00:00
indices . Remove ( entityID ) ;
2019-12-24 02:45:49 +00:00
priorities . Remove ( entityID ) ;
2020-03-19 22:44:04 +00:00
_idManager . Free ( entityID ) ;
2019-12-24 02:01:49 +00:00
return true ;
}
return false ;
}
2019-12-24 02:45:49 +00:00
public override void ForceRemove ( int entityID )
2019-12-24 02:01:49 +00:00
{
2020-03-19 22:44:04 +00:00
indices . Remove ( entityID ) ;
2019-12-24 02:45:49 +00:00
priorities . Remove ( entityID ) ;
2020-03-19 22:44:04 +00:00
_idManager . Free ( entityID ) ;
2019-12-24 02:01:49 +00:00
}
2019-12-24 02:45:49 +00:00
public override bool Has ( int entityID )
2019-12-05 22:59:55 +00:00
{
2020-03-19 22:44:04 +00:00
return indices . ContainsKey ( entityID ) ;
2019-12-05 22:59:55 +00:00
}
public override void Clear ( )
{
2020-03-20 00:26:22 +00:00
foreach ( var entityID in indices . Keys )
{
_idManager . Free ( entityID ) ;
}
2020-03-19 22:44:04 +00:00
indices . Clear ( ) ;
2019-12-06 07:55:17 +00:00
priorities . Clear ( ) ;
2019-12-05 22:59:55 +00:00
}
2019-12-30 03:43:05 +00:00
public override void ClearPriorities ( )
{
priorities . Clear ( ) ;
}
2019-12-24 02:45:49 +00:00
public IEnumerable < ( TComponent , int ) > All ( )
2019-12-05 22:59:55 +00:00
{
2020-03-19 22:44:04 +00:00
foreach ( var kvp in indices )
2019-12-17 04:40:15 +00:00
{
2020-03-19 22:44:04 +00:00
yield return ( components [ kvp . Value ] , kvp . Key ) ;
2019-12-17 04:40:15 +00:00
}
2019-12-05 22:59:55 +00:00
}
2019-12-24 02:45:49 +00:00
public override IEnumerable < ( int , Type , IComponent ) > AllInterfaceTyped ( )
2019-12-05 22:59:55 +00:00
{
2020-03-19 22:44:04 +00:00
foreach ( var kvp in indices )
2019-12-17 04:40:15 +00:00
{
2020-03-19 22:44:04 +00:00
yield return ( kvp . Key , typeof ( TComponent ) , ( IComponent ) components [ kvp . Value ] ) ;
2019-12-17 04:40:15 +00:00
}
2019-12-05 22:59:55 +00:00
}
}
}