diff --git a/src/Automatonymous.Tests/Activity_Specs.cs b/src/Automatonymous.Tests/Activity_Specs.cs index 80d5834..3834e86 100644 --- a/src/Automatonymous.Tests/Activity_Specs.cs +++ b/src/Automatonymous.Tests/Activity_Specs.cs @@ -50,10 +50,6 @@ public InstanceStateMachine() { InstanceState(x => x.CurrentState); - State(() => Running); - - Event(() => Initialized); - During(Initial, When(Initialized) .TransitionTo(Running)); @@ -101,10 +97,6 @@ public InstanceStateMachine() { InstanceState(x => x.CurrentState); - State(() => Running); - - Event(() => Initialized); - Initially( When(Initialized) .TransitionTo(Running)); @@ -159,10 +151,6 @@ class InstanceStateMachine : public InstanceStateMachine() { - State(() => Running); - - Event(() => Initialized); - Initially( When(Initialized) .Finalize()); @@ -233,11 +221,6 @@ public InstanceStateMachine() { InstanceState(x => x.CurrentState); - State(() => Initializing); - State(() => Running); - - Event(() => Initialized); - During(Initializing, When(Initialized) .TransitionTo(Running)); diff --git a/src/Automatonymous.Tests/Anytime_Specs.cs b/src/Automatonymous.Tests/Anytime_Specs.cs index 17ac414..06937c6 100644 --- a/src/Automatonymous.Tests/Anytime_Specs.cs +++ b/src/Automatonymous.Tests/Anytime_Specs.cs @@ -84,12 +84,6 @@ class TestStateMachine : { public TestStateMachine() { - State(() => Ready); - - Event(() => Init); - Event(() => Hello); - Event(() => EventA); - Initially( When(Init) .TransitionTo(Ready)); diff --git a/src/Automatonymous.Tests/AsyncActivity_Specs.cs b/src/Automatonymous.Tests/AsyncActivity_Specs.cs index efbdc65..2f56605 100644 --- a/src/Automatonymous.Tests/AsyncActivity_Specs.cs +++ b/src/Automatonymous.Tests/AsyncActivity_Specs.cs @@ -67,10 +67,6 @@ public TestStateMachine() { InstanceState(x => x.CurrentState); - State(() => Running); - - Event(() => Create); - During(Initial, When(Create) .Then(() => new SetValueAsyncActivity()) diff --git a/src/Automatonymous.Tests/Automatonymous.Tests.csproj b/src/Automatonymous.Tests/Automatonymous.Tests.csproj index 3d19f09..bba89d1 100644 --- a/src/Automatonymous.Tests/Automatonymous.Tests.csproj +++ b/src/Automatonymous.Tests/Automatonymous.Tests.csproj @@ -53,6 +53,7 @@ SolutionVersion.cs + diff --git a/src/Automatonymous.Tests/AutomatonymousStateMachine_Specs.cs b/src/Automatonymous.Tests/AutomatonymousStateMachine_Specs.cs new file mode 100644 index 0000000..3db6264 --- /dev/null +++ b/src/Automatonymous.Tests/AutomatonymousStateMachine_Specs.cs @@ -0,0 +1,141 @@ +// Copyright 2011 Chris Patterson, Dru Sellers +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use +// this file except in compliance with the License. You may obtain a copy of the +// License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. +namespace Automatonymous.Tests +{ + using System.Linq; + + using NUnit.Framework; + + + [TestFixture] + public class Using_a_simple_state_machine + { + [Test] + public void Should_register_all_state_properties() + { + var stateMachine = new TestStateMachine(); + + var states = stateMachine.States.ToList(); + + Assert.That(states, Has.Count.EqualTo(3)); + } + + [Test] + public void Should_register_inherited_initial_state_property() + { + var stateMachine = new TestStateMachine(); + + Assert.That(stateMachine.States, Contains.Item(stateMachine.Initial)); + } + + [Test] + public void Should_register_inherited_final_state_property() + { + var stateMachine = new TestStateMachine(); + + Assert.That(stateMachine.States, Contains.Item(stateMachine.Final)); + } + + [Test] + public void Should_register_declared_state_property() + { + var stateMachine = new TestStateMachine(); + + Assert.That(stateMachine.States, Contains.Item(stateMachine.ThisIsAState)); + } + + [Test] + public void Should_initialize_inherited_initial_state_property() + { + var stateMachine = new TestStateMachine(); + + Assert.That(stateMachine.Initial, Is.Not.Null); + } + + [Test] + public void Should_initialize_inherited_final_state_property() + { + var stateMachine = new TestStateMachine(); + + Assert.That(stateMachine.Final, Is.Not.Null); + } + + [Test] + public void Should_initialize_declared_state_property() + { + var stateMachine = new TestStateMachine(); + + Assert.That(stateMachine.ThisIsAState, Is.Not.Null); + } + + [Test] + public void Should_register_all_event_properties() + { + var stateMachine = new TestStateMachine(); + + var events = stateMachine.Events.ToList(); + + Assert.That(events, Has.Count.EqualTo(2)); + } + + [Test] + public void Should_register_simple_event_property() + { + var stateMachine = new TestStateMachine(); + + Assert.That(stateMachine.Events, Contains.Item(stateMachine.ThisIsASimpleEvent)); + } + + [Test] + public void Should_register_generic_event_property() + { + var stateMachine = new TestStateMachine(); + + Assert.That(stateMachine.Events, Contains.Item(stateMachine.ThisIsAnEventConsumingData)); + } + + [Test] + public void Should_initialize_simple_event_property() + { + var stateMachine = new TestStateMachine(); + + Assert.That(stateMachine.ThisIsASimpleEvent, Is.Not.Null); + } + + [Test] + public void Should_initialize_generic_event_property() + { + var stateMachine = new TestStateMachine(); + + Assert.That(stateMachine.ThisIsAnEventConsumingData, Is.Not.Null); + } + + + class Instance + { + } + + + class EventData + { + } + + + class TestStateMachine : AutomatonymousStateMachine + { + public State ThisIsAState { get; private set; } + public Event ThisIsASimpleEvent { get; private set; } + public Event ThisIsAnEventConsumingData { get; private set; } + } + } +} diff --git a/src/Automatonymous.Tests/Combine_Specs.cs b/src/Automatonymous.Tests/Combine_Specs.cs index 9543aa8..d82941f 100644 --- a/src/Automatonymous.Tests/Combine_Specs.cs +++ b/src/Automatonymous.Tests/Combine_Specs.cs @@ -72,12 +72,8 @@ class TestStateMachine : public TestStateMachine() { InstanceState(x => x.CurrentState); - State(() => Waiting); - Event(() => Start); - Event(() => First); - Event(() => Second); - Event(() => Third, x => x.CompositeStatus, First, Second); + ComposeEvent(Third, x => x.CompositeStatus, First, Second); Initially( When(Start) @@ -97,4 +93,4 @@ public TestStateMachine() public Event Third { get; private set; } } } -} \ No newline at end of file +} diff --git a/src/Automatonymous.Tests/DataActivity_Specs.cs b/src/Automatonymous.Tests/DataActivity_Specs.cs index 3d43c52..51906fe 100644 --- a/src/Automatonymous.Tests/DataActivity_Specs.cs +++ b/src/Automatonymous.Tests/DataActivity_Specs.cs @@ -75,11 +75,6 @@ public InstanceStateMachine() { InstanceState(x => x.CurrentState); - State(() => Running); - - Event(() => Initialized); - Event(() => PassedValue); - During(Initial, When(Initialized) .Then((instance, data) => instance.Value = data.Value) diff --git a/src/Automatonymous.Tests/Declarative_Specs.cs b/src/Automatonymous.Tests/Declarative_Specs.cs index bf5ed42..1775f71 100644 --- a/src/Automatonymous.Tests/Declarative_Specs.cs +++ b/src/Automatonymous.Tests/Declarative_Specs.cs @@ -68,10 +68,6 @@ public TopInstanceStateMachine() { InstanceState(x => x.Top); - State(() => Greeted); - - Event(() => Initialized); - During(Initial, When(Initialized) .TransitionTo(Greeted)); @@ -89,10 +85,6 @@ public BottomInstanceStateMachine() { InstanceState(x => x.Bottom); - State(() => Ignored); - - Event(() => Initialized); - During(Initial, When(Initialized) .TransitionTo(Ignored)); diff --git a/src/Automatonymous.Tests/Dependency_Specs.cs b/src/Automatonymous.Tests/Dependency_Specs.cs index 970857d..4497d87 100644 --- a/src/Automatonymous.Tests/Dependency_Specs.cs +++ b/src/Automatonymous.Tests/Dependency_Specs.cs @@ -102,10 +102,6 @@ public InstanceStateMachine() { InstanceState(x => x.CurrentState); - State(() => Running); - - Event(() => Create); - During(Initial, When(Create) .Then(() => new CalculateValueActivity(new LocalCalculator())) diff --git a/src/Automatonymous.Tests/EventLift_Specs.cs b/src/Automatonymous.Tests/EventLift_Specs.cs index a2185c3..33eb84b 100644 --- a/src/Automatonymous.Tests/EventLift_Specs.cs +++ b/src/Automatonymous.Tests/EventLift_Specs.cs @@ -50,10 +50,6 @@ class InstanceStateMachine : { public InstanceStateMachine() { - State(() => Running); - - Event(() => Initialized); - During(Initial, When(Initialized) .TransitionTo(Running)); @@ -107,10 +103,6 @@ public InstanceStateMachine() { InstanceState(x => x.CurrentState); - State(() => Running); - - Event(() => Initialized); - During(Initial, When(Initialized) .TransitionTo(Running)); diff --git a/src/Automatonymous.Tests/EventObservable_Specs.cs b/src/Automatonymous.Tests/EventObservable_Specs.cs index 8913e62..4401263 100644 --- a/src/Automatonymous.Tests/EventObservable_Specs.cs +++ b/src/Automatonymous.Tests/EventObservable_Specs.cs @@ -86,10 +86,6 @@ public InstanceStateMachine() { InstanceState(x => x.CurrentState); - State(() => Running); - - Event(() => Initialized); - During(Initial, When(Initialized) .TransitionTo(Running)); diff --git a/src/Automatonymous.Tests/Event_Specs.cs b/src/Automatonymous.Tests/Event_Specs.cs index 44c8491..b4c4b5a 100644 --- a/src/Automatonymous.Tests/Event_Specs.cs +++ b/src/Automatonymous.Tests/Event_Specs.cs @@ -73,9 +73,6 @@ class TestStateMachine : { public TestStateMachine() { - Event(() => Hello); - Event(() => EventA); - Event(() => EventInt); } public Event Hello { get; private set; } diff --git a/src/Automatonymous.Tests/Exception_Specs.cs b/src/Automatonymous.Tests/Exception_Specs.cs index 98aa374..2dd8041 100644 --- a/src/Automatonymous.Tests/Exception_Specs.cs +++ b/src/Automatonymous.Tests/Exception_Specs.cs @@ -84,10 +84,6 @@ public InstanceStateMachine() { InstanceState(x => x.CurrentState); - State(() => Failed); - - Event(() => Initialized); - During(Initial, When(Initialized) .Try(x => x.Then(instance => instance.Called = true) @@ -185,10 +181,6 @@ public InstanceStateMachine() { InstanceState(x => x.CurrentState); - State(() => Failed); - - Event(() => Initialized); - During(Initial, When(Initialized) .Try(x => x.Then(instance => instance.Called = true) diff --git a/src/Automatonymous.Tests/FilterExpression_Specs.cs b/src/Automatonymous.Tests/FilterExpression_Specs.cs index f13dc0a..a63079e 100644 --- a/src/Automatonymous.Tests/FilterExpression_Specs.cs +++ b/src/Automatonymous.Tests/FilterExpression_Specs.cs @@ -45,11 +45,6 @@ public InstanceStateMachine() { InstanceState(x => x.CurrentState); - State(() => True); - State(() => False); - - Event(() => Thing); - During(Initial, When(Thing, msg => msg.Condition) .TransitionTo(True), diff --git a/src/Automatonymous.Tests/Group_Specs.cs b/src/Automatonymous.Tests/Group_Specs.cs index d76eb16..ce344c0 100644 --- a/src/Automatonymous.Tests/Group_Specs.cs +++ b/src/Automatonymous.Tests/Group_Specs.cs @@ -77,10 +77,6 @@ public PitStop() { InstanceState(x => x.OverallState); - State(() => BeingServiced); - - Event(() => VehicleArrived); - During(Initial, When(VehicleArrived) .Then((instance, m) => @@ -110,8 +106,6 @@ public FillTank() { InstanceState(x => x.FuelState); - State(() => Filling); - Initially( When(Initial.Enter) .TransitionTo(Filling)); @@ -140,8 +134,6 @@ public CheckOil() { InstanceState(x => x.OilState); - State(() => AddingOil); - Initially( When(Initial.Enter) .TransitionTo(AddingOil)); diff --git a/src/Automatonymous.Tests/InstanceLift_Specs.cs b/src/Automatonymous.Tests/InstanceLift_Specs.cs index a430efc..8f2f309 100644 --- a/src/Automatonymous.Tests/InstanceLift_Specs.cs +++ b/src/Automatonymous.Tests/InstanceLift_Specs.cs @@ -53,10 +53,6 @@ public InstanceStateMachine() { InstanceState(x => x.CurrentState); - State(() => Running); - - Event(() => Initialized); - During(Initial, When(Initialized) .TransitionTo(Running)); @@ -111,10 +107,6 @@ public InstanceStateMachine() { InstanceState(x => x.CurrentState); - State(() => Running); - - Event(() => Initialized); - During(Initial, When(Initialized) .TransitionTo(Running)); diff --git a/src/Automatonymous.Tests/Introspection_Specs.cs b/src/Automatonymous.Tests/Introspection_Specs.cs index 9f269a5..e727250 100644 --- a/src/Automatonymous.Tests/Introspection_Specs.cs +++ b/src/Automatonymous.Tests/Introspection_Specs.cs @@ -89,15 +89,6 @@ public TestStateMachine() { InstanceState(x => x.CurrentState); - Event(() => Hello); - Event(() => YelledAt); - Event(() => Handshake); - Event(() => Ignored); - - State(() => Greeted); - State(() => Loved); - State(() => Pissed); - Initially( When(Hello) .TransitionTo(Greeted)); diff --git a/src/Automatonymous.Tests/Observable_Specs.cs b/src/Automatonymous.Tests/Observable_Specs.cs index 72f07d1..0974786 100644 --- a/src/Automatonymous.Tests/Observable_Specs.cs +++ b/src/Automatonymous.Tests/Observable_Specs.cs @@ -69,11 +69,6 @@ class InstanceStateMachine : { public InstanceStateMachine() { - State(() => Running); - - Event(() => Initialized); - Event(() => Finish); - During(Initial, When(Initialized) .TransitionTo(Running)); diff --git a/src/Automatonymous.Tests/SerializeState_Specs.cs b/src/Automatonymous.Tests/SerializeState_Specs.cs index 0c26c45..c69bfc5 100644 --- a/src/Automatonymous.Tests/SerializeState_Specs.cs +++ b/src/Automatonymous.Tests/SerializeState_Specs.cs @@ -55,11 +55,6 @@ public InstanceStateMachine() { InstanceState(x => x.CurrentState); - State(() => True); - State(() => False); - - Event(() => Thing); - During(Initial, When(Thing, msg => msg.Condition) .TransitionTo(True), diff --git a/src/Automatonymous.Tests/State_Specs.cs b/src/Automatonymous.Tests/State_Specs.cs index b2af85d..9a0606f 100644 --- a/src/Automatonymous.Tests/State_Specs.cs +++ b/src/Automatonymous.Tests/State_Specs.cs @@ -63,8 +63,6 @@ class TestStateMachine : public TestStateMachine() { InstanceState(x => x.CurrentState); - - State(() => Running); } public State Running { get; private set; } @@ -144,9 +142,6 @@ public TestStateMachine() { InstanceState(x => x.AutomatonymousState); - State(() => Running); - Event(() => Started); - Initially( When(Started) .TransitionTo(Running)); diff --git a/src/Automatonymous.Tests/Transition_Specs.cs b/src/Automatonymous.Tests/Transition_Specs.cs index d09023b..515f1e9 100644 --- a/src/Automatonymous.Tests/Transition_Specs.cs +++ b/src/Automatonymous.Tests/Transition_Specs.cs @@ -75,11 +75,6 @@ class InstanceStateMachine : { public InstanceStateMachine() { - State(() => Running); - - Event(() => Initialized); - Event(() => Finish); - During(Initial, When(Initialized) .TransitionTo(Running)); diff --git a/src/Automatonymous.Tests/Visualizer_Specs.cs b/src/Automatonymous.Tests/Visualizer_Specs.cs index b6b6c62..9e11105 100644 --- a/src/Automatonymous.Tests/Visualizer_Specs.cs +++ b/src/Automatonymous.Tests/Visualizer_Specs.cs @@ -88,17 +88,7 @@ class InstanceStateMachine : { public InstanceStateMachine() { - InstanceState(x => x.CurrentState); - - State(() => Running); - State(() => Suspended); - State(() => Failed); - - Event(() => Initialized); - Event(() => Finished); - Event(() => Suspend); - Event(() => Resume); - Event(() => Restart); + InstanceState(x => x.CurrentState); During(Initial, When(Initialized) diff --git a/src/Automatonymous/AutomatonymousStateMachine.cs b/src/Automatonymous/AutomatonymousStateMachine.cs index f97f53f..0a1d7ef 100644 --- a/src/Automatonymous/AutomatonymousStateMachine.cs +++ b/src/Automatonymous/AutomatonymousStateMachine.cs @@ -13,20 +13,68 @@ namespace Automatonymous { using System; + using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; + using Activities; + using Binders; + using Impl; + using Internals.Caching; using Internals.Extensions; using Internals.Primitives; + using Taskell; + public abstract class AutomatonymousStateMachine + { + private static readonly object PropertyLocker = new object(); + private static readonly IDictionary> Properties = new ConcurrentDictionary>(); + + protected static readonly Type OpenGenericDataEventType = typeof (DataEvent<>); + + // TODO: make this an Extension Method of Type + private static IEnumerable GetInheritanceChain(Type type, bool includeSelf = true) + { + var b = includeSelf ? type : type.BaseType; + + while (b != null) + { + yield return b; + + b = b.BaseType; + } + } + + protected static IEnumerable GetProperties(Type type) + { + if (Properties.ContainsKey(type) == false) + { + lock (PropertyLocker) + { + if (Properties.ContainsKey(type) == false) + { + var properties = GetInheritanceChain(type) + .SelectMany(x => x.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) + .ToList(); + + Properties[type] = properties; + } + } + } + + return Properties[type]; + } + } + public abstract class AutomatonymousStateMachine : + AutomatonymousStateMachine, AcceptStateMachineInspector, StateMachine where TInstance : class @@ -47,11 +95,10 @@ protected AutomatonymousStateMachine() _eventRaisingObserver = new EventRaisingObserver(_eventCache); _eventRaisedObserver = new EventRaisedObserver(_eventCache); - State(() => Initial); - State(() => Final); + RegisterStates(); + RegisterEvents(); - _instanceStateAccessor = new DefaultInstanceStateAccessor(_stateCache[Initial.Name], - _stateChangedObservable); + _instanceStateAccessor = new DefaultInstanceStateAccessor(_stateCache[Initial.Name], _stateChangedObservable); } public void Accept(StateMachineInspector inspector) @@ -59,17 +106,17 @@ public void Accept(StateMachineInspector inspector) Initial.Accept(inspector); _stateCache.Each(x => - { - if (Equals(x, Initial) || Equals(x, Final)) - return; + { + if (Equals(x, Initial) || Equals(x, Final)) + return; - x.Accept(inspector); - }); + x.Accept(inspector); + }); Final.Accept(inspector); } - StateAccessor StateMachine.InstanceStateAccessor + public StateAccessor InstanceStateAccessor { get { return _instanceStateAccessor; } } @@ -85,25 +132,25 @@ State StateMachine.GetState(string name) void StateMachine.RaiseEvent(Composer composer, TInstance instance, Event @event) { composer.Execute(() => - { - State state = _instanceStateAccessor.Get(instance); + { + State state = _instanceStateAccessor.Get(instance); - State instanceState = _stateCache[state.Name]; + State instanceState = _stateCache[state.Name]; - return composer.ComposeEvent(instance, instanceState, @event); - }); + return composer.ComposeEvent(instance, instanceState, @event); + }); } void StateMachine.RaiseEvent(Composer composer, TInstance instance, Event @event, TData data) { composer.Execute(() => - { - State state = _instanceStateAccessor.Get(instance); + { + State state = _instanceStateAccessor.Get(instance); - State instanceState = _stateCache[state.Name]; + State instanceState = _stateCache[state.Name]; - return composer.ComposeEvent(instance, instanceState, @event, data); - }); + return composer.ComposeEvent(instance, instanceState, @event, data); + }); } public State GetState(string name) @@ -171,17 +218,49 @@ protected void InstanceState(Expression> instanceStatePro _stateCache[Initial.Name], _stateChangedObservable); } - protected void Event(Expression> propertyExpression) + void RegisterEvents() { - PropertyInfo property = propertyExpression.GetPropertyInfo(); + var properties = GetProperties(GetType()) + .Where(x => typeof(Event).IsAssignableFrom(x.PropertyType)); // TODO: this may just need to be equals - string name = property.Name; + foreach (var property in properties) + { + var name = property.Name; - var @event = new SimpleEvent(name); + Event @event; - property.SetValue(this, @event); + if (property.PropertyType.IsGenericType) + { + var dataEventType = OpenGenericDataEventType.MakeGenericType(property.PropertyType.GetGenericArguments()); - _eventCache[name] = new StateMachineEvent(@event); + @event = (Event)Activator.CreateInstance(dataEventType, name); + } + else + { + @event = new SimpleEvent(name); + } + + _eventCache[name] = new StateMachineEvent(@event); + + property.SetValue(this, @event); + } + } + + void RegisterStates() + { + var properties = GetProperties(GetType()) + .Where(x => typeof(State).IsAssignableFrom(x.PropertyType)); // TODO: this may just need to be equals + + foreach (var property in properties) + { + var name = property.Name; + + State state = new StateImpl(name, _eventRaisingObserver, _eventRaisedObserver); + + _stateCache[name] = state; + + property.SetValue(this, state); + } } /// @@ -189,42 +268,46 @@ protected void Event(Expression> propertyExpression) /// 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 /// - /// The composite event + /// The composite event /// The property in the instance used to track the state of the composite event /// The events that must be raised before the composite event is raised - protected void Event(Expression> propertyExpression, + protected void ComposeEvent(Event @event, Expression> trackingPropertyExpression, params Event[] events) { + // TODO: check @event for null??? + if (events == null) + { throw new ArgumentNullException("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(); PropertyInfo trackingPropertyInfo = trackingPropertyExpression.GetPropertyInfo(); - string name = eventProperty.Name; - - var @event = new SimpleEvent(name); - - eventProperty.SetValue(this, @event); - - _eventCache[name] = new StateMachineEvent(@event); - var complete = new CompositeEventStatus(Enumerable.Range(0, events.Length) - .Aggregate(0, (current, x) => current | (1 << x))); + .Aggregate(0, (current, x) => current | (1 << x))); for (int i = 0; i < events.Length; i++) { int flag = 1 << i; var activity = new CompositeEventActivity(trackingPropertyInfo, flag, complete, - (consumer, instance) => ((StateMachine)this).RaiseEvent(consumer, instance, @event)); + (consumer, instance) => ((StateMachine) this).RaiseEvent(consumer, instance, @event)); foreach (var state in _stateCache.Where(x => !Equals(x, Initial))) { @@ -235,32 +318,6 @@ protected void Event(Expression> propertyExpression, } } - protected void Event(Expression>> propertyExpression) - { - PropertyInfo property = propertyExpression.GetPropertyInfo(); - - string name = property.Name; - - var @event = new DataEvent(name); - - property.SetValue(this, @event); - - _eventCache[name] = new StateMachineEvent(@event); - } - - protected void State(Expression> propertyExpression) - { - PropertyInfo property = propertyExpression.GetPropertyInfo(); - - string name = property.Name; - - var state = new StateImpl(name, _eventRaisingObserver, _eventRaisedObserver); - - property.SetValue(this, state); - - _stateCache[name] = state; - } - protected void During(State state, params IEnumerable>[] activities) { EventActivity[] eventActivities = activities.SelectMany(x => x).ToArray(); @@ -338,13 +395,13 @@ void BindTransitionEvents(State state, IEnumerable activity.Where(x => IsTransitionEvent(state, x.Event))); foreach (var eventActivity in eventActivities) - During(state, new[] {eventActivity}); + During(state, new[] { eventActivity }); } bool IsTransitionEvent(State state, Event eevent) { return Equals(eevent, state.Enter) || Equals(eevent, state.BeforeEnter) - || Equals(eevent, state.AfterLeave) || Equals(eevent, state.Leave); + || Equals(eevent, state.AfterLeave) || Equals(eevent, state.Leave); } protected void Finally(Func, EventActivityBinder> activityCallback) @@ -372,4 +429,4 @@ protected EventActivityBinder When(Event @event, return new DataEventActivityBinder(this, @event, filterExpression); } } -} \ No newline at end of file +} diff --git a/src/Automatonymous/CompositeEventStatus.cs b/src/Automatonymous/CompositeEventStatus.cs index 16242c0..9330343 100644 --- a/src/Automatonymous/CompositeEventStatus.cs +++ b/src/Automatonymous/CompositeEventStatus.cs @@ -61,4 +61,4 @@ public void Set(int flag) _bits |= flag; } } -} \ No newline at end of file +} diff --git a/src/Automatonymous/Event.cs b/src/Automatonymous/Event.cs index 7519eab..68548fe 100644 --- a/src/Automatonymous/Event.cs +++ b/src/Automatonymous/Event.cs @@ -27,4 +27,4 @@ public interface Event : Event { } -} \ No newline at end of file +} diff --git a/src/Automatonymous/State.cs b/src/Automatonymous/State.cs index eba6880..9900b97 100644 --- a/src/Automatonymous/State.cs +++ b/src/Automatonymous/State.cs @@ -53,4 +53,4 @@ public interface State : void Bind(EventActivity activity); } -} \ No newline at end of file +} diff --git a/src/MassTransit/MassTransit.AutomatonymousTests/CompositeEvent_Specs.cs b/src/MassTransit/MassTransit.AutomatonymousTests/CompositeEvent_Specs.cs index d80face..37d4ab4 100644 --- a/src/MassTransit/MassTransit.AutomatonymousTests/CompositeEvent_Specs.cs +++ b/src/MassTransit/MassTransit.AutomatonymousTests/CompositeEvent_Specs.cs @@ -94,12 +94,8 @@ class TestStateMachine : public TestStateMachine() { InstanceState(x => x.CurrentState); - State(() => Waiting); - Event(() => Start); - Event(() => First); - Event(() => Second); - Event(() => Third, x => x.CompositeStatus, First, Second); + ComposeEvent(Third, x => x.CompositeStatus, First, Second); Initially( When(Start) diff --git a/src/MassTransit/MassTransit.AutomatonymousTests/Fault_Specs.cs b/src/MassTransit/MassTransit.AutomatonymousTests/Fault_Specs.cs index a7d00e8..cd8db1b 100644 --- a/src/MassTransit/MassTransit.AutomatonymousTests/Fault_Specs.cs +++ b/src/MassTransit/MassTransit.AutomatonymousTests/Fault_Specs.cs @@ -109,15 +109,6 @@ public TestStateMachine() { InstanceState(x => x.CurrentState); - State(() => Running); - State(() => WaitingToStart); - State(() => FailedToStart); - - Event(() => Started); - Event(() => Initialized); - Event(() => Created); - Event(() => StartFaulted); - Initially( When(Started) .Then(instance => { throw new NotSupportedException("This is expected, but nonetheless exceptional"); }) diff --git a/src/MassTransit/MassTransit.AutomatonymousTests/PublishRequest_Specs.cs b/src/MassTransit/MassTransit.AutomatonymousTests/PublishRequest_Specs.cs index f702dd6..0afc185 100644 --- a/src/MassTransit/MassTransit.AutomatonymousTests/PublishRequest_Specs.cs +++ b/src/MassTransit/MassTransit.AutomatonymousTests/PublishRequest_Specs.cs @@ -74,9 +74,6 @@ public TestStateMachine() { InstanceState(x => x.CurrentState); - State(() => Running); - Event(() => Started); - Initially( When(Started) .PublishRequest((instance, context) => new RequestAuthorization diff --git a/src/MassTransit/MassTransit.AutomatonymousTests/Publish_Specs.cs b/src/MassTransit/MassTransit.AutomatonymousTests/Publish_Specs.cs index cde0661..4bbab1e 100644 --- a/src/MassTransit/MassTransit.AutomatonymousTests/Publish_Specs.cs +++ b/src/MassTransit/MassTransit.AutomatonymousTests/Publish_Specs.cs @@ -75,9 +75,6 @@ public TestStateMachine() { InstanceState(x => x.CurrentState); - State(() => Running); - Event(() => Started); - Initially( When(Started) .Publish((instance, msg) => new StartupComplete diff --git a/src/MassTransit/MassTransit.AutomatonymousTests/RemoveWhen_Specs.cs b/src/MassTransit/MassTransit.AutomatonymousTests/RemoveWhen_Specs.cs index 58a23b3..0fd25f2 100644 --- a/src/MassTransit/MassTransit.AutomatonymousTests/RemoveWhen_Specs.cs +++ b/src/MassTransit/MassTransit.AutomatonymousTests/RemoveWhen_Specs.cs @@ -101,12 +101,8 @@ class TestStateMachine : AutomatonymousStateMachine { public TestStateMachine() - { - InstanceState(x => x.CurrentState); - - State(() => Running); - Event(() => Started); - Event(() => Stopped); + { + InstanceState(x => x.CurrentState); Initially( When(Started) diff --git a/src/MassTransit/MassTransit.AutomatonymousTests/Respond_Specs.cs b/src/MassTransit/MassTransit.AutomatonymousTests/Respond_Specs.cs index b4436ae..175b778 100644 --- a/src/MassTransit/MassTransit.AutomatonymousTests/Respond_Specs.cs +++ b/src/MassTransit/MassTransit.AutomatonymousTests/Respond_Specs.cs @@ -75,9 +75,6 @@ public TestStateMachine() { InstanceState(x => x.CurrentState); - State(() => Running); - Event(() => Started); - Initially( When(Started) .Respond(new StartupComplete()) diff --git a/src/MassTransit/MassTransit.AutomatonymousTests/SimpleStateMachine_Specs.cs b/src/MassTransit/MassTransit.AutomatonymousTests/SimpleStateMachine_Specs.cs index 16e4d24..9f660df 100644 --- a/src/MassTransit/MassTransit.AutomatonymousTests/SimpleStateMachine_Specs.cs +++ b/src/MassTransit/MassTransit.AutomatonymousTests/SimpleStateMachine_Specs.cs @@ -100,11 +100,6 @@ public TestStateMachine() { InstanceState(x => x.CurrentState); - State(() => Running); - Event(() => Started); - Event(() => Stopped); - Event(() => ShouldNotBind); - Initially( When(Started) .TransitionTo(Running)); @@ -134,4 +129,4 @@ class Stop : public Guid CorrelationId { get; set; } } } -} \ No newline at end of file +} diff --git a/src/MassTransit/MassTransit.AutomatonymousTests/Testing_Specs.cs b/src/MassTransit/MassTransit.AutomatonymousTests/Testing_Specs.cs index 92486f3..4b99f83 100644 --- a/src/MassTransit/MassTransit.AutomatonymousTests/Testing_Specs.cs +++ b/src/MassTransit/MassTransit.AutomatonymousTests/Testing_Specs.cs @@ -116,11 +116,6 @@ public TestStateMachine() { InstanceState(x => x.CurrentState); - State(() => Running); - Event(() => Started); - Event(() => Stopped); - Event(() => ShouldNotBind); - Initially( When(Started) .TransitionTo(Running)); diff --git a/src/MassTransit/MassTransit.AutomatonymousTests/UncorrelatedMessage_Specs.cs b/src/MassTransit/MassTransit.AutomatonymousTests/UncorrelatedMessage_Specs.cs index 3f153ac..431f702 100644 --- a/src/MassTransit/MassTransit.AutomatonymousTests/UncorrelatedMessage_Specs.cs +++ b/src/MassTransit/MassTransit.AutomatonymousTests/UncorrelatedMessage_Specs.cs @@ -110,10 +110,6 @@ public TestStateMachine() { InstanceState(x => x.CurrentState); - State(() => Running); - Event(() => Started); - Event(() => CheckStatus); - Initially( When(Started) .Then((i, d) => i.ServiceName = d.ServiceName) diff --git a/src/NHibernate.AutomatonymousTests/Vanilla_Specs.cs b/src/NHibernate.AutomatonymousTests/Vanilla_Specs.cs index 9cf0ccd..7bf324f 100644 --- a/src/NHibernate.AutomatonymousTests/Vanilla_Specs.cs +++ b/src/NHibernate.AutomatonymousTests/Vanilla_Specs.cs @@ -176,12 +176,7 @@ public SuperShopper() { InstanceState(x => x.CurrentState); - State(() => OnTheWayToTheStore); - - Event(() => ExitFrontDoor); - Event(() => GotHitByCar); - - Event(() => EndOfTheWorld, x => x.Everything, ExitFrontDoor, GotHitByCar); + ComposeEvent(EndOfTheWorld, x => x.Everything, ExitFrontDoor, GotHitByCar); Initially( When(ExitFrontDoor)