Last active
November 10, 2018 07:50
-
-
Save Fejuto/1dbdcca27a2d25ce3c08bcf2d83d59b7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
///////////////////////////////////////////////////////////////////////////////////////////////// | |
// Our team's new way of writing systems using CompositeSystem.cs (attached in this gist) // | |
// Is functionally the same as the ReactiveSystem below. Keep reading to learn how it works. // | |
///////////////////////////////////////////////////////////////////////////////////////////////// | |
public class UpdatePositionSystem : CompositeSystem { | |
public UpdatePositionSystem(Contexts contexts) : base(contexts){ | |
AddInitialize(() => { | |
// Do initialization stuff | |
}); | |
AddReactEach(GameMatcher.Position, true, e => { | |
// Do stuff with changed entities. e.hasPosition is garuanteed to be true | |
}); | |
} | |
} | |
////////////////////////////////////////////////////////////////////////////////////////// | |
// How you are used to writing a system. A lot of boilerplate. FeelsBadMan // | |
////////////////////////////////////////////////////////////////////////////////////////// | |
public class UpdatePositionSystem : IInitializeSystem, ReactiveSystem<GameEntity> { | |
Context _context; | |
public UpdatePositionSystem (Contexts contexts) : base(context.game) { | |
_context = contexts.game; | |
} | |
public void Initialize() { | |
// Do initialization stuff | |
} | |
protected override Collector<GameEntity> GetTrigger(IContext<GameEntity> context) { | |
return contexts.CreateCollector(GameMatcher.Position) | |
} | |
protected override bool Filter(GameEntity entity) { | |
return entity.hasPosition; | |
} | |
protected override void Execute(List<GameEntity> entities) { | |
foreach (var e in entities) { | |
// Do stuff with changed entities. e.hasPosition is garuanteed to be true | |
} | |
} | |
} | |
/////////////////// | |
// Full API demo // | |
/////////////////// | |
public class DemoSystem : CompositeSystem { | |
public DemoSystem(Contexts contexts) : base(contexts) { | |
AddInitialize(() => { | |
//init | |
}); | |
AddExecute(() => { | |
//execute | |
}); | |
AddCleanup(() => { | |
//cleanup | |
}); | |
AddTeardown(() => { | |
//teardown | |
}); | |
/////////////////////////////////////////////////////////////////////// | |
// Each AddReact call adds a ReactiveSystem in the backend. // | |
/////////////////////////////////////////////////////////////////////// | |
//react to GroupEvent.Added. | |
//true means autoFilter which filters all entities not matching with the matcher. false means all entities pass. | |
AddReact(GameMatcher.Position, true, entities => { | |
foreach(var e in entities) { | |
//react. e.hasPosition is garuanteed to be true | |
} | |
}); | |
//custom filter | |
AddReact(GameMatcher.Position, e => e.hasPosition, entities => { | |
foreach (var e in entities) { | |
//react | |
} | |
}); | |
AddReact(e => e.hasPosition, entities => { | |
foreach (var e in entities) { | |
//react | |
} | |
}, GameMatcher.Position.AddedOrRemoved(), GameMatcher.Name.Removed()); | |
//lower level; you are unlikely to need this | |
AddReact(contexts.game.CreateCollector(GameMatcher.Position), e => e.hasPosition, entities => { | |
foreach (var e in entities) { | |
//react | |
} | |
}); | |
//////////////////////////////////////////////////////////////////////////////////////////// | |
// Each AddReact has a AddReactEach variation which saves you from writing a foreach loop // | |
//////////////////////////////////////////////////////////////////////////////////////////// | |
//react to GroupEvent.Added. | |
//true means autoFilter which filters all entities not matching with the matcher. false means all entities pass. | |
AddReactEach(GameMatcher.Position, true, e => { | |
//react. e.hasPosition is garuanteed to be true | |
}); | |
//custom filter | |
AddReactEach(GameMatcher.Position, e => e.hasPosition, e => { | |
//react | |
}); | |
AddReactEach(e => e.hasPosition, e => { | |
//react | |
}, GameMatcher.Position.AddedOrRemoved(), GameMatcher.Name.Removed()); | |
//lower level; you are unlikely to need this | |
AddReactEach(contexts.game.CreateCollector(GameMatcher.Position), e => e.hasPosition, e => { | |
//react | |
}); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using Entitas; | |
public class CompositeSystem : Systems { | |
IContexts contexts; | |
public CompositeSystem(IContexts contexts) { | |
this.contexts = contexts; | |
} | |
public void AddInitialize(Action initialize) { | |
Add(new InlineInitializeSystem(initialize)); | |
} | |
public void AddExecute(Action execute) { | |
Add(new InlineExecuteSystem(execute)); | |
} | |
public void AddCleanup(Action cleanup) { | |
Add(new InlineCleanupSystem(cleanup)); | |
} | |
public void AddTeardown(Action tearDown) { | |
Add(new InlineTeardownSystem(tearDown)); | |
} | |
public void AddReact<TEntity>(IMatcher<TEntity> matcher, bool autoFilter, Action<List<TEntity>> execute) where TEntity : class, IEntity { | |
AddReact(matcher, e => !autoFilter || matcher.Matches(e), execute); | |
} | |
public void AddReact<TEntity>(IMatcher<TEntity> matcher, Func<TEntity, bool> filter, Action<List<TEntity>> execute) where TEntity : class, IEntity { | |
AddReact(GetContext<TEntity>().CreateCollector(matcher), filter, execute); | |
} | |
public void AddReact<TEntity>(Func<TEntity, bool> filter, Action<List<TEntity>> execute, params TriggerOnEvent<TEntity>[] triggers) where TEntity : class, IEntity { | |
AddReact(GetContext<TEntity>().CreateCollector(triggers), filter, execute); | |
} | |
public void AddReact<TEntity>(ICollector<TEntity> collector, Func<TEntity, bool> filter, Action<List<TEntity>> execute) where TEntity : class, IEntity { | |
Add(new InlineReactiveSystem<TEntity>(collector, filter, execute)); | |
} | |
public void AddReactEach<TEntity>(IMatcher<TEntity> matcher, bool autoFilter, Action<TEntity> execute) where TEntity : class, IEntity { | |
AddReact(matcher, autoFilter, entities => entities.ForEach(execute)); | |
} | |
public void AddReactEach<TEntity>(IMatcher<TEntity> matcher, Func<TEntity, bool> filter, Action<TEntity> execute) where TEntity : class, IEntity { | |
AddReact(matcher, filter, entities => entities.ForEach(execute)); | |
} | |
public void AddReactEach<TEntity>(Func<TEntity, bool> filter, Action<TEntity> execute, params TriggerOnEvent<TEntity>[] triggers) where TEntity : class, IEntity { | |
AddReact(filter, entities => entities.ForEach(execute), triggers); | |
} | |
public void AddReactEach<TEntity>(ICollector<TEntity> collector, Func<TEntity, bool> filter, Action<TEntity> execute) where TEntity : class, IEntity { | |
AddReact(collector, filter, entities => entities.ForEach(execute)); | |
} | |
IContext<TEntity> GetContext<TEntity>() where TEntity : class, IEntity { | |
foreach (var c in contexts.allContexts) { | |
if (c is IContext<TEntity> context) return context; | |
} | |
throw new ArgumentException("Context was not valid"); | |
} | |
class InlineInitializeSystem : IInitializeSystem { | |
Action initialize; | |
public InlineInitializeSystem(Action initialize) { | |
this.initialize = initialize; | |
} | |
public void Initialize() { | |
initialize(); | |
} | |
} | |
class InlineExecuteSystem : IExecuteSystem { | |
Action execute; | |
public InlineExecuteSystem(Action execute) { | |
this.execute = execute; | |
} | |
public void Execute() { | |
execute(); | |
} | |
} | |
class InlineCleanupSystem : ICleanupSystem { | |
Action cleanup; | |
public InlineCleanupSystem(Action cleanup) { | |
this.cleanup = cleanup; | |
} | |
public void Cleanup() { | |
cleanup(); | |
} | |
} | |
class InlineTeardownSystem : ITearDownSystem { | |
Action tearDown; | |
public InlineTeardownSystem(Action tearDown) { | |
this.tearDown = tearDown; | |
} | |
public void TearDown() { | |
tearDown(); | |
} | |
} | |
class InlineReactiveSystem<TEntity> : ReactiveSystem<TEntity> where TEntity : class, IEntity { | |
Func<TEntity, bool> filter; | |
Action<List<TEntity>> execute; | |
public InlineReactiveSystem(ICollector<TEntity> collector, Func<TEntity, bool> filter, Action<List<TEntity>> execute) : base(collector) { | |
this.filter = filter; | |
this.execute = execute; | |
} | |
protected override ICollector<TEntity> GetTrigger(IContext<TEntity> context) { | |
throw new Exception("should never be called"); | |
} | |
protected override bool Filter(TEntity entity) { | |
return filter(entity); | |
} | |
protected override void Execute(List<TEntity> entities) { | |
execute(entities); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment