Skip to content

Commit a98d5ed

Browse files
committed
templated flowSymbol<input/output mask>(flags)
* Enforce at compile time that either input or output flags are considered. * Use horizontal flow symbols (as in console output). * Replace redundant direction(flags).
1 parent 7f33633 commit a98d5ed

File tree

4 files changed

+57
-66
lines changed

4 files changed

+57
-66
lines changed

core/include/moveit/task_constructor/container_p.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,8 @@ class ContainerBasePrivate : public StagePrivate
133133
child.pimpl()->setNextStarts(allowed ? pending_forward_ : InterfacePtr());
134134
}
135135
// report error about mismatching interface (start or end as determined by mask)
136-
void mismatchingInterface(InitStageException& errors, const StagePrivate& child, const InterfaceFlags mask) const;
136+
template <unsigned int mask>
137+
void mismatchingInterface(InitStageException& errors, const StagePrivate& child) const;
137138

138139
/// copy external_state to a child's interface and remember the link in internal_to map
139140
void copyState(Interface::iterator external, const InterfacePtr& target, bool updated);

core/include/moveit/task_constructor/stage.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,8 @@ class Connecting : public ComputeBase
382382
}
383383
};
384384

385-
const char* flowSymbol(moveit::task_constructor::InterfaceFlags f);
385+
/** Return (horizontal) flow symbol for start or end interface (specified by mask) */
386+
template <unsigned int mask>
387+
const char* flowSymbol(InterfaceFlags f);
386388
}
387389
}

core/src/container.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,11 @@ void ContainerBasePrivate::validateConnectivity() const {
104104
throw errors;
105105
}
106106

107-
void ContainerBasePrivate::mismatchingInterface(InitStageException& errors, const StagePrivate& child,
108-
const InterfaceFlags mask) const {
107+
template <unsigned int mask>
108+
void ContainerBasePrivate::mismatchingInterface(InitStageException& errors, const StagePrivate& child) const {
109109
boost::format desc("%1% interface of '%2%' (%3%) does not match mine (%4%)");
110110
errors.push_back(*me(), (desc % (mask == START_IF_MASK ? "start" : "end") % child.name() %
111-
flowSymbol(child.interfaceFlags() & mask) % flowSymbol(interfaceFlags() & mask))
111+
flowSymbol<mask>(child.interfaceFlags()) % flowSymbol<mask>(interfaceFlags()))
112112
.str());
113113
}
114114

@@ -417,8 +417,8 @@ void SerialContainerPrivate::connect(StagePrivate& stage1, StagePrivate& stage2)
417417
stage2.setPrevEnds(stage1.ends());
418418
else {
419419
boost::format desc("end interface of '%1%' (%2%) does not match start interface of '%3%' (%4%)");
420-
desc % stage1.name() % flowSymbol(flags1 & END_IF_MASK);
421-
desc % stage2.name() % flowSymbol(flags2 & START_IF_MASK);
420+
desc % stage1.name() % flowSymbol<END_IF_MASK>(flags1);
421+
desc % stage2.name() % flowSymbol<START_IF_MASK>(flags2);
422422
throw InitStageException(*me(), desc.str());
423423
}
424424
}
@@ -454,7 +454,7 @@ void SerialContainerPrivate::pruneInterface(InterfaceFlags accepted) {
454454
(last.pimpl()->requiredInterface() & END_IF_MASK) != (accepted & END_IF_MASK)) {
455455
boost::format desc(
456456
"requested end interface for container (%1%) does not agree with inferred end interface of last child (%2%)");
457-
desc % flowSymbol(accepted & END_IF_MASK) % flowSymbol(last.pimpl()->requiredInterface() & END_IF_MASK);
457+
desc % flowSymbol<END_IF_MASK>(accepted) % flowSymbol<END_IF_MASK>(last.pimpl()->requiredInterface());
458458
throw InitStageException(*me(), desc.str());
459459
}
460460

@@ -490,12 +490,12 @@ void SerialContainerPrivate::validateConnectivity() const {
490490
const auto my_flags = this->interfaceFlags();
491491
auto child_flags = start->interfaceFlags() & START_IF_MASK;
492492
if (child_flags != (my_flags & START_IF_MASK))
493-
mismatchingInterface(errors, *start, START_IF_MASK);
493+
mismatchingInterface<START_IF_MASK>(errors, *start);
494494

495495
const StagePrivate* last = children().back()->pimpl();
496496
child_flags = last->interfaceFlags() & END_IF_MASK;
497497
if (child_flags != (my_flags & END_IF_MASK))
498-
mismatchingInterface(errors, *last, END_IF_MASK);
498+
mismatchingInterface<END_IF_MASK>(errors, *last);
499499
}
500500

501501
// validate connectivity of children amongst each other
@@ -606,16 +606,16 @@ void ParallelContainerBasePrivate::pruneInterface(InterfaceFlags accepted) {
606606
boost::format desc("inferred interface of stage '%1%' (%2%/%3%) does not agree with the inferred interface of "
607607
"its siblings (%4%/%5%).");
608608
desc % child->name();
609-
desc % flowSymbol(child_interface & START_IF_MASK) % flowSymbol(child_interface & END_IF_MASK);
610-
desc % flowSymbol(interface & START_IF_MASK) % flowSymbol(interface & END_IF_MASK);
609+
desc % flowSymbol<START_IF_MASK>(child_interface) % flowSymbol<END_IF_MASK>(child_interface);
610+
desc % flowSymbol<START_IF_MASK>(interface) % flowSymbol<END_IF_MASK>(interface);
611611
exceptions.push_back(*me(), desc.str());
612612
}
613613
}
614614

615615
if ((interface & accepted) != accepted) {
616616
boost::format desc("required interface (%1%/%2%) does not match children (%3%/%4%).");
617-
desc % flowSymbol(accepted & START_IF_MASK) % flowSymbol(accepted & END_IF_MASK);
618-
desc % flowSymbol(interface & START_IF_MASK) % flowSymbol(interface & END_IF_MASK);
617+
desc % flowSymbol<START_IF_MASK>(accepted) % flowSymbol<END_IF_MASK>(accepted);
618+
desc % flowSymbol<START_IF_MASK>(interface) % flowSymbol<END_IF_MASK>(interface);
619619
exceptions.push_back(*me(), desc.str());
620620
}
621621

@@ -649,9 +649,9 @@ void ParallelContainerBasePrivate::validateConnectivity() const {
649649
for (const auto& child : children()) {
650650
InterfaceFlags current = child->pimpl()->interfaceFlags();
651651
if ((current & my_interface & START_IF_MASK) != (current & START_IF_MASK))
652-
mismatchingInterface(errors, *child->pimpl(), START_IF_MASK);
652+
mismatchingInterface<START_IF_MASK>(errors, *child->pimpl());
653653
if ((current & my_interface & END_IF_MASK) != (current & END_IF_MASK))
654-
mismatchingInterface(errors, *child->pimpl(), END_IF_MASK);
654+
mismatchingInterface<END_IF_MASK>(errors, *child->pimpl());
655655
}
656656

657657
// recursively validate children

core/src/stage.cpp

Lines changed: 38 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,30 @@
5252
namespace moveit {
5353
namespace task_constructor {
5454

55+
template <>
56+
const char* flowSymbol<START_IF_MASK>(InterfaceFlags f) {
57+
f = f & START_IF_MASK;
58+
if (f == READS_START)
59+
return "";
60+
if (f == WRITES_PREV_END)
61+
return "";
62+
if (f == UNKNOWN)
63+
return "?";
64+
return "";
65+
}
66+
67+
template <>
68+
const char* flowSymbol<END_IF_MASK>(InterfaceFlags f) {
69+
f = f & END_IF_MASK;
70+
if (f == READS_END)
71+
return "";
72+
if (f == WRITES_NEXT_START)
73+
return "";
74+
if (f == UNKNOWN)
75+
return "?";
76+
return "";
77+
}
78+
5579
void InitStageException::push_back(const Stage& stage, const std::string& msg) {
5680
errors_.emplace_back(std::make_pair(&stage, msg));
5781
}
@@ -103,9 +127,9 @@ void StagePrivate::pruneInterface(InterfaceFlags accepted) {
103127
// only one side needs to be specified but the value has to be compatible with this stage
104128
if (((accepted_start != UNKNOWN) && (accepted_start & required_start) != required_start) ||
105129
((accepted_end != UNKNOWN) && (accepted_end & required_end) != required_end)) {
106-
boost::format desc("this' interface %1%/%2% cannot match inferred interface %3%/%4%");
107-
desc % flowSymbol(required_start) % flowSymbol(required_end);
108-
desc % flowSymbol(accepted_start) % flowSymbol(accepted_end);
130+
boost::format desc("interface %1% %2% does not match inferred interface %3% %4%");
131+
desc % flowSymbol<START_IF_MASK>(required_start) % flowSymbol<END_IF_MASK>(required_end);
132+
desc % flowSymbol<START_IF_MASK>(accepted_start) % flowSymbol<END_IF_MASK>(accepted_end);
109133
throw InitStageException(*me(), desc.str());
110134
}
111135
}
@@ -115,9 +139,9 @@ void StagePrivate::validateConnectivity() const {
115139
InterfaceFlags required = requiredInterface();
116140
InterfaceFlags actual = interfaceFlags();
117141
if ((required & actual) != required) {
118-
boost::format desc("interface %1%/%2% does not satisfy required interface %3%/%4%");
119-
desc % flowSymbol(actual & START_IF_MASK) % flowSymbol(actual & END_IF_MASK);
120-
desc % flowSymbol(required & START_IF_MASK) % flowSymbol(required & END_IF_MASK);
142+
boost::format desc("interface %1% %2% does not satisfy required interface %3% %4%");
143+
desc % flowSymbol<START_IF_MASK>(actual) % flowSymbol<END_IF_MASK>(actual);
144+
desc % flowSymbol<START_IF_MASK>(required) % flowSymbol<END_IF_MASK>(required);
121145
throw InitStageException(*me(), desc.str());
122146
}
123147
}
@@ -362,43 +386,6 @@ void Stage::reportPropertyError(const Property::error& e) {
362386
throw std::runtime_error(oss.str());
363387
}
364388

365-
template <InterfaceFlag own, InterfaceFlag other>
366-
const char* direction(const StagePrivate& stage) {
367-
InterfaceFlags f = stage.interfaceFlags();
368-
369-
bool own_if = f & own;
370-
bool other_if = f & other;
371-
bool reverse = own & START_IF_MASK;
372-
if (own_if && other_if)
373-
return "<>";
374-
if (!own_if && !other_if)
375-
return "--";
376-
if (other_if ^ reverse)
377-
return "->";
378-
return "<-";
379-
}
380-
381-
const char* flowSymbol(InterfaceFlags f) {
382-
if (f == UNKNOWN)
383-
return "?"; // unknown interface
384-
385-
// f should have either INPUT or OUTPUT flags set (not both)
386-
assert(static_cast<bool>(f & START_IF_MASK) ^ static_cast<bool>(f & END_IF_MASK));
387-
388-
if (f & START_IF_MASK) {
389-
if (f == READS_START)
390-
return "";
391-
if (f == WRITES_PREV_END)
392-
return "";
393-
} else if (f & END_IF_MASK) {
394-
if (f == READS_END)
395-
return "";
396-
if (f == WRITES_NEXT_START)
397-
return "";
398-
}
399-
return "";
400-
}
401-
402389
std::ostream& operator<<(std::ostream& os, const StagePrivate& impl) {
403390
// starts
404391
for (const InterfaceConstPtr& i : { impl.prevEnds(), impl.starts() }) {
@@ -409,8 +396,9 @@ std::ostream& operator<<(std::ostream& os, const StagePrivate& impl) {
409396
os << "-";
410397
}
411398
// trajectories
412-
os << std::setw(5) << direction<READS_START, WRITES_PREV_END>(impl) << std::setw(3) << impl.solutions_.size()
413-
<< std::setw(5) << direction<READS_END, WRITES_NEXT_START>(impl);
399+
os << " " << flowSymbol<START_IF_MASK>(impl.interfaceFlags() | impl.requiredInterface()) << " ";
400+
os << std::setw(3) << impl.solutions_.size();
401+
os << " " << flowSymbol<END_IF_MASK>(impl.interfaceFlags() | impl.requiredInterface()) << " ";
414402
// ends
415403
for (const InterfaceConstPtr& i : { impl.ends(), impl.nextStarts() }) {
416404
os << std::setw(3);
@@ -436,11 +424,11 @@ void PropagatingEitherWayPrivate::initInterface(PropagatingEitherWay::Direction
436424
auto flow = [](PropagatingEitherWay::Direction dir) -> const char* {
437425
switch (dir) {
438426
case PropagatingEitherWay::AUTO:
439-
return flowSymbol(InterfaceFlags{ READS_START, WRITES_PREV_END });
427+
return flowSymbol<START_IF_MASK>(InterfaceFlags{ READS_START, WRITES_PREV_END });
440428
case PropagatingEitherWay::FORWARD:
441-
return flowSymbol(InterfaceFlags{ READS_START });
429+
return flowSymbol<START_IF_MASK>(InterfaceFlags{ READS_START });
442430
case PropagatingEitherWay::BACKWARD:
443-
return flowSymbol(InterfaceFlags{ WRITES_PREV_END });
431+
return flowSymbol<START_IF_MASK>(InterfaceFlags{ WRITES_PREV_END });
444432
}
445433
};
446434

@@ -459,14 +447,14 @@ void PropagatingEitherWayPrivate::initInterface(PropagatingEitherWay::Direction
459447

460448
void PropagatingEitherWayPrivate::pruneInterface(InterfaceFlags accepted) {
461449
if (accepted == UNKNOWN)
462-
throw InitStageException(*me(), std::string("cannot prune to ") + flowSymbol(UNKNOWN));
450+
throw InitStageException(*me(), "cannot prune to unknown interface");
463451
if ((accepted & START_IF_MASK) == READS_START || (accepted & END_IF_MASK) == WRITES_NEXT_START)
464452
initInterface(PropagatingEitherWay::FORWARD);
465453
else if ((accepted & START_IF_MASK) == WRITES_PREV_END || (accepted & END_IF_MASK) == READS_END)
466454
initInterface(PropagatingEitherWay::BACKWARD);
467455
else {
468456
boost::format desc("propagator cannot act with interfaces start(%1%), end(%2%)");
469-
desc % flowSymbol(accepted & START_IF_MASK) % flowSymbol(accepted & END_IF_MASK);
457+
desc % flowSymbol<START_IF_MASK>(accepted) % flowSymbol<END_IF_MASK>(accepted);
470458
throw InitStageException(*me(), desc.str());
471459
}
472460
}

0 commit comments

Comments
 (0)