文章

FlatBuffers

FlatBuffers

Why

  • Access to serialized data without parsing/unpacking
  • Memory Efficiency and Speed
  • Backwards and Forwards Compatibility
  • Small Footprint

How to Define FlatBuffer schema (.fbs)

namespace

FlatBuffers has support for namespaces to place the generated code into. There is mixed level of support for namespaces (some languages don’t have namespaces), but for the C family of languages, it is fully supported.

  • place the generated code into
1
namespace MyGame.Sample;

enum

Enums definitions can be defined with the backing numerical type. Implicit numbering is supported, so that Green would have a value of 1.

  • numerical type
  • Implicit numbering is supported
1
enum Color:byte { Red = 0, Green, Blue = 2 }

union

A union represents a single value from a set of possible values. Its effectively an enum (to represent the type actually store) and a value, combined into one. In this example, the union is not very useful, since it only has a single type.

  • Similar to the union of C++
1
union Equipment { Weapon }

struct

A struct is a collection of scalar fields with names.

It is itself a scalar type, which uses less memory and has faster lookup.

However, once a struct is defined, it cannot be changed.

Use tables for data structures that can evolve over time.

  • struct will be serialized inline in the table without any need for offset.
1
2
3
4
5
struct Vec3 { 
  x:float; 
  y:float;
  z:float;
}

scalar types

FlatBuffers has the standard set of scalar numerical types (int8, int16, int32, int64, uint8, uint16, uint32, uint64, float, double), as well as bool. Note, scalars are fixed width, varints are not supported.

table

Tables are the main data structure for grouping data together. It can evolve by adding and deprecating fields over time, while preserving forward and backwards compatibility.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
table Monster {
    pos:Vec3; // A field that happens to be a struct. This means the data of the Vec3 struct will be serialized inline in the table without any need for offset.

    mana:short = 150; // Fields can be provided a default value. Default values can be configured to not be serialized at all while still providing the default value while deserializing. However, once set, a default value cannot be changed.

    hp:short = 100;
    
    name:string; // A string field which points to a serialized string external to the table.
    
    friendly:bool = false (deprecated); // A deprecated field that is no longer being used. This is used instead of removing the field outright.
    
    inventory:[ubyte]; // A vector field that points to a vector of bytes. Like strings, the vector data is serialized elsewhere and this field just stores an offset to the vector.
    
    color:Color = Blue;
    
    weapons:[Weapon];  // Vector of tables and structs are also possible.
    
    equipped:Equipment;  // A field to a union type.
    
    path:[Vec3];
    
}

root_type

The root of the flatbuffer is always a table. This indicates the type of table the “entry” point of the flatbuffer will point to.

1
root_type Monster; 

compiler to transform the schema into language-specific code

Serialized

Read the data

本文由作者按照 CC BY 4.0 进行授权