Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds a simple parallel processor #108

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

namespace Stride.CommunityToolkit.Engine.EntityProcessors {

/// <summary>
/// Interface for use on components handled by ParallelProcessors.
/// </summary>
public interface IParallelComponent {

/// <summary>
/// Called once per entity processor update, for each relevant component, in arbitrary order.
/// Will be parallelised, so beware of thread safety.
/// </summary>
public void UpdateInParallel();

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using Stride.Core.Annotations;
using Stride.Core.Threading;
using Stride.Engine;
using Stride.Games;

namespace Stride.CommunityToolkit.Engine.EntityProcessors {

/// <summary>
/// An entity processor where component and data are the same, and easy
/// parallelisation of operations is supported via the Dispatcher.
/// </summary>
/// <typeparam name="TComponent"></typeparam>
public abstract class ParallelProcessor<TComponent> : EntityProcessor<TComponent> where TComponent : EntityComponent, IParallelComponent
{

/* Keep track of all components in a list as we need to get them by index */
private List<TComponent> componentList = new List<TComponent>();

public override void Update(GameTime time)
{

/* Allow the entity processor implementation to hook into things *before* the parallel processing... */
BeforeUpdate();

/* Dispatch UpdateInParallel across every ComponentData */
Dispatcher.For(0, componentList.Count, i =>
{
componentList[i].UpdateInParallel();
});

/* ... and after */
AfterUpdate();

}

/// <summary>
/// Invoked before the component's UpdateInParallel() method. Should contain any non-thread-safe initialisation.
/// </summary>
abstract protected void BeforeUpdate();

/// <summary>
/// Invoked after the component's UpdateInParallel() method. Should contain any non-thread-safe post-processing.
/// </summary>
abstract protected void AfterUpdate();

protected override void OnEntityComponentAdding(Entity entity, [NotNull] TComponent component, [NotNull] TComponent data)
{
componentList.Add(component);
}

protected override void OnEntityComponentRemoved(Entity entity, [NotNull] TComponent component, [NotNull] TComponent data)
{
componentList.Remove(component);
}

}

}