using Svelto.DataStructures;
using Svelto.Common;
namespace Svelto.ECS
{
///
/// SortedEnginesGroup is a practical way to group engines that can be ticked together. The class requires a
/// SequenceOrder struct that define the order of execution. The pattern to use is the following:
/// First define as many enums as you want with the ID of the engines to use. E.G.:
/// public enum WiresCompositionEngineNames
///{
/// WiresTimeRunningGroup,
/// WiresPreInitTimeRunningGroup,
/// WiresInitTimeStoppedGroup,
/// WiresInitTimeRunningGroup
///}
///
/// then link these ID to the actual engines, using the attribute Sequenced:
///
/// [Sequenced(nameof(WiresCompositionEngineNames.WiresTimeRunningGroup))]
/// class WiresTimeRunningGroup : UnsortedDeterministicEnginesGroupg {}
///
/// Note that the engine can be another group itself (like in this example).
///
/// then define the ISequenceOrder struct. E.G.:
/// public struct DeterministicTimeRunningEnginesOrder: ISequenceOrder
/// {
/// private static readonly string[] order =
/// {
/// nameof(TriggerEngineNames.PreWiresTimeRunningTriggerGroup),
/// nameof(TimerEnginesNames.PreWiresTimeRunningTimerGroup),
/// nameof(WiresCompositionEngineNames.WiresTimeRunningGroup),
/// nameof(SyncGroupEnginesGroups.UnsortedDeterministicTimeRunningGroup)
/// };
/// public string[] enginesOrder => order;
/// }
///
/// Now you can use the Type you just created (i.e.: DeterministicTimeRunningEnginesOrder) as generic parameter
/// of the SortedEnginesGroup.
/// While the system may look convoluted, is an effective way to keep the engines assemblies decoupled from
/// each other
/// The class is abstract and it requires a user defined interface to push the user to use recognisable names meaningful
/// to the context where they are used.
///
/// user defined interface that implements IStepEngine
public abstract class SortedEnginesGroup : IStepGroupEngine
where SequenceOrder : struct, ISequenceOrder where Interface : IStepEngine
{
protected SortedEnginesGroup(FasterList engines)
{
_name = "SortedEnginesGroup - "+this.GetType().Name;
_instancedSequence = new Sequence(engines);
}
public void Step()
{
var sequenceItems = _instancedSequence.items;
using (var profiler = new PlatformProfiler(_name))
{
for (var index = 0; index < sequenceItems.count; index++)
{
var engine = sequenceItems[index];
using (profiler.Sample(engine.name)) engine.Step();
}
}
}
public string name => _name;
readonly string _name;
readonly Sequence _instancedSequence;
}
///
/// Similar to SortedEnginesGroup except for the fact that an optional parameter can be passed to the engines
///
///
/// Specialised Parameter that can be passed to all the engines in the group
public abstract class SortedEnginesGroup: IStepGroupEngine
where SequenceOrder : struct, ISequenceOrder where Interface : IStepEngine
{
protected SortedEnginesGroup(FasterList engines)
{
_name = "SortedEnginesGroup - "+this.GetType().Name;
_instancedSequence = new Sequence(engines);
}
public void Step(in Parameter param)
{
var sequenceItems = _instancedSequence.items;
using (var profiler = new PlatformProfiler(_name))
{
for (var index = 0; index < sequenceItems.count; index++)
{
var engine = sequenceItems[index];
using (profiler.Sample(engine.name)) engine.Step(param);
}
}
}
public string name => _name;
readonly string _name;
readonly Sequence _instancedSequence;
}
}