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;