void subscribe_to(collection_type st) { auto state = this->shared_from_this(); collectionLifetime = composite_subscription(); // when the out observer is unsubscribed all the // inner subscriptions are unsubscribed as well auto innercstoken = state->out.add(collectionLifetime); collectionLifetime.add(make_subscription([state, innercstoken](){ state->out.remove(innercstoken); })); auto selectedSource = on_exception( [&](){return state->coordinator.in(std::move(st));}, state->out); if (selectedSource.empty()) { return; } // this subscribe does not share the out subscription // so that when it is unsubscribed the out will continue auto sinkInner = make_subscriber<value_type>( state->out, collectionLifetime, // on_next [state, st](value_type ct) { state->out.on_next(ct); }, // on_error [state](std::exception_ptr e) { state->out.on_error(e); }, //on_completed [state](){ if (!state->selectedCollections.empty()) { auto value = state->selectedCollections.front(); state->selectedCollections.pop_front(); state->collectionLifetime.unsubscribe(); state->subscribe_to(value); } else if (!state->sourceLifetime.is_subscribed()) { state->out.on_completed(); } } ); auto selectedSinkInner = on_exception( [&](){return state->coordinator.out(sinkInner);}, state->out); if (selectedSinkInner.empty()) { return; } selectedSource->subscribe(std::move(selectedSinkInner.get())); }
int main (int argc, char const *argv[]) { signal(SIGINT, stros_stop); ros_node_t* node = stros_init_node("/dummy",argv[1]); // subscribe subscribe_to( node,"/chatter",MSG_STRING,callback); stros_node_deploy(node); printf("Finish deploy\n"); spin(); return 0; }
void on_subscribe(Subscriber scbr) const { static_assert(is_subscriber<Subscriber>::value, "subscribe must be passed a subscriber"); typedef Subscriber output_type; struct concat_state_type : public std::enable_shared_from_this<concat_state_type> , public values { concat_state_type(values i, coordinator_type coor, output_type oarg) : values(std::move(i)) , sourceLifetime(composite_subscription::empty()) , collectionLifetime(composite_subscription::empty()) , coordinator(std::move(coor)) , out(std::move(oarg)) { } void subscribe_to(collection_type st) { auto state = this->shared_from_this(); collectionLifetime = composite_subscription(); // when the out observer is unsubscribed all the // inner subscriptions are unsubscribed as well auto innercstoken = state->out.add(collectionLifetime); collectionLifetime.add(make_subscription([state, innercstoken](){ state->out.remove(innercstoken); })); auto selectedSource = on_exception( [&](){return state->coordinator.in(std::move(st));}, state->out); if (selectedSource.empty()) { return; } // this subscribe does not share the out subscription // so that when it is unsubscribed the out will continue auto sinkInner = make_subscriber<value_type>( state->out, collectionLifetime, // on_next [state, st](value_type ct) { state->out.on_next(ct); }, // on_error [state](std::exception_ptr e) { state->out.on_error(e); }, //on_completed [state](){ if (!state->selectedCollections.empty()) { auto value = state->selectedCollections.front(); state->selectedCollections.pop_front(); state->collectionLifetime.unsubscribe(); state->subscribe_to(value); } else if (!state->sourceLifetime.is_subscribed()) { state->out.on_completed(); } } ); auto selectedSinkInner = on_exception( [&](){return state->coordinator.out(sinkInner);}, state->out); if (selectedSinkInner.empty()) { return; } selectedSource->subscribe(std::move(selectedSinkInner.get())); } composite_subscription sourceLifetime; composite_subscription collectionLifetime; std::deque<collection_type> selectedCollections; coordinator_type coordinator; output_type out; }; auto coordinator = initial.coordination.create_coordinator(scbr.get_subscription()); // take a copy of the values for each subscription auto state = std::shared_ptr<concat_state_type>(new concat_state_type(initial, std::move(coordinator), std::move(scbr))); state->sourceLifetime = composite_subscription(); // when the out observer is unsubscribed all the // inner subscriptions are unsubscribed as well state->out.add(state->sourceLifetime); auto source = on_exception( [&](){return state->coordinator.in(state->source);}, state->out); if (source.empty()) { return; } // this subscribe does not share the observer subscription // so that when it is unsubscribed the observer can be called // until the inner subscriptions have finished auto sink = make_subscriber<collection_type>( state->out, state->sourceLifetime, // on_next [state](collection_type st) { if (state->collectionLifetime.is_subscribed()) { state->selectedCollections.push_back(st); } else if (state->selectedCollections.empty()) { state->subscribe_to(st); } }, // on_error [state](std::exception_ptr e) { state->out.on_error(e); }, // on_completed [state]() { if (!state->collectionLifetime.is_subscribed() && state->selectedCollections.empty()) { state->out.on_completed(); } } ); auto selectedSink = on_exception( [&](){return state->coordinator.out(sink);}, state->out); if (selectedSink.empty()) { return; } source->subscribe(std::move(selectedSink.get())); }