Skip to content

Commit aef9916

Browse files
committed
Propagate either STATUS or PRIORITY updates into a container
1 parent a48b932 commit aef9916

File tree

1 file changed

+23
-17
lines changed

1 file changed

+23
-17
lines changed

core/src/container.cpp

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,17 @@ void ContainerBasePrivate::setStatus(const Stage* creator, const InterfaceState*
165165
setStatus<dir>(successor->creator(), target, state<dir>(*successor), status);
166166
}
167167

168+
// recursively update state priorities along solution path
169+
template <Interface::Direction dir>
170+
inline void updateStatePrios(const InterfaceState& s, const InterfaceState::Priority& prio) {
171+
InterfaceState::Priority priority(prio, s.priority().status());
172+
if (s.priority() == priority)
173+
return;
174+
const_cast<InterfaceState&>(s).updatePriority(priority);
175+
for (const SolutionBase* successor : trajectories<dir>(s))
176+
updateStatePrios<dir>(*state<dir>(*successor), prio);
177+
}
178+
168179
void ContainerBasePrivate::onNewFailure(const Stage& child, const InterfaceState* from, const InterfaceState* to) {
169180
ROS_DEBUG_STREAM_NAMED("Pruning", "'" << child.name() << "' generated a failure");
170181
switch (child.pimpl()->interfaceFlags()) {
@@ -191,14 +202,20 @@ void ContainerBasePrivate::onNewFailure(const Stage& child, const InterfaceState
191202
template <Interface::Direction dir>
192203
void ContainerBasePrivate::copyState(Interface::iterator external, const InterfacePtr& target,
193204
Interface::UpdateFlags updated) {
194-
if (updated) { // propagate external state update to internal copies
195-
auto internals{ externalToInternalMap().equal_range(&*external) };
196-
for (auto& i = internals.first; i != internals.second; ++i) {
197-
setStatus<dir>(nullptr, nullptr, i->second, external->priority().status());
198-
}
205+
if (updated) {
206+
auto prio = external->priority();
207+
auto internals = externalToInternalMap().equal_range(&*external);
208+
209+
if (updated.testFlag(Interface::Update::STATUS)) { // propagate external status updates to internal copies
210+
for (auto& i = internals.first; i != internals.second; ++i)
211+
setStatus<dir>(nullptr, nullptr, i->second, prio.status());
212+
} else if (updated.testFlag(Interface::Update::PRIORITY)) {
213+
for (auto& i = internals.first; i != internals.second; ++i)
214+
updateStatePrios<opposite<dir>()>(*i->second, prio);
215+
} else
216+
assert(false); // Expecting either STATUS or PRIORITY updates, not both!
199217
return;
200218
}
201-
202219
// create a clone of external state within target interface (child's starts() or ends())
203220
auto internal = states_.insert(states_.end(), InterfaceState(*external));
204221
target->add(*internal);
@@ -426,17 +443,6 @@ struct SolutionCollector
426443
SolutionSequence::container_type trace;
427444
};
428445

429-
// recursively update state priorities along solution path
430-
template <Interface::Direction dir>
431-
inline void updateStatePrios(const InterfaceState& s, const InterfaceState::Priority& prio) {
432-
InterfaceState::Priority priority(prio, s.priority().status());
433-
if (s.priority() == priority)
434-
return;
435-
const_cast<InterfaceState&>(s).updatePriority(priority);
436-
for (const SolutionBase* successor : trajectories<dir>(s))
437-
updateStatePrios<dir>(*state<dir>(*successor), prio);
438-
}
439-
440446
void SerialContainer::onNewSolution(const SolutionBase& current) {
441447
ROS_DEBUG_STREAM_NAMED("SerialContainer", "'" << this->name() << "' received solution of child stage '"
442448
<< current.creator()->name() << "'");

0 commit comments

Comments
 (0)