Skip to content

Instantly share code, notes, and snippets.

@juanarzola
Last active October 6, 2016 08:44
Show Gist options
  • Save juanarzola/1d05c5941f344f224d221c0c0a0a3f3f to your computer and use it in GitHub Desktop.
Save juanarzola/1d05c5941f344f224d221c0c0a0a3f3f to your computer and use it in GitHub Desktop.
UniRx observable wrappers for Entitas entity and group events
using System;
namespace Entitas {
/** Used in the *AnyChangeObservable methods to observe multiple change types */
[Flags]
public enum ChangeType : short{
Addition = 1 << 0,
Replacement = 1 << 1,
Removal = 1 << 2,
};
}
using System;
using UniRx;
namespace Entitas {
public class ComponentReplacedEventArgs<T> : EventArgs {
public Entity entity;
public int index;
public T previous;
public T current;
}
public class EntityChangedEventArgs<T> : EventArgs {
public Entity entity;
public int index;
public T component;
}
public partial class Entity {
// Component replaced observable
public IObservable<ComponentReplacedEventArgs<T>> OnComponentReplacedAsObservable<T>(){
var componentReplaced = Observable.FromEvent<ComponentReplaced, ComponentReplacedEventArgs<T>>(handler => {
ComponentReplaced componentReplacedHandler = (entity, index, previousComponent, newComponent) => {
if(previousComponent is T){
var args = new ComponentReplacedEventArgs<T>();
args.entity = entity;
args.index = index;
args.previous = (T)previousComponent;
args.current = (T)newComponent;
handler(args);
}
};
return componentReplacedHandler;
},
componentReplacedHandler => OnComponentReplaced += componentReplacedHandler,
componentReplacedHandler => OnComponentReplaced -= componentReplacedHandler);
return componentReplaced;
}
// Component added observable
public IObservable<EntityChangedEventArgs<T>> OnComponentAddedAsObservable<T>(){
var componentAdded = Observable.FromEvent<EntityChanged, EntityChangedEventArgs<T>>(handler => {
EntityChanged componentAddedHandler = (entity, index, component) => {
if(component is T){
var args = new EntityChangedEventArgs<T>();
args.entity = entity;
args.index = index;
args.component = (T)component;
handler(args);
}
};
return componentAddedHandler;
},
componentAddedHandler => OnComponentAdded += componentAddedHandler,
componentAddedHandler => OnComponentAdded -= componentAddedHandler);
return componentAdded;
}
// Component removed observable
public IObservable<EntityChangedEventArgs<T>> OnComponentRemovedAsObservable<T>(){
var componentRemoved = Observable.FromEvent<EntityChanged, EntityChangedEventArgs<T>>(handler => {
EntityChanged componentRemovedHandler = (entity, index, component) => {
if(component is T){
var args = new EntityChangedEventArgs<T>();
args.entity = entity;
args.index = index;
args.component = (T)component;
handler(args);
}
};
return componentRemovedHandler;
},
componentRemovedHandler => OnComponentRemoved += componentRemovedHandler,
componentRemovedHandler => OnComponentRemoved -= componentRemovedHandler);
return componentRemoved;
}
}
}
using System;
using System.Collections.Generic;
using UniRx;
namespace Entitas {
public class AnyComponentChangeEventArgs<T> : EventArgs {
public EntityChangedEventArgs<T> addition;
public ComponentReplacedEventArgs<T> replacement;
public EntityChangedEventArgs<T> removal;
}
public partial class Entity {
/** A component of type T had any of the changes specified in 'changeTypes'. The appropriate 'replacement', 'addition' or 'removal' field will be set in the resulting AnyComponentChangeEventArgs. */
public IObservable<AnyComponentChangeEventArgs<T>> OnAnyChangeObservable<T>(ChangeType changeTypes = ChangeType.Addition | ChangeType.Replacement | ChangeType.Removal){
List<IObservable<AnyComponentChangeEventArgs<T>>> observedChanges = new List<IObservable<AnyComponentChangeEventArgs<T>>>();
if((changeTypes & ChangeType.Addition) == ChangeType.Addition){
var componentAdded = OnComponentAddedAsObservable<T>().Select<EntityChangedEventArgs<T>, AnyComponentChangeEventArgs<T>>(addition => {
var change = new AnyComponentChangeEventArgs<T>();
change.addition = addition;
return change;
});
observedChanges.Add(componentAdded);
}
if((changeTypes & ChangeType.Replacement) == ChangeType.Replacement){
var componentReplaced = OnComponentReplacedAsObservable<T>().Select<ComponentReplacedEventArgs<T>, AnyComponentChangeEventArgs<T>>(replacement => {
var change = new AnyComponentChangeEventArgs<T>();
change.replacement = replacement;
return change;
});
observedChanges.Add(componentReplaced);
}
if((changeTypes & ChangeType.Removal) == ChangeType.Removal){
var componentRemoved = OnComponentRemovedAsObservable<T>().Select<EntityChangedEventArgs<T>, AnyComponentChangeEventArgs<T>>(removal => {
var change = new AnyComponentChangeEventArgs<T>();
change.removal = removal;
return change;
});
observedChanges.Add(componentRemoved);
}
return Observable.Merge(observedChanges);
}
}
}
using System;
using UniRx;
namespace Entitas {
public class GroupChangedEventArgs<T> : EventArgs {
public Group group;
public Entity entity;
public int index;
public T component;
}
public class GroupUpdatedEventArgs<T> : EventArgs {
public Group group;
public Entity entity;
public int index;
public T previous;
public T current;
}
public partial class Group {
// Entity added observable
public IObservable<GroupChangedEventArgs<T>> OnEntityAddedAsObservable<T>(){
var entityAdded = Observable.FromEvent<GroupChanged, GroupChangedEventArgs<T>>(handler => {
GroupChanged entityAddedHandler = (group, entity, index, component) => {
if(component is T){
var args = new GroupChangedEventArgs<T>();
args.group = group;
args.entity = entity;
args.index = index;
args.component = (T)component;
handler(args);
}
};
return entityAddedHandler;
},
entityAddedHandler => OnEntityAdded += entityAddedHandler,
entityAddedHandler => OnEntityAdded -= entityAddedHandler);
return entityAdded;
}
// Entity removed observable
public IObservable<GroupChangedEventArgs<T>> OnEntityRemovedAsObservable<T>(){
var entityRemoved = Observable.FromEvent<GroupChanged, GroupChangedEventArgs<T>>(handler => {
GroupChanged entityRemovedHandler = (group, entity, index, component) => {
if(component is T){
var args = new GroupChangedEventArgs<T>();
args.group = group;
args.entity = entity;
args.index = index;
args.component = (T)component;
handler(args);
}
};
return entityRemovedHandler;
},
entityRemovedHandler => OnEntityRemoved += entityRemovedHandler,
entityRemovedHandler => OnEntityRemoved -= entityRemovedHandler);
return entityRemoved;
}
// Entity updated observable
public IObservable<GroupUpdatedEventArgs<T>> OnEntityUpdatedAsObservable<T>(){
var entityUpdated = Observable.FromEvent<GroupUpdated, GroupUpdatedEventArgs<T>>(handler => {
GroupUpdated entityRemovedHandler = (group, entity, index, previous, current) => {
if(previous is T){
var args = new GroupUpdatedEventArgs<T>();
args.group = group;
args.entity = entity;
args.index = index;
args.previous = (T)previous;
args.current = (T)current;
handler(args);
}
};
return entityRemovedHandler;
},
entityUpdatedHandler => OnEntityUpdated += entityUpdatedHandler,
entityUpdatedHandler => OnEntityUpdated -= entityUpdatedHandler);
return entityUpdated;
}
}
}
using System;
using System.Collections.Generic;
using UniRx;
namespace Entitas {
public class AnyEntityChangeEventArgs<T> : EventArgs {
public GroupChangedEventArgs<T> addition;
public GroupUpdatedEventArgs<T> update;
public GroupChangedEventArgs<T> removal;
}
public partial class Group {
/** A component of type T had any of the changes specified in 'changeTypes' within the group. The appropriate 'update', 'addition' or 'removal' field will be set in the resulting AnyEntityChangeEventArgs. */
public IObservable<AnyEntityChangeEventArgs<T>> OnAnyEntityChangeObservable<T>(ChangeType changeTypes = ChangeType.Addition | ChangeType.Replacement | ChangeType.Removal){
List<IObservable<AnyEntityChangeEventArgs<T>>> observedChanges = new List<IObservable<AnyEntityChangeEventArgs<T>>>();
if((changeTypes & ChangeType.Addition) == ChangeType.Addition){
var entityAdded = OnEntityAddedAsObservable<T>().Select<GroupChangedEventArgs<T>, AnyEntityChangeEventArgs<T>>(addition => {
var change = new AnyEntityChangeEventArgs<T>();
change.addition = addition;
return change;
});
observedChanges.Add(entityAdded);
}
if((changeTypes & ChangeType.Replacement) == ChangeType.Replacement){
var entityUpdated = OnEntityUpdatedAsObservable<T>().Select<GroupUpdatedEventArgs<T>, AnyEntityChangeEventArgs<T>>(update => {
var change = new AnyEntityChangeEventArgs<T>();
change.update = update;
return change;
});
observedChanges.Add(entityUpdated);
}
if((changeTypes & ChangeType.Removal) == ChangeType.Removal){
var entityRemoved = OnEntityRemovedAsObservable<T>().Select<GroupChangedEventArgs<T>, AnyEntityChangeEventArgs<T>>(removal => {
var change = new AnyEntityChangeEventArgs<T>();
change.removal = removal;
return change;
});
observedChanges.Add(entityRemoved);
}
return Observable.Merge(observedChanges);
}
}
}
@juanarzola
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment