SerialContainer: Resolve interfaces of all stages

This commit is contained in:
Robert Haschke 2020-04-10 20:25:54 +02:00
parent 499fcfb04b
commit c4d0ab0636

View File

@ -433,35 +433,50 @@ void SerialContainerPrivate::resolveInterface(InterfaceFlags expected) {
Stage& first = *children().front(); Stage& first = *children().front();
Stage& last = *children().back(); Stage& last = *children().back();
// FIRST child InitStageException exceptions;
first.pimpl()->resolveInterface(expected & START_IF_MASK);
// connect first child's (start) push interface try { // FIRST child
setChildsPushBackwardInterface(first.pimpl()); first.pimpl()->resolveInterface(expected & START_IF_MASK);
// validate that first child's and this container's start interfaces match // connect first child's (start) push interface
validateInterface<START_IF_MASK>(*first.pimpl(), expected); setChildsPushBackwardInterface(first.pimpl());
// connect first child's (start) pull interface // validate that first child's and this container's start interfaces match
if (const InterfacePtr& target = first.pimpl()->starts()) validateInterface<START_IF_MASK>(*first.pimpl(), expected);
starts_.reset(new Interface( // connect first child's (start) pull interface
[this, target](Interface::iterator it, bool updated) { this->copyState(it, target, updated); })); if (const InterfacePtr& target = first.pimpl()->starts())
starts_.reset(new Interface(
[this, target](Interface::iterator it, bool updated) { this->copyState(it, target, updated); }));
} catch (InitStageException& e) {
exceptions.append(e);
}
// process all children and connect them // process all children and connect them
for (auto it = ++children().begin(), previous_it = children().begin(); it != children().end(); ++it, ++previous_it) { for (auto it = ++children().begin(), previous_it = children().begin(); it != children().end(); ++it, ++previous_it) {
StagePrivate* child_impl = (**it).pimpl(); try {
StagePrivate* previous_impl = (**previous_it).pimpl(); StagePrivate* child_impl = (**it).pimpl();
child_impl->resolveInterface(invert(previous_impl->requiredInterface()) & START_IF_MASK); StagePrivate* previous_impl = (**previous_it).pimpl();
connect(*previous_impl, *child_impl); child_impl->resolveInterface(invert(previous_impl->requiredInterface()) & START_IF_MASK);
connect(*previous_impl, *child_impl);
} catch (InitStageException& e) {
exceptions.append(e);
}
} }
// connect last child's (end) push interface try { // connect last child's (end) push interface
setChildsPushForwardInterface(last.pimpl()); setChildsPushForwardInterface(last.pimpl());
// validate that last child's and this container's end interfaces match // validate that last child's and this container's end interfaces match
validateInterface<END_IF_MASK>(*last.pimpl(), expected); validateInterface<END_IF_MASK>(*last.pimpl(), expected);
// connect last child's (end) pull interface // connect last child's (end) pull interface
if (const InterfacePtr& target = last.pimpl()->ends()) if (const InterfacePtr& target = last.pimpl()->ends())
ends_.reset(new Interface( ends_.reset(new Interface(
[this, target](Interface::iterator it, bool updated) { this->copyState(it, target, updated); })); [this, target](Interface::iterator it, bool updated) { this->copyState(it, target, updated); }));
} catch (InitStageException& e) {
exceptions.append(e);
}
required_interface_ = first.pimpl()->interfaceFlags() & START_IF_MASK | last.pimpl()->interfaceFlags() & END_IF_MASK; required_interface_ = first.pimpl()->interfaceFlags() & START_IF_MASK | last.pimpl()->interfaceFlags() & END_IF_MASK;
if (exceptions)
throw exceptions;
} }
void SerialContainerPrivate::validateConnectivity() const { void SerialContainerPrivate::validateConnectivity() const {