7 #include "activities/SActivitySequencer.hpp" 9 #include <fwActivities/IActivityValidator.hpp> 10 #include <fwActivities/registry/Activities.hpp> 12 #include <fwCom/Signal.hxx> 13 #include <fwCom/Signals.hpp> 14 #include <fwCom/Slot.hpp> 15 #include <fwCom/Slots.hpp> 16 #include <fwCom/Slots.hxx> 18 #include <fwData/Composite.hpp> 20 #include <fwGui/dialog/MessageDialog.hpp> 22 #include <fwMedData/ActivitySeries.hpp> 23 #include <fwMedData/SeriesDB.hpp> 25 #include <fwMedDataTools/helper/SeriesDB.hpp> 27 #include <fwRuntime/operations.hpp> 29 #include <fwServices/macros.hpp> 31 #include <fwTools/dateAndTime.hpp> 32 #include <fwTools/UUID.hpp> 34 #include <boost/foreach.hpp> 45 const ::fwCom::Slots::SlotKeyType s_NEXT_SLOT =
"next";
46 const ::fwCom::Slots::SlotKeyType s_PREVIOUS_SLOT =
"previous";
47 const ::fwCom::Slots::SlotKeyType s_SEND_INFO_SLOT =
"sendInfo";
49 const ::fwCom::Signals::SignalKeyType s_ACTIVITY_CREATED_SIG =
"activityCreated";
50 const ::fwCom::Signals::SignalKeyType s_ENABLED_PREVIOUS_SIG =
"enabledPrevious";
51 const ::fwCom::Signals::SignalKeyType s_ENABLED_NEXT_SIG =
"enabledNext";
53 const ::fwServices::IService::KeyType s_SERIESDB_INOUT =
"seriesDB";
54 const ::fwServices::IService::KeyType s_OVERRIDES_INOUT =
"requirementOverrides";
61 newSlot(s_NEXT_SLOT, &SActivitySequencer::next,
this);
62 newSlot(s_PREVIOUS_SLOT, &SActivitySequencer::previous,
this);
63 newSlot(s_SEND_INFO_SLOT, &SActivitySequencer::sendInfo,
this);
65 m_sigActivityCreated = newSignal< ActivityCreatedSignalType >(s_ACTIVITY_CREATED_SIG);
66 m_sigEnabledPrevious = newSignal< EnabledPreviousSignalType >(s_ENABLED_PREVIOUS_SIG);
67 m_sigEnabledNext = newSignal< EnabledNextSignalType >(s_ENABLED_NEXT_SIG);
80 const ::fwServices::IService::ConfigType config = this->
getConfigTree();
81 BOOST_FOREACH( const ::fwServices::IService::ConfigType::value_type &v, config.equal_range(
"activity") )
83 m_activityIds.push_back(v.second.get<std::string>(
""));
103 ::fwMedData::SeriesDB::sptr seriesDB = this->getInOut< ::fwMedData::SeriesDB >(s_SERIESDB_INOUT);
104 SLM_ASSERT(
"Missing '" + s_SERIESDB_INOUT +
"' seriesDB", seriesDB);
106 m_currentActivity = -1;
108 for (
const auto& series: seriesDB->getContainer())
110 ::fwMedData::ActivitySeries::sptr activity = ::fwMedData::ActivitySeries::dynamicCast(series);
115 SLM_ERROR(
"The series DB must only contain 'ActivitySeries'. The series of type '" +
116 series->getClassname() +
"' will be removed");
119 helper.remove(series);
122 else if (std::find(m_activityIds.begin(), m_activityIds.end(),
123 activity->getActivityConfigId()) == m_activityIds.end())
126 SLM_ERROR(
"The activity '" +activity->getActivityConfigId() +
"' is unknown, it will be removed");
129 helper.remove(activity);
135 this->storeActivityData();
139 if (m_currentActivity >= 0)
142 const size_t index =
static_cast<size_t>(m_currentActivity);
143 ::fwMedData::ActivitySeries::sptr lastActivity = this->getActivity(index);
145 m_sigActivityCreated->asyncEmit(lastActivity);
151 void SActivitySequencer::next()
153 if (m_currentActivity >= 0)
155 this->storeActivityData();
158 const size_t newIdx =
static_cast<size_t>(m_currentActivity + 1);
159 if (newIdx >= m_activityIds.size())
161 OSLM_ERROR(
"no activity to launch, the current activity '"+ m_activityIds.back() +
"' is the last one.");
165 ::fwMedData::ActivitySeries::sptr activity = this->getActivity(newIdx);
167 if(this->checkValidity(activity,
true))
169 m_sigActivityCreated->asyncEmit(activity);
177 void SActivitySequencer::previous()
179 if (m_currentActivity <= 0)
181 OSLM_ERROR(
"no activity to launch, the current activity '"+ m_activityIds[0] +
"' is the first one.");
184 this->storeActivityData();
185 const size_t newIdx =
static_cast<size_t>(m_currentActivity - 1);
187 ::fwMedData::ActivitySeries::sptr activity = this->getActivity(newIdx);
189 if(this->checkValidity(activity,
true))
191 m_sigActivityCreated->asyncEmit(activity);
199 void SActivitySequencer::sendInfo()
const 201 const bool previousEnabled = (m_currentActivity > 0);
202 m_sigEnabledPrevious->asyncEmit(previousEnabled);
204 const bool nextEnabled = (m_currentActivity < static_cast<int>(m_activityIds.size()) -1);
205 m_sigEnabledNext->asyncEmit(nextEnabled);
210 void SActivitySequencer::storeActivityData()
212 ::fwMedData::SeriesDB::sptr seriesDB = this->getInOut< ::fwMedData::SeriesDB >(s_SERIESDB_INOUT);
213 SLM_ASSERT(
"Missing '" + s_SERIESDB_INOUT +
"' seriesDB", seriesDB);
216 const size_t currentIdx =
static_cast<size_t>(m_currentActivity);
217 SLM_ASSERT(
"SeriesDB does not contain enough series.", seriesDB->size() > currentIdx);
218 ::fwMedData::Series::sptr series = seriesDB->getContainer()[currentIdx];
219 ::fwMedData::ActivitySeries::sptr activity = ::fwMedData::ActivitySeries::dynamicCast(series);
220 SLM_ASSERT(
"seriesDB contains an unknown series : " + series->getClassname(), activity);
221 ::fwData::Composite::sptr composite = activity->getData();
222 ::fwData::Composite::csptr overrides = this->getInput< ::fwData::Composite>(s_OVERRIDES_INOUT);
227 auto overridesContainer = overrides->getContainer();
228 for (
const auto& elt : composite->getContainer())
230 if(overridesContainer.count(elt.first) == 0)
232 m_requirements[elt.first] = elt.second;
238 for (
const auto& elt : composite->getContainer())
240 m_requirements[elt.first] = elt.second;
247 ::fwMedData::ActivitySeries::sptr SActivitySequencer::getActivity(
size_t index)
249 ::fwMedData::SeriesDB::sptr seriesDB = this->getInOut< ::fwMedData::SeriesDB >(s_SERIESDB_INOUT);
250 SLM_ASSERT(
"Missing '" + s_SERIESDB_INOUT +
"' seriesDB", seriesDB);
252 ::fwMedData::ActivitySeries::sptr activity;
253 ::fwData::Composite::csptr overrides = this->getInput< ::fwData::Composite>(s_OVERRIDES_INOUT);
254 if (seriesDB->size() > index)
256 ::fwMedData::Series::sptr series = seriesDB->getContainer()[index];
257 activity = ::fwMedData::ActivitySeries::dynamicCast(series);
258 SLM_ASSERT(
"seriesDB contains an unknown series : " + series->getClassname(), activity);
259 ::fwData::Composite::sptr composite = activity->getData();
264 auto overridesContainer = overrides->getContainer();
265 for (
const auto& elt : composite->getContainer())
267 composite->getContainer()[elt.first] = overridesContainer.count(elt.first) == 0 ?
268 m_requirements[elt.first] : overridesContainer[elt.first];
273 for (
const auto& elt : composite->getContainer())
275 composite->getContainer()[elt.first] = m_requirements[elt.first];
281 const std::string activityId = m_activityIds[index];
282 const ::fwActivities::registry::ActivityInfo&
info =
285 activity = ::fwMedData::ActivitySeries::New();
287 activity->setModality(
"OT");
290 const ::boost::posix_time::ptime now = ::boost::posix_time::second_clock::local_time();
294 activity->setActivityConfigId(info.id);
295 activity->setDescription(info.description);
297 ::fwData::Composite::sptr composite = activity->getData();
299 for (
const auto& req : info.requirements)
303 auto overridesContainer = overrides->getContainer();
304 if(overridesContainer.count(req.name) != 0)
306 composite->getContainer()[req.name] = overridesContainer[req.name];
309 else if (m_requirements.find(req.name) != m_requirements.end())
311 composite->getContainer()[req.name] = m_requirements[req.name];
313 else if (req.create ==
true || (req.minOccurs == 0 && req.maxOccurs == 0))
316 ::fwData::Object::sptr newObj = ::fwData::factory::New(req.type);
317 composite->getContainer()[req.name] = newObj;
318 m_requirements[req.name] = newObj;
320 else if (req.minOccurs == 0)
323 ::fwData::Composite::sptr optionalDataComposite = ::fwData::Composite::New();
324 composite->getContainer()[req.name] = optionalDataComposite;
325 m_requirements[req.name] = optionalDataComposite;
330 helper.
add(activity);
343 bool SActivitySequencer::checkValidity(
const fwMedData::ActivitySeries::csptr& activity,
bool showDialog)
const 346 std::string errorMsg;
348 SLM_ASSERT(
"activity is not defined", activity);
350 const ::fwActivities::registry::ActivityInfo&
info =
354 std::shared_ptr< ::fwRuntime::Bundle > bundle = ::fwRuntime::findBundle(info.bundleId, info.bundleVersion);
355 if (!bundle->isStarted())
360 for (std::string validatorImpl : info.validatorsImpl)
362 ::fwActivities::IValidator::sptr validator = ::fwActivities::validator::factory::New(validatorImpl);
364 ::fwActivities::IActivityValidator::sptr activityValidator =
365 ::fwActivities::IActivityValidator::dynamicCast(validator);
367 SLM_ERROR_IF(
"Validator '" + validatorImpl +
"' instantiation failed", !activityValidator);
369 if (activityValidator)
373 if(!validation.first)
376 errorMsg +=
"\n" + validation.second;
381 if (!ok && showDialog)
384 "not be launched: \n" + errorMsg);
virtual ACTIVITIES_API ~SActivitySequencer() noexcept
Destructor. Do nothing.
This class is a helper to define the connections of a service and its data.
std::pair< bool, std::string > ValidationType
Defines validation result of an activity. First element tells if the activity is validated or not by ...
Class allowing to block a Connection.
static FWGUI_API IMessageDialog::Buttons showMessageDialog(const std::string &title, const std::string &message,::fwGui::dialog::IMessageDialog::Icons icon=INFO)
static FWACTIVITIES_API Activities::sptr getDefault()
Return the default global instance of Activities.
ACTIVITIES_API SActivitySequencer() noexcept
Constructor. Do nothing.
virtual void configuring() override
Parse XML configuration.
virtual void starting() override
Do nothing.
virtual void updating() override
Analyse the series contained in the current seriesDB.
#define SLM_ERROR(message)
static FWMEDDATA_APIconst::fwCom::Signals::SignalKeyType s_ADDED_SERIES_SIG
Type of signal when series are added.
#define OSLM_ERROR(message)
virtual ACTIVITIES_API KeyConnectionsMap getAutoConnections() const override
Connect the service to the SeriesDB signals.
This interface defines control service API. Does nothing particularly, can be considered as a default...
#define SLM_ERROR_IF(message, cond)
#define SLM_ASSERT(message, cond)
work like 'assert' from 'cassert', with in addition a message logged by spylog (with FATAL loglevel) ...
The namespace activities contains helpers and services allowing to launch activities.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_MODIFIED_SIG
Key in m_signals map of signal m_sigModified.
virtual void stopping() override
Do nothing.
static FWSERVICES_APIconst::fwCom::Slots::SlotKeyType s_UPDATE_SLOT
Slot to call start method.
virtual FWSERVICES_API void info(std::ostream &_sstream)
Write information in a stream.
This service allows to launch activities sequentially.
FWSERVICES_API ConfigType getConfigTree() const
Return the configuration, in an boost property tree.