##// END OF EJS Templates
sync
cin -
r157:948c015a9011 v2
parent child
Show More
@@ -1,141 +1,153
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
33
13 .Cat(
34 _def.DefineTransition(initializing,ready,(int)Operations.Success);
14 Token.New(ExecutionState.Ready) // uninitialized -> initial
35 _def.DefineTransition(initializing,error,(int)Operations.Fail);
15 .Cat(
36
16 Token.New(ExecutionState.Starting) // initial -> starting
37 _def.DefineTransition(ready, starting, (int)Operations.Start);
17 .Cat(
38 _def.DefineTransition(ready, disposing, (int)Operations.Dispose);
18 Token.New(ExecutionState.Running) // running -> {stopping -> stopped | failed }
39
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
40
37 var _dfa = new EDFADefinition<ExecutionState>(EnumAlphabet<ExecutionState>.FullAlphabet);
41 _def.DefineTransition(starting, running, (int)Operations.Success);
38 builder.BuildDFA(_dfa); // don't optimize dfa to avoid remapping of the alphabet
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);
39
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;
56 }
68 }
57 }
69 }
58 }
70 }
59
71
60 readonly Automaton m_automaton = new Automaton();
72 readonly Automaton m_automaton = new Automaton();
61 IPromise m_pending;
73 IPromise m_pending;
62 Exception m_lastError;
74 Exception m_lastError;
63
75
64 protected RunnableComponent(bool initialized) {
76 protected RunnableComponent(bool initialized) {
65 if (initialized)
77 if (initialized)
66 m_automaton.MoveTo(ExecutionState.Ready);
78 m_automaton.MoveTo(ExecutionState.Ready);
67 else
79 else
68 m_automaton.MoveTo(ExecutionState.Uninitialized);
80 m_automaton.MoveTo(ExecutionState.Uninitialized);
69 }
81 }
70
82
71 #region IInitializable implementation
83 #region IInitializable implementation
72
84
73 public void Init() {
85 public void Init() {
74
86
75 }
87 }
76
88
77 #endregion
89 #endregion
78
90
79 #region IRunnable implementation
91 #region IRunnable implementation
80
92
81 public IPromise Start() {
93 public IPromise Start() {
82 return Safe.InvokePromise(() => {
94 return Safe.InvokePromise(() => {
83 Promise promise;
95 Promise promise;
84 lock (m_automaton) {
96 lock (m_automaton) {
85 if (m_automaton.Current == ExecutionState.Starting)
97 if (m_automaton.Current == ExecutionState.Starting)
86 return m_pending;
98 return m_pending;
87 m_automaton.MoveTo(ExecutionState.Starting);
99 m_automaton.MoveTo(ExecutionState.Starting);
88 m_pending = promise = new Promise();
100 m_pending = promise = new Promise();
89 }
101 }
90
102
91 var start = Safe.InvokePromise(OnStart);
103 var start = Safe.InvokePromise(OnStart);
92 promise.On(null, null, start.Cancel);
104 promise.On(null, null, start.Cancel);
93 start.On(promise.Resolve, promise.Reject, promise.CancelOperation);
105 start.On(promise.Resolve, promise.Reject, promise.CancelOperation);
94
106
95 return promise.Then(() => {
107 return promise.Then(() => {
96 lock(m_automaton) {
108 lock(m_automaton) {
97 m_automaton.MoveTo(ExecutionState.Running);
109 m_automaton.MoveTo(ExecutionState.Running);
98 m_pending = null;
110 m_pending = null;
99 }
111 }
100
112
101 Run();
113 Run();
102 }, err => {
114 }, err => {
103 if (BeginTransition(RUNNING_REQUIRE)) {
115 if (BeginTransition(RUNNING_REQUIRE)) {
104 m_lastError = err;
116 m_lastError = err;
105 CompleteTransition(FAILED_STATE);
117 CompleteTransition(FAILED_STATE);
106 throw new PromiseTransientException(err);
118 throw new PromiseTransientException(err);
107 }
119 }
108 throw new OperationCanceledException();
120 throw new OperationCanceledException();
109 }, reason => {
121 }, reason => {
110 throw new OperationCanceledException("The operation was cancelled", reason);
122 throw new OperationCanceledException("The operation was cancelled", reason);
111 });
123 });
112 });
124 });
113 }
125 }
114
126
115 protected virtual IPromise OnStart() {
127 protected virtual IPromise OnStart() {
116 return Promise.SUCCESS;
128 return Promise.SUCCESS;
117 }
129 }
118
130
119 protected virtual void Run() {
131 protected virtual void Run() {
120 }
132 }
121
133
122 public IPromise Stop() {
134 public IPromise Stop() {
123 throw new NotImplementedException();
135 throw new NotImplementedException();
124 }
136 }
125
137
126 public ExecutionState State {
138 public ExecutionState State {
127 get {
139 get {
128 throw new NotImplementedException();
140 throw new NotImplementedException();
129 }
141 }
130 }
142 }
131
143
132 public Exception LastError {
144 public Exception LastError {
133 get {
145 get {
134 throw new NotImplementedException();
146 throw new NotImplementedException();
135 }
147 }
136 }
148 }
137
149
138 #endregion
150 #endregion
139 }
151 }
140 }
152 }
141
153
@@ -1,32 +1,36
1 using Implab;
1 using Implab;
2 using System;
2 using System;
3
3
4 namespace Implab.Parsing {
4 namespace Implab.Parsing {
5 public class EDFADefinition<T> : DFADefinitionBase where T : struct, IConvertible {
5 public class EDFADefinition<T> : DFADefinitionBase where T : struct, IConvertible {
6 readonly EnumAlphabet<T> m_alphabet;
6 readonly EnumAlphabet<T> m_alphabet;
7
7
8 public EnumAlphabet<T> Alphabet {
8 public EnumAlphabet<T> Alphabet {
9 get { return m_alphabet; }
9 get { return m_alphabet; }
10 }
10 }
11
11
12 public EDFADefinition(EnumAlphabet<T> alphabet) {
12 public EDFADefinition(EnumAlphabet<T> alphabet) {
13 Safe.ArgumentNotNull(alphabet, "alphabet");
13 Safe.ArgumentNotNull(alphabet, "alphabet");
14 m_alphabet = alphabet;
14 m_alphabet = alphabet;
15 }
15 }
16
16
17 public override int AlphabetSize {
17 public override int AlphabetSize {
18 get { return m_alphabet.Count; }
18 get { return m_alphabet.Count; }
19 }
19 }
20
20
21 public void DefineTransition(int s1, int s2, T input) {
22 DefineTransition(s1, s2, m_alphabet.Translate(input));
23 }
24
21 public EDFADefinition<T> Optimize() {
25 public EDFADefinition<T> Optimize() {
22 var optimized = new EDFADefinition<T>(new EnumAlphabet<T>());
26 var optimized = new EDFADefinition<T>(new EnumAlphabet<T>());
23 Optimize(optimized, m_alphabet, optimized.Alphabet);
27 Optimize(optimized, m_alphabet, optimized.Alphabet);
24
28
25 return optimized;
29 return optimized;
26 }
30 }
27
31
28 public void PrintDFA() {
32 public void PrintDFA() {
29 PrintDFA(m_alphabet);
33 PrintDFA(m_alphabet);
30 }
34 }
31 }
35 }
32 }
36 }
General Comments 0
You need to be logged in to leave comments. Login now