Skip to content

Instantly share code, notes, and snippets.

@KumoKairo
Last active April 22, 2018 02:29
Show Gist options
  • Save KumoKairo/b49473ba148a38cc54cc7469b252bebf to your computer and use it in GitHub Desktop.
Save KumoKairo/b49473ba148a38cc54cc7469b252bebf to your computer and use it in GitHub Desktop.
// -------------------------------
// Common action invoker interface
public interface IActionInvoker
{
string InvokingActionType { get; }
void Execute(Contexts contexts);
}
// -------------------------------
// -------------------------------
// Action component itself
using Entitas;
[Game]
public class ActionComponent : IComponent
{
public string type;
}
// -------------------------------
// -------------------------------
// An Entitas component for it (entitas as a DI container)
using Entitas;
using Entitas.CodeGeneration.Attributes;
[Game]
public class ActionInvokerComponent : IComponent
{
[EntityIndex]
public string type;
public IActionInvoker handler;
}
// -------------------------------
// -------------------------------
// Action implementation example
using Entitas;
public class SelectNextCarButtonHandler : IActionInvoker
{
public string InvokingActionType { get { return ActionTypes.SelectNextCar; } }
public void Execute(Contexts contexts)
{
var currentSelectedCarIndex = contexts.game.selectedCarId.value;
currentSelectedCarIndex += 1;
currentSelectedCarIndex %= contexts.game.GetEntities(GameMatcher.RuntimeCarData).Length;
contexts.game.ReplaceSelectedCarId(currentSelectedCarIndex);
}
}
// -------------------------------
// -------------------------------
// Invoking system with an optional Timer parameter
using System.Collections.Generic;
using Entitas;
public class InvokeActionsSystem : ReactiveSystem<GameEntity>
{
private Contexts _contexts;
public InvokeActionsSystem(Contexts contexts) : base(contexts.game)
{
_contexts = contexts;
}
protected override ICollector<GameEntity> GetTrigger(IContext<GameEntity> context)
{
return context.CreateCollector(GameMatcher.Timer.Removed(), GameMatcher.Action.Added());
}
protected override bool Filter(GameEntity entity)
{
return entity.hasAction && !entity.hasTimer;
}
protected override void Execute(List<GameEntity> entities)
{
foreach (var buttonPressEntity in entities)
{
var handlers = _contexts.game.GetEntitiesWithActionInvoker(buttonPressEntity.action.type);
foreach (var handler in handlers)
{
handler.actionInvoker.handler.Execute(_contexts);
}
buttonPressEntity.isDestroyed = true;
}
}
}
// -------------------------------
// -------------------------------
// Action registration system that registers all invokers on startup
// Reflection can be easily replaced with a code generator that runs that loop offline and creates an array of implementing types
using System;
using System.Reflection;
using Entitas;
public class InitializeActionInvokersSystem : IInitializeSystem
{
private Contexts _contexts;
public InitializeActionInvokersSystem(Contexts contexts)
{
_contexts = contexts;
}
public void Initialize()
{
var assembly = Assembly.GetAssembly(typeof(IActionInvoker));
var types = assembly.GetTypes();
foreach (var type in types)
{
if (type.IsClass && !type.IsAbstract && typeof(IActionInvoker).IsAssignableFrom(type))
{
var handler = (IActionInvoker) Activator.CreateInstance(type);
var handledType = handler.InvokingActionType;
var entity = _contexts.game.CreateEntity();
entity.AddActionInvoker(handledType, handler);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment