dimanche 22 avril 2018

Initialize a List of Lists with Cap’n Proto Builders

I've been following along with the capnproto c++ serialization page, but ran in to a snag. I'm trying to build a list of commands that each have a list of floats using capnproto buffers. I'm having trouble figuring out why my program is crashing on the first call to set() on an inner list. I have a feeling that the issue is that commands[cmd++] might be a Reader, not a Builder.

My proto file:

struct Image {
  timestamp @2 :UInt32;

  commands @3 :List(Command);

  struct Command {
    cmd :union{
       type @0 :PrimitiveType;
       state @1 :Text;
    }
    values @2:List(Float32);
    enum PrimitiveType {
      line @0;
      circle @1;
    }
  }
}

My builder code:

void render(vector<circle> pts, int fd){
     ::capnp::MallocMessageBuilder message;
  Image::Builder img = message.initRoot<Image>();
  img.setTimestamp(time(nullptr));

  capnp::List<Image::Command>::Builder commands = img.initCommands(pts.size());
  int cmd = 0;
  for(int i=0; i < pts.size(); i++){

    auto curCommand = commands[cmd++];
    curCommand.getCmd().setType(Image::Command::PrimitiveType::CIRCLE);

    auto v = curCommand.initValues(3);
    v.set(0, pts[i].pos.x);
    v.set(1, pts[i].pos.y);
    v.set(2, pts[i].r);
  };  
 writePackedMessageToFd(fd, message); 
}

It looks like curCommand.setValues( { m_pts[i].pos.x, m_pts[i].pos.y, m_pts[i].r } ); is closer to the correct way to create it, but this also asserts and seems to be calling set(index, value) under the hood as well.

Aucun commentaire:

Enregistrer un commentaire