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-20 07:09:57 +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 readonly TComponent [ ] _components = new TComponent [ 512 ] ;
2020-03-19 22:44:04 +00:00
private readonly IDManager _idManager = new IDManager ( ) ;
2019-12-05 22:59:55 +00:00
2020-03-20 07:09:57 +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-20 07:09:57 +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 ] ] ;
2020-03-19 22:44:04 +00:00
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
{
2020-03-20 07:09:57 +00:00
if ( ! _priorities . ContainsKey ( entityID ) | | priority < _priorities [ entityID ] )
2019-12-24 02:45:49 +00:00
{
2020-03-19 22:44:04 +00:00
InternalSet ( entityID , component ) ;
2020-03-20 07:09:57 +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 07:09:57 +00:00
if ( ! _indices . ContainsKey ( entityID ) )
2020-03-20 00:26:22 +00:00
{
2020-03-20 07:09:57 +00:00
_indices [ entityID ] = _idManager . NextID ( ) ;
2020-03-20 00:26:22 +00:00
}
2020-03-19 22:44:04 +00:00
var ptr = Unsafe . AsPointer ( ref component ) ;
2020-03-20 07:09:57 +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
{
2020-03-20 07:09:57 +00:00
if ( ! _priorities . ContainsKey ( entityID ) | | priority < _priorities [ entityID ] )
2019-12-24 02:01:49 +00:00
{
2020-03-20 07:09:57 +00:00
_priorities [ entityID ] = priority ;
_indices . Remove ( entityID ) ;
_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-20 07:09:57 +00:00
_indices . Remove ( entityID ) ;
_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-20 07:09:57 +00:00
return _indices . ContainsKey ( entityID ) ;
2019-12-05 22:59:55 +00:00
}
public override void Clear ( )
{
2020-03-20 07:09:57 +00:00
foreach ( var entityID in _indices . Keys )
2020-03-20 00:26:22 +00:00
{
_idManager . Free ( entityID ) ;
}
2020-03-20 07:09:57 +00:00
_indices . Clear ( ) ;
_priorities . Clear ( ) ;
2019-12-05 22:59:55 +00:00
}
2019-12-30 03:43:05 +00:00
public override void ClearPriorities ( )
{
2020-03-20 07:09:57 +00:00
_priorities . Clear ( ) ;
2019-12-30 03:43:05 +00:00
}
2019-12-24 02:45:49 +00:00
public IEnumerable < ( TComponent , int ) > All ( )
2019-12-05 22:59:55 +00:00
{
2020-03-20 07:09:57 +00:00
foreach ( var kvp in _indices )
2019-12-17 04:40:15 +00:00
{
2020-03-20 07:09:57 +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-20 07:09:57 +00:00
foreach ( var kvp in _indices )
2019-12-17 04:40:15 +00:00
{
2020-03-20 07:09:57 +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
}
}
}