Oneof

Oneof’s are powerful in saving RAM in your MCU. If you have a message where you will only set one of the 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 a union to do this. This means it is only possible to use one of the variables at a time.

Let us take a look at an example:

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

This message has a oneof named Bar. This oneof holds three variables of different sizes: 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 a 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 a oneof is set, the which variable changes. This holds also when deserializing a message. 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).