Had a few spare hours to have another bash at it.

In the seems-to-work-but-I-have-no-idea-what-I'm-doing category…

template <typename T>
class SharedOrphan {
public:
    SharedOrphan(std::shared_ptr<capnp::MallocMessageBuilder> mb, capnp::
Orphan<T>& orphan) :
        message_builder(mb), orphan(std::move(orphan))
    {};
    
    inline capnp::BuilderFor<T> get() {
        return orphan.get();
    };

    inline capnp::ReaderFor<T> getReader() const {
        return orphan.getReader();
    };
    
private:
    std::shared_ptr<capnp::MallocMessageBuilder> message_builder;
    capnp::Orphan<T> orphan;
};

SharedOrphan<::Status::Amp> amp_status() {
    std::shared_ptr<capnp::MallocMessageBuilder> mb = std::shared_ptr<capnp
::MallocMessageBuilder>(new capnp::MallocMessageBuilder());
//std::make_shared<capnp::MallocMessageBuilder>();
    
    auto amp_status_o = mb->getOrphanage().newOrphan<::Status::Amp>();
    auto amp_status = amp_status_o.get();
    
    auto zones = amp_status.initZones(6);
    
    for (auto z: zones) {
        z.setId("zone ID");
        z.setVolume(10);
    }
    
    return SharedOrphan<::Status::Amp>(mb, amp_status_o);
}


SharedOrphan<::Status::HDMI> hdmi_status() {
    std::shared_ptr<capnp::MallocMessageBuilder> mb = std::shared_ptr<capnp
::MallocMessageBuilder>(new capnp::MallocMessageBuilder());
//std::make_shared<capnp::MallocMessageBuilder>();

    auto hdmi_status_o = mb->getOrphanage().newOrphan<::Status::HDMI>();
    
    return SharedOrphan<::Status::HDMI>(mb, hdmi_status_o);
}


void broadcast_status() {
    capnp::MallocMessageBuilder mb;
    
    auto status = mb.initRoot<Status>();
    
    auto amp_status_f = boost::async(boost::launch::async, amp_status).share
();
    auto hdmi_status_f = boost::async(boost::launch::async, hdmi_status).
share();
    
    auto all_f = boost::when_all(amp_status_f, hdmi_status_f);
    auto str = all_f.then([&](decltype(all_f)) {
        
        status.setAmp(amp_status_f.get().getReader());
        status.setHdmi(hdmi_status_f.get().getReader());
        
        return status;
        
    }).get().toString();
    
    std::cout << str.flatten().cStr() << std::endl;
}


The resulting message is built correctly. And I'm assuming that since I'm 
passing around both the Orphan and the backing MessageBuilder, that there 
are no use-after-free issues with this.

- Adam

-- 
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].
Visit this group at https://groups.google.com/group/capnproto.

Reply via email to