It works ! Thank you for the expanded explanation, it helped a lot. I 
initially though there would be a "prettier" out-of-the-box solution, but as 
long as it works...

While I have you, I have a more general question. Is it common case to 
distribute Cap'n'Proto genererated headers as part of a library, or 
everything must stay private ?
Let's say I have defined some enum in the .capnp and I want the users of my 
library to use them. 
For the moment I have a duplicated the definition of this enum in a public 
header, and I do static casts before serialization.
Le lundi 26 avril 2021 à 17:40:59 UTC+2, [email protected] a écrit :

> 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/8c279b5e-0fe0-4dac-af58-22eeda468c92n%40googlegroups.com.

Reply via email to