Skip to content

Commit fa78e5a

Browse files
committed
Adds a simple parallel processor
Adds a simple ParallelProcessor EntityProcessor which, on Update, processes every registered IParallelComponent in parallel using the Dispatcher. Also includes a before and after update hook to allow for any sequential processing that might want to be performed manually before or afterwards.
1 parent 7717303 commit fa78e5a

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
2+
namespace Stride.CommunityToolkit.Engine.EntityProcessors {
3+
4+
/// <summary>
5+
/// Interface for use on components handled by ParallelProcessors.
6+
/// </summary>
7+
public interface IParallelComponent {
8+
9+
/// <summary>
10+
/// Called once per entity processor update, for each relevant component, in arbitrary order.
11+
/// Will be parallelised, so beware of thread safety.
12+
/// </summary>
13+
public void UpdateInParallel();
14+
15+
}
16+
17+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
using Stride.Core.Annotations;
2+
using Stride.Core.Threading;
3+
using Stride.Engine;
4+
using Stride.Games;
5+
6+
namespace Stride.CommunityToolkit.Engine.EntityProcessors {
7+
8+
/// <summary>
9+
/// An entity processor where component and data are the same, and easy
10+
/// parallelisation of operations is supported via the Dispatcher.
11+
/// </summary>
12+
/// <typeparam name="TComponent"></typeparam>
13+
public abstract class ParallelProcessor<TComponent> : EntityProcessor<TComponent> where TComponent : EntityComponent, IParallelComponent
14+
{
15+
16+
/* Keep track of all components in a list as we need to get them by index */
17+
private List<TComponent> componentList = new List<TComponent>();
18+
19+
public override void Update(GameTime time)
20+
{
21+
22+
/* Allow the entity processor implementation to hook into things *before* the parallel processing... */
23+
BeforeUpdate();
24+
25+
/* Dispatch UpdateInParallel across every ComponentData */
26+
Dispatcher.For(0, componentList.Count, i =>
27+
{
28+
componentList[i].UpdateInParallel();
29+
});
30+
31+
/* ... and after */
32+
AfterUpdate();
33+
34+
}
35+
36+
/// <summary>
37+
/// Invoked before the component's UpdateInParallel() method. Should contain any non-thread-safe initialisation.
38+
/// </summary>
39+
abstract protected void BeforeUpdate();
40+
41+
/// <summary>
42+
/// Invoked after the component's UpdateInParallel() method. Should contain any non-thread-safe post-processing.
43+
/// </summary>
44+
abstract protected void AfterUpdate();
45+
46+
protected override void OnEntityComponentAdding(Entity entity, [NotNull] TComponent component, [NotNull] TComponent data)
47+
{
48+
componentList.Add(component);
49+
}
50+
51+
protected override void OnEntityComponentRemoved(Entity entity, [NotNull] TComponent component, [NotNull] TComponent data)
52+
{
53+
componentList.Remove(component);
54+
}
55+
56+
}
57+
58+
}

0 commit comments

Comments
 (0)