Beispiel #1
0
        /// <summary>
        /// Adds a composite event to the state machine. A composite event is triggered when all
        /// off the required events have been raised. Note that required events cannot be in the initial
        /// state since it would cause extra instances of the state machine to be created
        /// </summary>
        /// <param name="propertyExpression">The composite event</param>
        /// <param name="trackingPropertyExpression">The property in the instance used to track the state of the composite event</param>
        /// <param name="options">Options on the composite event</param>
        /// <param name="events">The events that must be raised before the composite event is raised</param>
        protected virtual void CompositeEvent(Expression <Func <Event> > propertyExpression,
                                              Expression <Func <TInstance, int> > trackingPropertyExpression,
                                              CompositeEventOptions options,
                                              params Event[] events)
        {
            PropertyInfo trackingPropertyInfo = trackingPropertyExpression.GetPropertyInfo();

            var accessor = new IntCompositeEventStatusAccessor <TInstance>(trackingPropertyInfo);

            CompositeEvent(propertyExpression, accessor, options, events);
        }
Beispiel #2
0
        void CompositeEvent(Expression <Func <Event> > propertyExpression, CompositeEventStatusAccessor <TInstance> accessor,
                            CompositeEventOptions options, Event[] events)
        {
            if (events == null)
            {
                throw new ArgumentNullException(nameof(events));
            }
            if (events.Length > 31)
            {
                throw new ArgumentException("No more than 31 events can be combined into a single event");
            }
            if (events.Length == 0)
            {
                throw new ArgumentException("At least one event must be specified for a composite event");
            }
            if (events.Any(x => x == null))
            {
                throw new ArgumentException("One or more events specified has not yet been initialized");
            }

            PropertyInfo eventProperty = propertyExpression.GetPropertyInfo();

            string name = eventProperty.Name;

            var @event = new TriggerEvent(name);

            eventProperty.SetValue(this, @event);

            _eventCache[name] = new StateMachineEvent <TInstance>(@event, false);

            var complete = new CompositeEventStatus(Enumerable.Range(0, events.Length)
                                                    .Aggregate(0, (current, x) => current | (1 << x)));

            for (int i = 0; i < events.Length; i++)
            {
                int flag = 1 << i;

                var activity = new CompositeEventActivity <TInstance>(accessor, flag, complete, @event);

                Func <State <TInstance>, bool> filter = x => options.HasFlag(CompositeEventOptions.IncludeInitial) || !Equals(x, Initial);
                foreach (var state in _stateCache.Values.Where(filter))
                {
                    During(state,
                           When(events[i])
                           .Execute(x => activity));
                }
            }
        }
 public StateMachineModifier <TInstance> CompositeEvent(Event @event,
                                                        Expression <Func <TInstance, CompositeEventStatus> > trackingPropertyExpression, CompositeEventOptions options,
                                                        params Event[] events)
 {
     _machine.CompositeEvent(@event, trackingPropertyExpression, options, events);
     return(this);
 }
 public StateMachineModifier <TInstance> CompositeEvent(Event @event, Expression <Func <TInstance, int> > trackingPropertyExpression,
                                                        CompositeEventOptions options, params Event[] events)
 {
     return(CommitActivities().CompositeEvent(@event, trackingPropertyExpression, options, events));
 }