Skip to content

Commit 0eb96e1

Browse files
committed
Merge branch 'systems-rx-split'
2 parents a1dee6d + bfb1d13 commit 0eb96e1

File tree

174 files changed

+1401
-886
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

174 files changed

+1401
-886
lines changed

README.md

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
# EcsRx
1+
# EcsRx / SystemsRx
22

3-
EcsRx is a reactive take on the common ECS pattern with a well separated design using rx and adhering to IoC and other sensible design patterns.
3+
EcsRx is a reactive take on the common ECS pattern with a well separated design using rx and adhering to IoC and other sensible design patterns, with a more cut down systems only version called SystemsRx if you dont need Entities and Components.
44

55
[![Build Status][build-status-image]][build-status-url]
66
[![Code Quality Status][codacy-image]][codacy-url]
@@ -91,15 +91,30 @@ If you want to run the examples then just clone it and open examples project in
9191

9292
There are also a suite of tests which are being expanded as the project grows, it was written with testability in mind.
9393

94-
## Note on infrastructure/view namespaces and going forward
94+
## Architecture / Infrastructure
9595

96-
This library started out as a unity specific project but has moved to a generic .net library, due to this the movement of functionality from the unity layer down into the core has been incremental.
96+
### MicroRx
9797

98-
We are now at a point where the underlying infrastructure module (mainly for `EcsRxApplication` and dependency injection notions) has been added, and the generic view module has been moved here. While both of these libraries offer a stepping stone to get up and running quicker they unfortunately are not as easy as just including and off you go.
98+
This is a bare bones rx implementation, it literally just contains some basic `Subject` and other related rx classes, this is so that we do not have a dependencies on rx.net or unirx in the core.
99+
100+
### SystemsRx
101+
102+
SystemsRx is a really just the Systems aspect of the ECS paradigm without any dependencies on Entites or Components. It allows you create your own conventions for systems as well as make use of the infrastructure layer which provides a DI abstraction layer, Plugin support and some best practice classes.
103+
104+
The 2 main libraries here are **SystemsRx** and **SystemsRx.Infrastructure**, these only have a dependency on **MicroRx**
105+
106+
### EcsRx
107+
108+
This is layered on top of **SystemsRx** and adds the ECS paradigm to the framework as well as adding a couple of systems specifically for entity handling. This also contains an **EcsRx.Infrastructure** layer which builds off the **SystemsRx.Infrastructure** layer to provide additional ECS related infrastructure.
109+
110+
### EcsRx.Plugins.*
111+
112+
These are plugins that can be used with **EcsRx** to add new functionality to the library, from entity persistance/rehydration to schedulable systems, these can optionally be added to your projects.
113+
114+
### History
115+
The library was originally deveoped for unity (way before they had their own ECS framework) and since then has moved to be a regular .net library that can run anywhere (Even in Blazor WASM).
99116

100-
The examples folder shows examples on how to create your own application implementations, but hopefully once things have been ironed out in the whole Rx world this area will improve more as we start to add another layer which will let you just drop in and go (like the unity version).
101117

102-
If you want to know more about this drop into the discord chat and we can discuss more.
103118

104119
## Docs
105120

appveyor.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
version: 3.12.{build}
1+
version: 4.0.{build}
22
branches:
33
only:
44
- master

build/pack.bat

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
set version=3.0.0
22
dotnet pack ../src/EcsRx.MicroRx -c Release -o ../../_dist /p:version=%version%
3+
dotnet pack ../src/SystemsRx -c Release -o ../../_dist /p:version=%version%
4+
dotnet pack ../src/SystemsRx.Infrastructure -c Release -o ../../_dist /p:version=%version%
35
dotnet pack ../src/EcsRx -c Release -o ../../_dist /p:version=%version%
46
dotnet pack ../src/EcsRx.Plugins.ReactiveSystems -c Release -o ../../_dist /p:version=%version%
57
dotnet pack ../src/EcsRx.Plugins.Views -c Release -o ../../_dist /p:version=%version%

docs/breaking-changes.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
11
# Breaking Changes
22

3+
## 3.12.0 -> 4.0.0
4+
5+
- `IEcsRxPlugin` has been renamed to `ISystemsRxPlugin` and lives in `SystemsRx.Infrastructure`
6+
- `EventReactionSystem<T>` no longer exists, the same convention can be mapped to `IReactToEventSystem` from `SystemsRx`
7+
- `IBasicSystem` has changed and has no `IEntity` dependencies and lives in `SystemsRx`, the same convention can be mapped to `IBasicEntitySystem` in `EcsRx`
8+
- `IManualSystem` no longer has a group or gets passed `IObservableGroupManager`, you can inject it yourself if you need it
9+
- `EcsRx` now depends upon `SystemsRx`, all the classes in `SystemsRx` were originally in `EcsRx` but now can be used without the `ECS` related paradigm dependencies
10+
- `ISystem` no longer contains an `IGroup` and now lives in `SystemsRx` there is now an `IGroupSystem` which represents a system with a `IGroup`
11+
312
## 3.10.0 -> 3.11.0
413

5-
- IEntityCollectionManager no longer exists, it is now just `IObservableGroupManager`
14+
- `IEntityCollectionManager` no longer exists, it is now just `IObservableGroupManager`
615

716
## 3.9.0 -> 3.10.0
817

9-
- IEntityCollectionManager no longer contains EntityCollections its now within `IEntityDatabase`, which is within there
18+
- `IEntityCollectionManager` no longer contains EntityCollections its now within `IEntityDatabase`, which is within there
1019

1120
## 3.8.0 -> 3.9.0
1221

docs/framework/systems.md

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,47 @@ Systems are where all the logic lives, it takes entities from the collection and
44

55
This means your systems don't need to worry about the logistics of getting entities and dealing with them, you just express how you want to interact with entities and let the `SystemExecutor` handle the heavy lifting and pass you the entities for processing. This can easily be seen when you look at all the available system interfaces which all process individual entities not groups of them.
66

7+
> Since version 4.0.0 of EcsRx some systems can be used without the Ecs paradigm and live within the `SystemsRx` library, which can be included without the need for `EcsRx`.
8+
79
## System Types
810

911
This is where it gets interesting, so we have multiple flavours of systems depending on how you want to consume the entities, by default there is `IManualSystem` but there is a project containing all most common systems (`EcsRx.Systems`). You can also mix them up so you could have a single system implement `ISetupSystem`, `ITeardown` and `IReactToEntitySystem` which would run a setup method for each entity when it joins the group then react to the entity changes and process them on changes, then finally run some logic when the entity is being removed from the group.
1012

11-
All systems have the notion of a `Group` which describes what entities to target out of the pool, so you don't need to do much other than setup the right groupings and implement the methods for the interfaces.
13+
All **ECS** *(Not SystemsRx)* systems have the notion of a `Group` which describes what entities to target out of the pool, so you don't need to do much other than setup the right groupings and implement the methods for the interfaces.
1214

13-
### IManualSystem
15+
### `IManualSystem` *(SystemsRx)*
1416

1517
This is a niche system for when you want to carry out some logic outside the scope of entities, or want to have
1618
more fine grained control over how you deal with the entities matched.
1719

18-
Rather than the `SystemExecutor` doing most of the work for you and managing the subscriptions and entity interactions
19-
this just provides you the `GroupAccessor` for the entities targeted and its up to you to control how they are
20-
dealt with.
20+
Rather than the `SystemExecutor` doing most of the work for you and managing the subscriptions it leaves it up to you
21+
to manage everything how you want once the system has been started.
2122

2223
The `StartSystem` method will be triggered when the system has been added to the executor, and the `StopSystem`
2324
will be triggered when the system is removed.
2425

26+
### `IBasicSystem` *(SystemsRx)*
27+
28+
This is a basic system that is triggered every update (based on scheduler update frequency) and lets you do anything you want per update.
29+
30+
### `IReactToEventSystem` *(SystemsRx)*
31+
32+
This allows you to react to any event of that type which is published over the `IEventSystem`.
33+
34+
### `IBasicEntitySystem` *(EcsRx)*
35+
36+
This system allows you to process each entity within the group on every update cycle (much like `IBasicSystem` but with entities).
37+
38+
### `ReactiveSystems`
39+
40+
There is a few plugins that contain more contextual systems that can be read about more in the docs.
41+
2542
## System Loading Order
2643

2744
So by default (with the default implementation of `ISystemExecutor`) systems will load in the order of:
2845

2946
1. Implementations of `ISetupSystem`
3047
2. Implementations of `IReactToEntitySystem`
31-
3. Other Systems
48+
3. Other Systems
3249

3350
However within those groupings it will load the systems in whatever order Zenject/Extenject (assuming you are using it) provides them, however there is a way to enforce some level of priority by applying the `[Priority(1)]` attribute, this allows you to specify the priority of how systems should be loaded. The ordering will be from lowest to highest so if you have a priority of 1 it will load before a system with a priority of 10.

src/EcsRx.Examples/Application/EcsRxConsoleApplication.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
using EcsRx.Infrastructure;
2-
using EcsRx.Infrastructure.Dependencies;
1+
using SystemsRx.Infrastructure.Dependencies;
2+
using EcsRx.Infrastructure;
33
using EcsRx.Infrastructure.Ninject;
44
using EcsRx.Plugins.Batching;
55
using EcsRx.Plugins.Computeds;

src/EcsRx.Examples/Custom/Systems/FirstSystem.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
using System;
2-
using EcsRx.Attributes;
2+
using SystemsRx.Attributes;
33
using EcsRx.Entities;
44
using EcsRx.Examples.Custom.Groups;
55
using EcsRx.Groups;

src/EcsRx.Examples/Custom/Systems/SecondSystem.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
using System;
2-
using EcsRx.Attributes;
2+
using SystemsRx.Attributes;
33
using EcsRx.Entities;
44
using EcsRx.Examples.Custom.Groups;
55
using EcsRx.Groups;

src/EcsRx.Examples/ExampleApps/BatchedGroupExample/BatchedGroupExampleApplication.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
using System;
2+
using SystemsRx.Infrastructure.Extensions;
23
using EcsRx.Examples.Application;
34
using EcsRx.Examples.ExampleApps.BatchedGroupExample.Blueprints;
45
using EcsRx.Examples.ExampleApps.BatchedGroupExample.Modules;
5-
using EcsRx.Infrastructure.Extensions;
66

77
namespace EcsRx.Examples.ExampleApps.BatchedGroupExample
88
{

src/EcsRx.Examples/ExampleApps/BatchedGroupExample/Modules/CustomComponentLookupsModule.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
using System;
22
using System.Collections.Generic;
3+
using SystemsRx.Infrastructure.Dependencies;
4+
using SystemsRx.Infrastructure.Extensions;
35
using EcsRx.Components.Lookups;
46
using EcsRx.Examples.ExampleApps.BatchedGroupExample.Components;
57
using EcsRx.Examples.ExampleApps.BatchedGroupExample.Lookups;
6-
using EcsRx.Infrastructure.Dependencies;
7-
using EcsRx.Infrastructure.Extensions;
88

99
namespace EcsRx.Examples.ExampleApps.BatchedGroupExample.Modules
1010
{

src/EcsRx.Examples/ExampleApps/BatchedGroupExample/Systems/BatchedMovementSystem.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
using System;
22
using System.Numerics;
33
using System.Reactive.Linq;
4+
using SystemsRx.Threading;
5+
using EcsRx.Collections;
46
using EcsRx.Components.Database;
57
using EcsRx.Components.Lookups;
68
using EcsRx.Examples.ExampleApps.BatchedGroupExample.Components;
79
using EcsRx.Plugins.Batching.Factories;
810
using EcsRx.Plugins.Batching.Systems;
9-
using EcsRx.Threading;
1011

1112
namespace EcsRx.Examples.ExampleApps.BatchedGroupExample.Systems
1213
{
1314
public class BatchedMovementSystem : BatchedSystem<PositionComponent, MovementSpeedComponent>
1415
{
15-
public BatchedMovementSystem(IComponentDatabase componentDatabase, IComponentTypeLookup componentTypeLookup, IBatchBuilderFactory batchBuilderFactory, IThreadHandler threadHandler) : base(componentDatabase, componentTypeLookup, batchBuilderFactory, threadHandler)
16+
public BatchedMovementSystem(IComponentDatabase componentDatabase, IComponentTypeLookup componentTypeLookup, IBatchBuilderFactory batchBuilderFactory, IThreadHandler threadHandler, IObservableGroupManager observableGroupManager)
17+
: base(componentDatabase, componentTypeLookup, batchBuilderFactory, threadHandler, observableGroupManager)
1618
{}
1719

1820
protected override IObservable<bool> ReactWhen()
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,30 @@
11
using System;
22
using System.Reactive.Linq;
3+
using SystemsRx.Systems.Conventional;
34
using EcsRx.Blueprints;
4-
using EcsRx.Collections;
55
using EcsRx.Collections.Database;
66
using EcsRx.Collections.Entity;
77
using EcsRx.Examples.ExampleApps.BatchedGroupExample.Blueprints;
8-
using EcsRx.Groups;
9-
using EcsRx.Groups.Observable;
10-
using EcsRx.Systems;
118

129
namespace EcsRx.Examples.ExampleApps.BatchedGroupExample.Systems
1310
{
1411
public class SpawnerSystem : IManualSystem
1512
{
1613
private IDisposable _sub;
1714
private IBlueprint _blueprint = new MoveableBlueprint();
18-
19-
public IGroup Group { get; } = new EmptyGroup();
15+
2016
public IEntityCollection DefaultCollection { get; }
2117

2218
public SpawnerSystem(IEntityDatabase entityDatabase)
2319
{ DefaultCollection = entityDatabase.GetCollection(); }
2420

25-
public void StartSystem(IObservableGroup observableGroup)
21+
public void StartSystem()
2622
{ _sub = Observable.Interval(TimeSpan.FromSeconds(2)).Subscribe(x => Spawn()); }
2723

2824
public void Spawn()
2925
{ DefaultCollection.CreateEntity(_blueprint); }
3026

31-
public void StopSystem(IObservableGroup observableGroup)
27+
public void StopSystem()
3228
{ _sub.Dispose(); }
3329
}
3430
}

src/EcsRx.Examples/ExampleApps/ComputedGroupExample/ComputedGroupExampleApplication.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
using System;
2+
using SystemsRx.Infrastructure.Extensions;
23
using EcsRx.Examples.Application;
34
using EcsRx.Examples.ExampleApps.ComputedGroupExample.Blueprints;
45
using EcsRx.Examples.ExampleApps.ComputedGroupExample.Modules;
5-
using EcsRx.Infrastructure.Extensions;
66

77
namespace EcsRx.Examples.ExampleApps.ComputedGroupExample
88
{

src/EcsRx.Examples/ExampleApps/ComputedGroupExample/Modules/ComputedModule.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
using SystemsRx.Infrastructure.Dependencies;
2+
using SystemsRx.Infrastructure.Extensions;
13
using EcsRx.Examples.ExampleApps.ComputedGroupExample.Components;
24
using EcsRx.Examples.ExampleApps.ComputedGroupExample.ComputedGroups;
35
using EcsRx.Groups;
4-
using EcsRx.Infrastructure.Dependencies;
56
using EcsRx.Infrastructure.Extensions;
67

78
namespace EcsRx.Examples.ExampleApps.ComputedGroupExample.Modules

src/EcsRx.Examples/ExampleApps/ComputedGroupExample/Systems/DisplayLowestHealthSystem.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Reactive.Linq;
4+
using SystemsRx.Extensions;
5+
using SystemsRx.Systems;
6+
using SystemsRx.Systems.Conventional;
47
using EcsRx.Examples.ExampleApps.ComputedGroupExample.ComputedGroups;
58
using EcsRx.Examples.ExampleApps.ComputedGroupExample.Extensions;
69
using EcsRx.Extensions;
@@ -13,8 +16,6 @@ namespace EcsRx.Examples.ExampleApps.ComputedGroupExample.Systems
1316
{
1417
public class DisplayLowestHealthSystem : IManualSystem
1518
{
16-
public IGroup Group { get; } = new EmptyGroup();
17-
1819
private readonly IList<IDisposable> _subscriptions = new List<IDisposable>();
1920

2021
private readonly ILowestHealthComputedGroup _lowestHealthGroup;
@@ -24,10 +25,10 @@ public DisplayLowestHealthSystem(ILowestHealthComputedGroup lowestHealthGroup)
2425
_lowestHealthGroup = lowestHealthGroup;
2526
}
2627

27-
public void StartSystem(IObservableGroup observableGroup)
28+
public void StartSystem()
2829
{ Observable.Interval(TimeSpan.FromSeconds(1)).Subscribe(UpdateListings).AddTo(_subscriptions); }
2930

30-
public void StopSystem(IObservableGroup observableGroup)
31+
public void StopSystem()
3132
{ _subscriptions.DisposeAll(); }
3233

3334
public void UpdateListings(long _)

src/EcsRx.Examples/ExampleApps/ComputedGroupExample/Systems/RandomlyChangeHp.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
namespace EcsRx.Examples.ExampleApps.ComputedGroupExample.Systems
1111
{
12-
public class RandomlyChangeHpSystem : IReactToGroupSystem
12+
public class RandomlyChangeHpGroupSystem : IReactToGroupSystem
1313
{
1414
private const int HealthChange = 20;
1515

src/EcsRx.Examples/ExampleApps/DataPipelinesExample/Modules/PipelineModule.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
using SystemsRx.Infrastructure.Dependencies;
2+
using SystemsRx.Infrastructure.Extensions;
13
using EcsRx.Examples.ExampleApps.DataPipelinesExample.Pipelines;
2-
using EcsRx.Infrastructure.Dependencies;
3-
using EcsRx.Infrastructure.Extensions;
44
using LazyData.Json;
55
using LazyData.Json.Handlers;
66

src/EcsRx.Examples/ExampleApps/DataPipelinesExample/PersistDataApplication.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
11
using System;
2-
using EcsRx.Entities;
2+
using SystemsRx.Infrastructure.Extensions;
33
using EcsRx.Examples.Application;
44
using EcsRx.Examples.ExampleApps.DataPipelinesExample.Components;
55
using EcsRx.Examples.ExampleApps.DataPipelinesExample.Events;
66
using EcsRx.Examples.ExampleApps.DataPipelinesExample.Modules;
7-
using EcsRx.Examples.ExampleApps.HealthExample.Blueprints;
8-
using EcsRx.Examples.ExampleApps.HealthExample.Components;
9-
using EcsRx.Examples.ExampleApps.HealthExample.Events;
107
using EcsRx.Extensions;
11-
using EcsRx.Infrastructure.Extensions;
12-
using Persistity.Pipelines;
138

149
namespace EcsRx.Examples.ExampleApps.DataPipelinesExample
1510
{

src/EcsRx.Examples/ExampleApps/DataPipelinesExample/Systems/PlayerStateUpdaterSystem.cs renamed to src/EcsRx.Examples/ExampleApps/DataPipelinesExample/Systems/PlayerStateUpdaterGroupSystem.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1+
using SystemsRx.Scheduling;
12
using EcsRx.Entities;
23
using EcsRx.Examples.ExampleApps.DataPipelinesExample.Components;
34
using EcsRx.Extensions;
45
using EcsRx.Groups;
5-
using EcsRx.Scheduling;
66
using EcsRx.Systems;
77

88
namespace EcsRx.Examples.ExampleApps.DataPipelinesExample.Systems
99
{
10-
public class PlayerStateUpdaterSystem : IBasicSystem
10+
public class PlayerStateUpdaterEntitySystem : IBasicEntitySystem
1111
{
1212
public IGroup Group { get; } = new Group(typeof(PlayerStateComponent));
1313

1414
public ITimeTracker TimeTracker { get; }
1515

16-
public PlayerStateUpdaterSystem(ITimeTracker timeTracker)
16+
public PlayerStateUpdaterEntitySystem(ITimeTracker timeTracker)
1717
{
1818
TimeTracker = timeTracker;
1919
}

0 commit comments

Comments
 (0)