comparison Framework/Loaders/LoaderStateMachine.cpp @ 860:238693c3bc51 am-dev

merge default -> am-dev
author Alain Mazy <alain@mazy.be>
date Mon, 24 Jun 2019 14:35:00 +0200
parents 47fc7919977d
children a7351ad54960
comparison
equal deleted inserted replaced
856:a6e17a5a39e7 860:238693c3bc51
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 LOG(ERROR) << "Error: " << message.GetException().What() << " Details: " <<
111 message.GetException().GetDetails();
112 Clear();
113 }
114
115
116 template <typename T>
117 void LoaderStateMachine::HandleSuccessMessage(const T& message)
118 {
119 assert(activeCommands_ > 0);
120 activeCommands_--;
121
122 try
123 {
124 dynamic_cast<State&>(message.GetOrigin().GetPayload()).Handle(message);
125 Step();
126 }
127 catch (Orthanc::OrthancException& e)
128 {
129 LOG(ERROR) << "Error in the state machine, stopping all processing: " <<
130 e.What() << " Details: " << e.GetDetails();
131 Clear();
132 }
133 }
134
135
136 LoaderStateMachine::LoaderStateMachine(IOracle& oracle,
137 IObservable& oracleObservable) :
138 IObserver(oracleObservable.GetBroker()),
139 oracle_(oracle),
140 active_(false),
141 simultaneousDownloads_(4),
142 activeCommands_(0)
143 {
144 oracleObservable.RegisterObserverCallback(
145 new Callable<LoaderStateMachine, OrthancRestApiCommand::SuccessMessage>
146 (*this, &LoaderStateMachine::HandleSuccessMessage));
147
148 oracleObservable.RegisterObserverCallback(
149 new Callable<LoaderStateMachine, GetOrthancImageCommand::SuccessMessage>
150 (*this, &LoaderStateMachine::HandleSuccessMessage));
151
152 oracleObservable.RegisterObserverCallback(
153 new Callable<LoaderStateMachine, GetOrthancWebViewerJpegCommand::SuccessMessage>
154 (*this, &LoaderStateMachine::HandleSuccessMessage));
155
156 oracleObservable.RegisterObserverCallback(
157 new Callable<LoaderStateMachine, OracleCommandExceptionMessage>
158 (*this, &LoaderStateMachine::HandleExceptionMessage));
159 }
160
161
162 void LoaderStateMachine::SetSimultaneousDownloads(unsigned int count)
163 {
164 if (active_)
165 {
166 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
167 }
168 else if (count == 0)
169 {
170 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
171 }
172 else
173 {
174 simultaneousDownloads_ = count;
175 }
176 }
177 }