Mercurial > pub > ImplabNet
comparison Implab/Components/RunnableComponent.cs @ 158:130781364799 v2
refactoring, code cleanup
| author | cin |
|---|---|
| date | Thu, 18 Feb 2016 14:34:02 +0300 |
| parents | 948c015a9011 |
| children | c32688129f14 |
comparison
equal
deleted
inserted
replaced
| 157:948c015a9011 | 158:130781364799 |
|---|---|
| 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 | 6 |
| 7 | 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; | |
| 20 | |
| 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 }); | |
| 31 | |
| 32 _def.DefineTransition(created,initializing,(int)Operations.Initialize); | |
| 33 | |
| 34 _def.DefineTransition(initializing,ready,(int)Operations.Success); | |
| 35 _def.DefineTransition(initializing,error,(int)Operations.Fail); | |
| 36 | |
| 37 _def.DefineTransition(ready, starting, (int)Operations.Start); | |
| 38 _def.DefineTransition(ready, disposing, (int)Operations.Dispose); | |
| 39 | 8 |
| 40 | 9 |
| 41 _def.DefineTransition(starting, running, (int)Operations.Success); | 10 |
| 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; | |
| 53 } | |
| 54 | |
| 55 int m_state; | |
| 56 | |
| 57 public Automaton() { | |
| 58 m_state = DFADefinitionBase.INITIAL_STATE; | |
| 59 } | |
| 60 | |
| 61 void Move(Operations op) { | |
| 62 | |
| 63 } | |
| 64 | |
| 65 public ExecutionState Current { | |
| 66 get { | |
| 67 return (ExecutionState)m_context.info; | |
| 68 } | |
| 69 } | |
| 70 } | |
| 71 | |
| 72 readonly Automaton m_automaton = new Automaton(); | |
| 73 IPromise m_pending; | 11 IPromise m_pending; |
| 74 Exception m_lastError; | 12 Exception m_lastError; |
| 75 | 13 |
| 76 protected RunnableComponent(bool initialized) { | 14 protected RunnableComponent(bool initialized) { |
| 77 if (initialized) | 15 |
| 78 m_automaton.MoveTo(ExecutionState.Ready); | |
| 79 else | |
| 80 m_automaton.MoveTo(ExecutionState.Uninitialized); | |
| 81 } | 16 } |
| 82 | 17 |
| 83 #region IInitializable implementation | 18 #region IInitializable implementation |
| 84 | 19 |
| 85 public void Init() { | 20 public void Init() { |
| 89 #endregion | 24 #endregion |
| 90 | 25 |
| 91 #region IRunnable implementation | 26 #region IRunnable implementation |
| 92 | 27 |
| 93 public IPromise Start() { | 28 public IPromise Start() { |
| 94 return Safe.InvokePromise(() => { | 29 throw new NotImplementedException(); |
| 95 Promise promise; | |
| 96 lock (m_automaton) { | |
| 97 if (m_automaton.Current == ExecutionState.Starting) | |
| 98 return m_pending; | |
| 99 m_automaton.MoveTo(ExecutionState.Starting); | |
| 100 m_pending = promise = new Promise(); | |
| 101 } | |
| 102 | |
| 103 var start = Safe.InvokePromise(OnStart); | |
| 104 promise.On(null, null, start.Cancel); | |
| 105 start.On(promise.Resolve, promise.Reject, promise.CancelOperation); | |
| 106 | |
| 107 return promise.Then(() => { | |
| 108 lock(m_automaton) { | |
| 109 m_automaton.MoveTo(ExecutionState.Running); | |
| 110 m_pending = null; | |
| 111 } | |
| 112 | |
| 113 Run(); | |
| 114 }, err => { | |
| 115 if (BeginTransition(RUNNING_REQUIRE)) { | |
| 116 m_lastError = err; | |
| 117 CompleteTransition(FAILED_STATE); | |
| 118 throw new PromiseTransientException(err); | |
| 119 } | |
| 120 throw new OperationCanceledException(); | |
| 121 }, reason => { | |
| 122 throw new OperationCanceledException("The operation was cancelled", reason); | |
| 123 }); | |
| 124 }); | |
| 125 } | 30 } |
| 126 | 31 |
| 127 protected virtual IPromise OnStart() { | 32 protected virtual IPromise OnStart() { |
| 128 return Promise.SUCCESS; | 33 return Promise.SUCCESS; |
| 129 } | 34 } |
