public static IDisposable OnAction(this object target, Action <ISerializedActionCall> listener, bool attachAfter = true) { if (!target.IsStateTreeNode()) { throw new InvalidOperationException("Can not listen for action on Non State Tree Node"); } void FireListener(IMiddlewareEvent call) { if (call.Type == MiddlewareEventType.Action && call.Id == call.RootId) { var source = call.Context.GetStateTreeNode(); var data = new SerializedActionCall { Name = call.Name, Path = StateTreeUtils.GetRelativePathBetweenNodes(target.GetStateTreeNode(), source), //TODO: serialize arguments Arguments = call.Arguments.ToArray() }; listener(data); } } Action <IMiddlewareEvent, Action <IMiddlewareEvent, Func <object, object> >, Action <object> > onAfterAction = (IMiddlewareEvent call, Action <IMiddlewareEvent, Func <object, object> > next, Action <object> action) => { next(call, null); FireListener(call); }; Action <IMiddlewareEvent, Action <IMiddlewareEvent, Func <object, object> >, Action <object> > onBeforeAction = (IMiddlewareEvent call, Action <IMiddlewareEvent, Func <object, object> > next, Action <object> action) => { FireListener(call); next(call, null); }; return(StateTreeAction.AddMiddleware(target.GetStateTree(), attachAfter ? onAfterAction : onBeforeAction)); }
public static string GetRelativePath(this object target, object relative) { return(StateTreeUtils.GetRelativePathBetweenNodes(target.GetStateTreeNode(), relative.GetStateTreeNode())); }