You need your `SubscriberImpl` to hold a regular C++ pointer back to the `MediaLibraryImpl` that created it, so that you can access its `publishers_` set through that pointer. You can pass the pointer to `SubscriberImpl`'s constructor.
You'll also want to make sure the pointer doesn't become a dangling pointer, so `SubscriberImpl` should also hold a `MediaLibrary::Client` which points to the same `MediaLibraryImpl` -- holding this counts as a strong reference so Cap'n Proto won't destroy the `MediaLibraryImpl`. Inside `addSubscriber()` you can use `thisCap()` to get a `MediaLibrary::Client` pointing to `this`, then you'd pass that to `SubscriberImpl`'s constructor, along with the plain C++ pointer to `this`. -Kenton On Mon, Apr 26, 2021 at 10:25 AM Théophile B. <[email protected]> wrote: > Thank you for your quick answer! > > The `Server` to `Client` "conversion" is done via the bootstrap > capability, but I need the underlying `Server` back when calling > capabilities returned by the bootstrap capability. > Here is a simplified example where I (tried) to implement your advice: > > interface MediaLibrary { > addPublisher @0 (name :Text) -> (pub :Publisher); > addSubscriber @1 (name :Text) -> (sub :Subscriber); > > interface Publisher {} > > interface Subscriber { > listenTo @0 (publisher :Publisher); > } > } > > class MediaLibraryImpl final : public MediaLibrary::Server { > public: > kj::Promise<void> addPublisher(AddPublisherContext context) override { > my_underlying_library::Publisher* output = ...; // call the > underlying lib > MediaLibrary::Publisher::Client pub = publishers_.add(kj::heap< > PublisherImpl>(output)); > context.getResults().setPub(pub); > return kj::READY_NOW; > } > > kj::Promise<void> addSubscriber(AddSubscriberContext context) override { > my_underlying_library::Subscriber* output = ...; // call the > underlying lib > MediaLibrary::Subscriber::Client sub = subscribers_.add(kj::heap< > SubscriberImpl>(output)); > context.getResults().setSub(sub); > return kj::READY_NOW; > } > > private: > capnp::CapabilityServerSet<MediaLibrary::Subscriber> subscribers_; > capnp::CapabilityServerSet<MediaLibrary::Publisher> publishers_; > }; > > class PublisherImpl : public virtual GstDaemon::Publisher::Server { > protected: > PublisherImpl(my_underlying_library::Publisher* pub) : pub_(pub) {} > > private: > my_underlying_library::Publisher* pub_; > } > > class SubscriberImpl : public virtual GstDaemon::Subscriber::Server { > protected: > SubscriberImpl(my_underlying_library::Subscriber* sub) : sub_(sub) {} > > kj::Promise<void> listenTo(ListenToContext context) override { > auto pub = context.getParams().getPublisher(); // GstDaemon::Publisher > ::Client > // No access to CapabilityServerSet ! > // We we would like to do: sub_->listenTo("pub_") > } > > private: > my_underlying_library::Subscriber* sub_; > } > > If I understand well, I can now do subscribers_.getLocalServer("GstDaemon > ::Publisher::Client") from `MediaLibraryImpl`. > Bu what about SubscriberImpl, where the `listenTo` needs `PublisherImpl` ? > Is it possible to have access to `MediaLibraryImpl` from `SubscriberImpl` > ? > Instead, should I pass references to the `CapabilityServerSet` to ` > PublisherImpl` and `SubscriberImpl` ? > > Le lundi 26 avril 2021 à 16:30:55 UTC+2, [email protected] a écrit : > >> Hi Théophile, >> >> Take a look at CapabilityServerSet: >> >> >> https://github.com/capnproto/capnproto/blob/6b5bcc2c6e954bc6e167ac581eb628e5a462a469/c++/src/capnp/capability.h#L607-L633 >> >> When you convert your `Server` object to a `Client`, you need to do it >> using a CapabilityServerSet. Later, you can use the same set to unwrap the >> `Client` and get the underlying `Server` back -- even if the client has >> been passed over the network and back in the meantime. >> >> -Kenton >> >> On Mon, Apr 26, 2021 at 9:25 AM Théophile B. <[email protected]> >> wrote: >> >>> I'm not sure I'm usign the right terminology in my question, but I hope >>> you will understand my problem with the following example. >>> >>> I'm developing a media library where the user can play/pause/stop >>> different kinds of "pipelines" (source ~ camera, filter ~ processing, sink >>> ~ display). Depending on their type, these pipeline can listen to each >>> other, or not (e.g: a source pipeline cannot listen). I'm now working on a >>> "capnp wrapper" of the library, so that it can be controlled via RPC. >>> >>> I have replicated the class inheritance with success: >>> >>> interface Publisher {} >>> >>> interface Subscriber { >>> listenTo @0 (publisher :Publisher); >>> } >>> >>> interface Pipeline { >>> play @0 (); >>> pause @1 (); >>> stop @2 (); >>> } >>> >>> interface SourcePipeline extends(Pipeline, Publisher) {} >>> >>> interface FilterPipeline extends(Pipeline, Publisher, Subscriber) {} >>> >>> interface SinkPipeline extends(Pipeline, Subscriber) {} >>> >>> Server-side I have those impl classes, which holds the references to the >>> underlying objects of the media library (pub_ & sub_). >>> >>> class PublisherImpl : public virtual GstDaemon::Publisher::Server { >>> protected: >>> PublisherImpl(my_underlying_library::Publisher* pub) : pub_(pub) {} >>> private: >>> my_underlying_library::Publisher* pub_; >>> }; >>> >>> class SubscriberImpl : public virtual GstDaemon::Subscriber::Server { >>> protected: >>> SubscriberImpl(my_underlying_library::Subscriber* sub) : sub_(sub) {} >>> >>> kj::Promise<void> listenTo(ListenToContext context) override { >>> auto pub = context.getParams().getPublisher(); // GstDaemon::Publisher >>> ::Client >>> // ??? = PublisherImpl::pub_ >>> sub_->listenTo(???) >>> } >>> >>> private: >>> my_underlying_library::Subscriber* sub_; >>> }; >>> >>> Now, from the client, I wanted to do something like this: >>> //GstDaemon::Subscriber::Client subscriber; // already returned by the >>> server >>> //GstDaemon::Publisher::Client publisher; // already returned by the >>> server >>> auto request = subscriber.listenToRequest(); >>> request.setPublisher(publisher); >>> auto promise = request.send(); >>> >>> However, as you can see, on the server it's not possible to get the pub_ >>> pointer when the listenTo method is called. Is there any way I can get >>> a reference to the PublisherImpl here ? >>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "Cap'n Proto" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to [email protected]. >>> To view this discussion on the web visit >>> https://groups.google.com/d/msgid/capnproto/488a63c6-92bc-4bc8-9ab8-e648d3a577bfn%40googlegroups.com >>> <https://groups.google.com/d/msgid/capnproto/488a63c6-92bc-4bc8-9ab8-e648d3a577bfn%40googlegroups.com?utm_medium=email&utm_source=footer> >>> . >>> >> -- > You received this message because you are subscribed to the Google Groups > "Cap'n Proto" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To view this discussion on the web visit > https://groups.google.com/d/msgid/capnproto/45982dae-5fb0-4adb-8b15-9fea70506d25n%40googlegroups.com > <https://groups.google.com/d/msgid/capnproto/45982dae-5fb0-4adb-8b15-9fea70506d25n%40googlegroups.com?utm_medium=email&utm_source=footer> > . > -- You received this message because you are subscribed to the Google Groups "Cap'n Proto" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/capnproto/CAJouXQmJ6cz_%2BGKsgo82ePNFaerqy27XJcEKMgXAMD3ePzRpvA%40mail.gmail.com.
