Oneof

Oneof’s are really powerful in saving RAM in your mcu. If you have a message where you will only set one of multiple variables at a time the oneof field will only allocate memory for the largest variable of the lot. The Embedded Proto implementation makes use of an union to do this. This means it is only possible to use one of the variables at a time.

Lets take a look at an example:

message Foo 
{
  oneof Bar 
  {
    bool active = 1;
    int32 count = 2;
    double value = 3;
  }
  // Other variables
}

This message has an oneof named Bar. This oneof holds three variables of different sizes, respectively one byte, four and eight. Because of the union the C++ code will only allocate eight bytes.

Please note that there is some overhead to an oneof. It is required to store which variable is currently in use. This is done via the field tag value. Each message generated by Embedded Proto has an enum class called id. This enumeration holds a list of all variables defined in the message together with their field tag. Each oneof has an accompanying variable of the type id. accessible via the which function.

enum class id
{
  NOT_SET = 0,
  ACTIVE = 1,
  COUNT = 2,
  VALUE = 3
};

id get_which_Bar() const;

Each time one of the variables in an oneof is set the which variable changes. This holds true also when deserializing a messages. Allowing you to make a switch statement to select which value to get from the object.

Template parameters and oneofs
If you have a message with an oneof together with fields which require template parameters (repeated, string and bytes) you need to watch the order of the templates. Template parameters for the regular fields are generated first only to be followed by the fields in the oneof(s).