2019-08-01 22:06:19 +00:00
using System ;
using System.Collections.Generic ;
2019-08-02 00:34:54 +00:00
2019-08-01 22:06:19 +00:00
namespace Encompass
{
2019-12-06 06:32:09 +00:00
internal class ComponentUpdateManager
2019-08-01 22:06:19 +00:00
{
2019-12-06 06:32:09 +00:00
private readonly ComponentStore existingAndPendingComponentStore = new ComponentStore ( ) ;
2019-12-05 20:10:33 +00:00
private readonly ComponentStore existingComponentStore = new ComponentStore ( ) ;
private readonly ComponentStore pendingComponentStore = new ComponentStore ( ) ;
2019-12-06 01:07:06 +00:00
private readonly Dictionary < Type , Dictionary < Entity , int > > typeToEntityToPendingComponentPriority = new Dictionary < Type , Dictionary < Entity , int > > ( 128 ) ;
2019-08-02 06:09:41 +00:00
2019-12-06 06:32:09 +00:00
public ComponentStore UpToDateComponentStore { get ; private set ; } = new ComponentStore ( ) ;
2019-12-05 22:59:55 +00:00
2019-12-16 07:28:02 +00:00
public void RegisterComponentType < TComponent > ( ) where TComponent : struct , IComponent
{
existingAndPendingComponentStore . RegisterComponentType < TComponent > ( ) ;
existingComponentStore . RegisterComponentType < TComponent > ( ) ;
pendingComponentStore . RegisterComponentType < TComponent > ( ) ;
2019-12-17 02:51:45 +00:00
UpToDateComponentStore . RegisterComponentType < TComponent > ( ) ;
2019-12-16 07:28:02 +00:00
}
2019-12-20 19:10:42 +00:00
public void FinishRegistering ( )
{
existingAndPendingComponentStore . FinishRegistering ( ) ;
existingComponentStore . FinishRegistering ( ) ;
pendingComponentStore . FinishRegistering ( ) ;
UpToDateComponentStore . FinishRegistering ( ) ;
}
2019-12-06 06:32:09 +00:00
internal void Clear ( )
2019-08-01 23:24:57 +00:00
{
2019-12-06 06:32:09 +00:00
existingAndPendingComponentStore . ClearAll ( ) ;
2019-12-05 20:10:33 +00:00
existingComponentStore . ClearAll ( ) ;
pendingComponentStore . ClearAll ( ) ;
2019-12-06 03:55:17 +00:00
UpToDateComponentStore . ClearAll ( ) ;
2019-08-21 02:25:59 +00:00
2019-12-05 04:50:08 +00:00
foreach ( var dictionary in typeToEntityToPendingComponentPriority . Values )
2019-08-21 02:25:59 +00:00
{
dictionary . Clear ( ) ;
}
2019-08-01 23:24:57 +00:00
}
2019-12-06 00:00:00 +00:00
internal void SetStartingComponentStore ( ComponentStore componentStore )
{
2019-12-06 06:32:09 +00:00
UpToDateComponentStore = componentStore ;
2019-12-06 00:00:00 +00:00
}
2019-12-06 03:55:17 +00:00
internal void AddExistingComponent < TComponent > ( Entity entity , TComponent component ) where TComponent : struct , IComponent
2019-08-01 23:24:57 +00:00
{
2019-12-06 03:55:17 +00:00
RegisterExistingOrPendingComponentMessage ( entity , component ) ;
2019-08-01 23:24:57 +00:00
2019-12-06 03:55:17 +00:00
existingComponentStore . Set ( entity , component ) ;
2019-08-01 23:24:57 +00:00
}
2019-12-06 08:36:54 +00:00
internal bool AddPendingComponent < TComponent > ( Entity entity , TComponent component , int priority ) where TComponent : struct , IComponent
2019-08-01 23:24:57 +00:00
{
2019-12-06 03:55:17 +00:00
if ( pendingComponentStore . Set ( entity , component , priority ) )
2019-12-05 22:59:55 +00:00
{
2019-12-06 03:55:17 +00:00
RegisterExistingOrPendingComponentMessage ( entity , component ) ;
2019-12-06 08:36:54 +00:00
return true ;
2019-12-05 22:59:55 +00:00
}
2019-12-06 08:36:54 +00:00
return false ;
2019-08-01 23:24:57 +00:00
}
2019-12-05 20:10:33 +00:00
private void RegisterExistingOrPendingComponentMessage < TComponent > ( Entity entity , TComponent component ) where TComponent : struct , IComponent
2019-08-01 23:24:57 +00:00
{
2019-12-06 06:32:09 +00:00
existingAndPendingComponentStore . Set ( entity , component ) ;
UpToDateComponentStore . Set ( entity , component ) ;
2019-12-05 23:14:28 +00:00
}
2019-12-06 08:36:54 +00:00
public bool UpdateComponent < TComponent > ( Entity entity , TComponent component , int priority ) where TComponent : struct , IComponent
2019-12-05 23:14:28 +00:00
{
2019-12-06 08:36:54 +00:00
return UpToDateComponentStore . Set < TComponent > ( entity , component , priority ) ;
2019-08-01 23:24:57 +00:00
}
// general component reads by type
2019-12-17 04:40:15 +00:00
internal IEnumerable < ( TComponent , Entity ) > ReadExistingAndPendingComponentsByType < TComponent > ( ) where TComponent : struct , IComponent
2019-08-01 23:24:57 +00:00
{
2019-12-06 06:32:09 +00:00
return existingAndPendingComponentStore . All < TComponent > ( ) ;
2019-08-01 23:24:57 +00:00
}
2019-12-17 04:40:15 +00:00
internal IEnumerable < ( TComponent , Entity ) > ReadExistingComponentsByType < TComponent > ( ) where TComponent : struct , IComponent
2019-08-01 23:24:57 +00:00
{
2019-12-05 20:10:33 +00:00
return existingComponentStore . All < TComponent > ( ) ;
2019-08-01 23:24:57 +00:00
}
2019-12-17 04:40:15 +00:00
internal IEnumerable < ( TComponent , Entity ) > ReadPendingComponentsByType < TComponent > ( ) where TComponent : struct , IComponent
2019-08-01 23:24:57 +00:00
{
2019-12-05 20:10:33 +00:00
return pendingComponentStore . All < TComponent > ( ) ;
2019-08-01 23:24:57 +00:00
}
// singular component reads by type
2019-12-17 04:40:15 +00:00
internal ( TComponent , Entity ) ReadFirstExistingOrPendingComponentByType < TComponent > ( ) where TComponent : struct , IComponent
2019-08-01 23:24:57 +00:00
{
2019-10-24 19:48:36 +00:00
if ( ! SomeExistingOrPendingComponent < TComponent > ( ) ) { throw new Exceptions . NoComponentOfTypeException ( $"No Component with type {typeof(TComponent)} exists" ) ; }
2019-12-17 04:40:15 +00:00
var enumerator = ReadExistingAndPendingComponentsByType < TComponent > ( ) . GetEnumerator ( ) ;
enumerator . MoveNext ( ) ;
return enumerator . Current ;
2019-08-01 23:24:57 +00:00
}
2019-12-17 04:40:15 +00:00
internal ( TComponent , Entity ) ReadFirstExistingComponentByType < TComponent > ( ) where TComponent : struct , IComponent
2019-08-01 23:24:57 +00:00
{
2019-10-24 19:48:36 +00:00
if ( ! SomeExistingComponent < TComponent > ( ) ) { throw new Exceptions . NoComponentOfTypeException ( $"No Component with type {typeof(TComponent)} exists" ) ; }
2019-12-17 04:40:15 +00:00
var enumerator = ReadExistingComponentsByType < TComponent > ( ) . GetEnumerator ( ) ;
enumerator . MoveNext ( ) ;
return enumerator . Current ;
2019-08-01 23:24:57 +00:00
}
2019-12-17 04:40:15 +00:00
internal ( TComponent , Entity ) ReadFirstPendingComponentByType < TComponent > ( ) where TComponent : struct , IComponent
2019-08-01 23:24:57 +00:00
{
2019-12-06 08:36:54 +00:00
if ( ! SomePendingComponent < TComponent > ( ) ) { throw new Exceptions . NoComponentOfTypeException ( $"No Component with type {typeof(TComponent)} exists" ) ; }
2019-12-17 04:40:15 +00:00
var enumerator = ReadPendingComponentsByType < TComponent > ( ) . GetEnumerator ( ) ;
enumerator . MoveNext ( ) ;
return enumerator . Current ;
2019-08-01 23:24:57 +00:00
}
// check if some component of type exists in the world
internal bool SomeExistingOrPendingComponent < TComponent > ( ) where TComponent : struct , IComponent
{
2019-12-06 06:32:09 +00:00
return existingAndPendingComponentStore . Any < TComponent > ( ) ;
2019-08-01 23:24:57 +00:00
}
internal bool SomeExistingComponent < TComponent > ( ) where TComponent : struct , IComponent
{
2019-12-05 20:10:33 +00:00
return existingComponentStore . Any < TComponent > ( ) ;
2019-08-01 23:24:57 +00:00
}
internal bool SomePendingComponent < TComponent > ( ) where TComponent : struct , IComponent
{
2019-12-05 20:10:33 +00:00
return pendingComponentStore . Any < TComponent > ( ) ;
2019-08-01 23:24:57 +00:00
}
// read components by entity and type
2019-12-05 20:10:33 +00:00
internal TComponent ReadExistingComponentByEntityAndType < TComponent > ( Entity entity ) where TComponent : struct , IComponent
2019-08-01 23:24:57 +00:00
{
2019-12-05 20:10:33 +00:00
return existingComponentStore . Get < TComponent > ( entity ) ;
2019-08-01 23:24:57 +00:00
}
2019-12-05 20:10:33 +00:00
internal TComponent ReadPendingComponentByEntityAndType < TComponent > ( Entity entity ) where TComponent : struct , IComponent
2019-08-01 23:24:57 +00:00
{
2019-12-05 20:10:33 +00:00
return pendingComponentStore . Get < TComponent > ( entity ) ;
2019-08-01 23:24:57 +00:00
}
// check if entity has component of type
internal bool HasExistingOrPendingComponent < TComponent > ( Entity entity ) where TComponent : struct , IComponent
{
2019-12-06 06:32:09 +00:00
return existingAndPendingComponentStore . Has < TComponent > ( entity ) ;
2019-08-01 23:24:57 +00:00
}
2019-11-13 21:15:43 +00:00
internal bool HasExistingOrPendingComponent ( Entity entity , Type type )
{
2019-12-06 06:32:09 +00:00
return existingAndPendingComponentStore . Has ( type , entity ) ;
2019-11-13 21:15:43 +00:00
}
2019-08-01 23:24:57 +00:00
internal bool HasExistingComponent < TComponent > ( Entity entity ) where TComponent : struct , IComponent
{
2019-12-05 20:10:33 +00:00
return existingComponentStore . Has < TComponent > ( entity ) ;
2019-08-01 23:24:57 +00:00
}
2019-11-13 21:15:43 +00:00
internal bool HasExistingComponent ( Entity entity , Type type )
{
2019-12-05 20:10:33 +00:00
return existingComponentStore . Has ( type , entity ) ;
2019-11-13 21:15:43 +00:00
}
2019-08-01 23:24:57 +00:00
internal bool HasPendingComponent < TComponent > ( Entity entity ) where TComponent : struct , IComponent
{
2019-12-05 20:10:33 +00:00
return pendingComponentStore . Has < TComponent > ( entity ) ;
2019-08-01 23:24:57 +00:00
}
2019-08-20 00:30:31 +00:00
2019-11-13 21:15:43 +00:00
internal bool HasPendingComponent ( Entity entity , Type type )
{
2019-12-05 20:10:33 +00:00
return pendingComponentStore . Has ( type , entity ) ;
2019-08-20 00:30:31 +00:00
}
2019-12-05 23:14:28 +00:00
internal void Remove < TComponent > ( Entity entity ) where TComponent : struct , IComponent
{
2019-12-06 06:32:09 +00:00
UpToDateComponentStore . Remove < TComponent > ( entity ) ;
2019-12-05 23:14:28 +00:00
}
2019-08-01 22:06:19 +00:00
}
}