comparison Framework/Loaders/LoaderStateMachine.cpp @ 815:df442f1ba0c6

reorganization
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 28 May 2019 21:59:20 +0200
parents
children 47fc7919977d
comparison
equal deleted inserted replaced
814:aead999345e0 815:df442f1ba0c6
1 /**
2 * Stone of Orthanc
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, Belgium
5 * Copyright (C) 2017-2019 Osimis S.A., Belgium
6 *
7 * This program is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU Affero General Public License
9 * as published by the Free Software Foundation, either version 3 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 **/
20
21
22 #include "LoaderStateMachine.h"
23
24 #include <Core/OrthancException.h>
25
26 namespace OrthancStone
27 {
28 void LoaderStateMachine::State::Handle(const OrthancRestApiCommand::SuccessMessage& message)
29 {
30 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
31 }
32
33
34 void LoaderStateMachine::State::Handle(const GetOrthancImageCommand::SuccessMessage& message)
35 {
36 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
37 }
38
39
40 void LoaderStateMachine::State::Handle(const GetOrthancWebViewerJpegCommand::SuccessMessage& message)
41 {
42 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
43 }
44
45
46 void LoaderStateMachine::Schedule(OracleCommandWithPayload* command)
47 {
48 std::auto_ptr<OracleCommandWithPayload> protection(command);
49
50 if (command == NULL)
51 {
52 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
53 }
54
55 if (!command->HasPayload())
56 {
57 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange,
58 "The payload must contain the next state");
59 }
60
61 pendingCommands_.push_back(protection.release());
62 Step();
63 }
64
65
66 void LoaderStateMachine::Start()
67 {
68 if (active_)
69 {
70 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
71 }
72
73 active_ = true;
74
75 for (size_t i = 0; i < simultaneousDownloads_; i++)
76 {
77 Step();
78 }
79 }
80
81
82 void LoaderStateMachine::Step()
83 {
84 if (!pendingCommands_.empty() &&
85 activeCommands_ < simultaneousDownloads_)
86 {
87 oracle_.Schedule(*this, pendingCommands_.front());
88 pendingCommands_.pop_front();
89
90 activeCommands_++;
91 }
92 }
93
94
95 void LoaderStateMachine::Clear()
96 {
97 for (PendingCommands::iterator it = pendingCommands_.begin();
98 it != pendingCommands_.end(); ++it)
99 {
100 delete *it;
101 }
102
103 pendingCommands_.clear();
104 }
105
106
107 void LoaderStateMachine::HandleExceptionMessage(const OracleCommandExceptionMessage& message)
108 {
109 LOG(ERROR) << "Error in the state machine, stopping all processing";
110 Clear();
111 }
112
113
114 template <typename T>
115 void LoaderStateMachine::HandleSuccessMessage(const T& message)
116 {
117 assert(activeCommands_ > 0);
118 activeCommands_--;
119
120 try
121 {
122 dynamic_cast<State&>(message.GetOrigin().GetPayload()).Handle(message);
123 Step();
124 }
125 catch (Orthanc::OrthancException& e)
126 {
127 LOG(ERROR) << "Error in the state machine, stopping all processing: " << e.What();
128 Clear();
129 }
130 }
131
132
133 LoaderStateMachine::LoaderStateMachine(IOracle& oracle,
134 IObservable& oracleObservable) :
135 IObserver(oracleObservable.GetBroker()),
136 oracle_(oracle),
137 active_(false),
138 simultaneousDownloads_(4),
139 activeCommands_(0)
140 {
141 oracleObservable.RegisterObserverCallback(
142 new Callable<LoaderStateMachine, OrthancRestApiCommand::SuccessMessage>
143 (*this, &LoaderStateMachine::HandleSuccessMessage));
144
145 oracleObservable.RegisterObserverCallback(
146 new Callable<LoaderStateMachine, GetOrthancImageCommand::SuccessMessage>
147 (*this, &LoaderStateMachine::HandleSuccessMessage));
148
149 oracleObservable.RegisterObserverCallback(
150 new Callable<LoaderStateMachine, GetOrthancWebViewerJpegCommand::SuccessMessage>
151 (*this, &LoaderStateMachine::HandleSuccessMessage));
152
153 oracleObservable.RegisterObserverCallback(
154 new Callable<LoaderStateMachine, OracleCommandExceptionMessage>
155 (*this, &LoaderStateMachine::HandleExceptionMessage));
156 }
157
158
159 void LoaderStateMachine::SetSimultaneousDownloads(unsigned int count)
160 {
161 if (active_)
162 {
163 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
164 }
165 else if (count == 0)
166 {
167 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
168 }
169 else
170 {
171 simultaneousDownloads_ = count;
172 }
173 }
174 }