Last active
October 6, 2016 08:44
-
-
Save juanarzola/1d05c5941f344f224d221c0c0a0a3f3f to your computer and use it in GitHub Desktop.
UniRx observable wrappers for Entitas entity and group events
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; | |
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, | |
}; | |
} |
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 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; | |
} | |
} | |
} |
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 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); | |
} | |
} | |
} |
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 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; | |
} | |
} | |
} |
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 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); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for your detailed explanation!
Edit: maybe you can contact the Entitas guys so they can link to this gist in their wiki.