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; |