Mercurial > pub > ImplabNet
comparison Implab/Components/RunnableComponent.cs @ 157:948c015a9011 v2
sync
| author | cin |
|---|---|
| date | Thu, 18 Feb 2016 11:03:47 +0300 |
| parents | 97fbbf816844 |
| children | 130781364799 |
comparison
equal
deleted
inserted
replaced
| 156:97fbbf816844 | 157:948c015a9011 |
|---|---|
| 1 using System; | 1 using System; |
| 2 using Implab.Parsing; | 2 using Implab.Parsing; |
| 3 | 3 |
| 4 namespace Implab.Components { | 4 namespace Implab.Components { |
| 5 public class RunnableComponent : Disposable, IRunnable, IInitializable { | 5 public class RunnableComponent : Disposable, IRunnable, IInitializable { |
| 6 class Automaton : DFAutomaton<ExecutionState> { | 6 |
| 7 static readonly EDFADefinition<ExecutionState> _dfa; | 7 |
| 8 class Automaton { | |
| 9 enum Operations { | |
| 10 Initialize, | |
| 11 Start, | |
| 12 Stop, | |
| 13 Fail, | |
| 14 Success, | |
| 15 Dispose | |
| 16 } | |
| 17 | |
| 18 static readonly EDFADefinition<ExecutionState> _def = new EDFADefinition<ExecutionState>(EnumAlphabet<ExecutionState>.FullAlphabet); | |
| 19 static readonly DFAStateDescriptior[] _states; | |
| 8 | 20 |
| 9 static Automaton() { | 21 static Automaton() { |
| 22 var created = _def.AddState(); // initial state | |
| 23 var initializing = _def.AddState(); | |
| 24 var ready = _def.AddState(); | |
| 25 var starting = _def.AddState(); | |
| 26 var running = _def.AddState(); | |
| 27 var stopping = _def.AddState(); | |
| 28 var error = _def.AddState(); | |
| 29 var disposing = _def.AddState(); | |
| 30 var disposed = _def.AddState(new int[] { 0 }); | |
| 10 | 31 |
| 11 var token = Token | 32 _def.DefineTransition(created,initializing,(int)Operations.Initialize); |
| 12 .New(ExecutionState.Uninitialized).Optional() // we can skip uninitialized state | |
| 13 .Cat( | |
| 14 Token.New(ExecutionState.Ready) // uninitialized -> initial | |
| 15 .Cat( | |
| 16 Token.New(ExecutionState.Starting) // initial -> starting | |
| 17 .Cat( | |
| 18 Token.New(ExecutionState.Running) // running -> {stopping -> stopped | failed } | |
| 19 .Cat( | |
| 20 Token.New(ExecutionState.Stopping) // running -> stopping | |
| 21 .Cat( | |
| 22 Token.New(ExecutionState.Stopped) // stopping -> stopped | |
| 23 .Or(Token.New(ExecutionState.Failed)) // stopping -> failed | |
| 24 ) | |
| 25 .Or(Token.New(ExecutionState.Failed)) // running -> failed | |
| 26 ) | |
| 27 .Or(Token.New(ExecutionState.Failed)) // starting -> failed | |
| 28 ).EClosure() | |
| 29 ) | |
| 30 .Or(Token.New(ExecutionState.Failed)) // uninitialized->failed | |
| 31 .Cat(Token.New(ExecutionState.Disposed).Tag(0)) // ... -> disposed | |
| 32 ); | |
| 33 | |
| 34 var builder = new DFABuilder(); | |
| 35 token.Accept(builder); | |
| 36 | 33 |
| 37 var _dfa = new EDFADefinition<ExecutionState>(EnumAlphabet<ExecutionState>.FullAlphabet); | 34 _def.DefineTransition(initializing,ready,(int)Operations.Success); |
| 38 builder.BuildDFA(_dfa); // don't optimize dfa to avoid remapping of the alphabet | 35 _def.DefineTransition(initializing,error,(int)Operations.Fail); |
| 39 | 36 |
| 37 _def.DefineTransition(ready, starting, (int)Operations.Start); | |
| 38 _def.DefineTransition(ready, disposing, (int)Operations.Dispose); | |
| 39 | |
| 40 | |
| 41 _def.DefineTransition(starting, running, (int)Operations.Success); | |
| 42 _def.DefineTransition(starting, error, (int)Operations.Fail); | |
| 43 | |
| 44 _def.DefineTransition(running, stopping, (int)Operations.Stop); | |
| 45 _def.DefineTransition(running, error, (int)Operations.Fail); | |
| 46 | |
| 47 _def.DefineTransition(stopping, ready, (int)Operations.Success); | |
| 48 _def.DefineTransition(stopping, error, (int)Operations.Fail); | |
| 49 | |
| 50 _def.DefineTransition(disposing, disposed, (int)Operations.Success); | |
| 51 | |
| 52 _states = _def.States; | |
| 40 } | 53 } |
| 41 | 54 |
| 42 public Automaton() : base(_dfa.States, INITIAL_STATE, ExecutionState.Reserved) { | 55 int m_state; |
| 56 | |
| 57 public Automaton() { | |
| 58 m_state = DFADefinitionBase.INITIAL_STATE; | |
| 43 } | 59 } |
| 44 | 60 |
| 45 public void MoveTo(ExecutionState state) { | 61 void Move(Operations op) { |
| 46 | 62 |
| 47 if (!CanMove((int)state)) | |
| 48 throw new InvalidOperationException(String.Format("Illegal state transition from {0} to {1}", Current, state)); | |
| 49 Move((int)state); | |
| 50 m_context.info = state; | |
| 51 } | 63 } |
| 52 | 64 |
| 53 public ExecutionState Current { | 65 public ExecutionState Current { |
| 54 get { | 66 get { |
| 55 return (ExecutionState)m_context.info; | 67 return (ExecutionState)m_context.info; |
