Skip to content

Instantly share code, notes, and snippets.

@WeslomPo
Last active March 20, 2017 03:08
Show Gist options
  • Save WeslomPo/645750608efe9adc4752ae7f304417ae to your computer and use it in GitHub Desktop.
Save WeslomPo/645750608efe9adc4752ae7f304417ae to your computer and use it in GitHub Desktop.
Generic entitas
using System;
using Entitas;
using Entitas.Unity.VisualDebugging;
using Zenject;
namespace Generic {
public class Context<TEntity> : Entitas.Context<TEntity>, IInitializable where TEntity : class, IEntity, new() {
public readonly Matcher<TEntity> Matcher;
public Context(ContextInfo contextInfo, Matcher<TEntity> matcher)
: base(contextInfo.componentTypes.Length, 0, contextInfo) {
Matcher = matcher;
}
public void Initialize() {
#if(!ENTITAS_DISABLE_VISUAL_DEBUGGING && UNITY_EDITOR)
if (!UnityEngine.Application.isPlaying)
return;
var observer = new ContextObserver(this);
UnityEngine.Object.DontDestroyOnLoad(observer.gameObject);
#endif
}
public TEntity Get<T>() where T : IComponent {
return GetGroup(Matcher.For<T>()).GetSingleEntity();
}
public bool Has<T>() where T : IComponent {
return Get<T>() != null;
}
public TEntity Set<T>(T component) where T : IComponent {
if (Has<T>())
throw new Exception("Something went wrong with setting " + typeof(T) + " component.");
TEntity entity = CreateEntity();
entity.AddComponent(component);
return entity;
}
public TEntity Replace<T>(T component) where T : IComponent {
TEntity entity = Get<T>();
if (entity == null)
return Set(component);
entity.ReplaceComponent(component);
return entity;
}
public void Remove<T>() where T : IComponent {
DestroyEntity(Get<T>());
}
}
}
using System;
using Entitas;
namespace Generic {
public class Entity : Entitas.Entity {
public void AddComponent<T>(T component) where T : IComponent {
AddComponent(contextInfo.IndexOf<T>(), component);
}
public void RemoveComponent<T>() where T : IComponent {
RemoveComponent(contextInfo.IndexOf<T>());
}
public void ReplaceComponent<T>(T component) where T : IComponent {
ReplaceComponent(contextInfo.IndexOf<T>(), component);
}
public T GetComponent<T>() where T : IComponent {
return (T) base.GetComponent(contextInfo.IndexOf<T>());
}
public bool HasComponent<T>() where T : IComponent {
return HasComponent(contextInfo.IndexOf<T>());
}
public bool HasComponents(Type[] components) {
return HasComponents(contextInfo.IndicesOf(components));
}
public bool HasAnyComponent(Type[] components) {
return HasAnyComponent(contextInfo.IndicesOf(components));
}
}
}
using Entitas;
namespace Generic {
public class GameContext : Context<Entity> {
public GameContext(ContextInfo contextInfo) : base(contextInfo, new Matcher<Entity>(contextInfo)) {
}
}
}
using System;
using Entitas;
using Generic;
using Zenject;
namespace Installers {
public class ContextInstaller : MonoInstaller {
public override void InstallBindings() {
GameContext();
}
public void GameContext() {
Type[] components = {
typeof(DebugMessage),
typeof(Position)
};
string[] names = new string[components.Length];
for (int index = 0; index < components.Length; index++)
names[index] = components[index].ToString();
Container.Bind<ContextInfo>()
.FromInstance(new ContextInfo("Game", names, components))
.WhenInjectedInto<GameContext>();
Container.BindInterfacesAndSelfTo<GameContext>().AsSingle();
}
}
}
using System.Collections.Generic;
using Entitas;
using Generic;
using UnityEngine;
using Entity = Generic.Entity;
namespace Systems {
public class DebugMessageSystem : ReactiveSystem<Entity>
{
private readonly GameContext _context;
public DebugMessageSystem(GameContext context) : base(context) {
_context = context;
}
protected override Collector<Entity> GetTrigger(IContext<Entity> context) {
return context.CreateCollector((context as GameContext).Matcher.For<DebugMessage>());
}
protected override bool Filter(Entity entity) {
return entity.HasComponent<DebugMessage>();
}
protected override void Execute(List<Entity> entities)
{
D.Log("Reactive", entities.Count);
foreach (var e in entities) {
DebugMessage component = e.GetComponent<DebugMessage>();
// This is my bicycle instead of Debug.Log
// D.Log(component.Message);
Debug.Log(component.Message);
}
}
}
}
using Entitas;
using Generic;
using UnityEngine;
namespace Systems {
public class Movings : IInitializeSystem, IExecuteSystem {
private readonly GameContext _context;
private DebugMessage _component;
public Movings(GameContext context) {
_context = context;
}
public void Initialize() {
_component = new DebugMessage {Message = "Test"};
}
public void Execute() {
_context.Replace(new DebugMessage {Message = "Test"});
}
}
}
using Entitas;
using Generic;
namespace Systems {
public class Hello : Feature {
public Hello(GameContext context) : base("HelloFeature") {
Add(new Movings(context));
Add(new DebugMessageSystem(context));
Add(new CleanUpDebug(context));
}
}
}
using System;
using Entitas;
using Generic;
using Zenject;
namespace Systems {
public class GameController : ITickable, ILateTickable, IInitializable, IDisposable {
private readonly GameContext _context;
private Entitas.Systems _systems;
[Inject]
public GameController(GameContext context) {
_context = context;
}
public void Initialize() {
_systems = new Feature("Systems").Add(new Hello(_context));
_systems.Initialize();
}
public void Tick() {
_systems.Execute();
}
public void LateTick() {
_systems.Cleanup();
}
public void Dispose() { }
}
}
using System;
using Entitas;
namespace Generic {
public static class LookupTable {
public static int IndexOf<T>(this ContextInfo contextInfo) where T : IComponent {
// Todo assert if -1
return Array.IndexOf(contextInfo.componentTypes, typeof(T));
}
public static int[] IndicesOf(this ContextInfo contextInfo, Type[] types) {
int[] indices = new int[types.Length];
for (int index = 0; index < types.Length; index++)
indices[index] = Array.IndexOf(contextInfo.componentTypes, types[index]);
return indices;
}
}
}
using System;
using System.Collections.Generic;
using Entitas;
namespace Generic {
public class Matcher<TEntity> where TEntity : class, IEntity, new() {
private readonly ContextInfo _contextInfo;
private readonly Dictionary<Type, IMatcher<TEntity>> _cache = new Dictionary<Type, IMatcher<TEntity>>();
public Matcher(ContextInfo contextInfo) {
_contextInfo = contextInfo;
}
public IMatcher<TEntity> For<T>() where T : IComponent {
Type type = typeof(T);
if (_cache.ContainsKey(type))
return _cache[type];
var matcher = (Entitas.Matcher<TEntity>) Entitas.Matcher<TEntity>.AllOf(_contextInfo.IndexOf<T>());
matcher.componentNames = _contextInfo.componentNames;
_cache[type] = matcher;
return matcher;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment