@@ -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+
168179void 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
191202template <Interface::Direction dir>
192203void 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-
440446void 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