More native code gen functionality.

Allow tables to be mapped to native types directly.  For example, a table
representing a vector3 (eg. table Vec3 { x:float; y:float; z:float; }) can
be mapped to a "mathfu::vec3" native type in NativeTables.  This requires
users to provide Pack and UnPack functions that convert between the
Table and native types.  This is done by adding the "native_type" attribute
to the table definition.

To support user-defined flatbuffers::Pack and flatbuffers::UnPack functions,
support a "native_include" markup that will generate a corresponding

Also add an UnPackTo function which allows users to pass in a pointer to
a NativeTable object into which to UnPack the Table.  The existing UnPack
function is now simply:

  NativeTable* UnPack() {
    NativeTable* obj = new NativeTable();
    Table::UnPackTo(obj);
    return obj;
  }

Finally, allow native types to be given a default value as well which are
set in the NativeTable constructor.  This is done by providing a
"native_default" attribute to the member of a table.

Change-Id: Ic45cb48b0e6d7cfa5734b24819e54aa96d847cfd
This commit is contained in:
Wouter van Oortmerssen 2017-01-18 16:23:35 -08:00
parent 42a265b419
commit 3f936c5655
7 changed files with 318 additions and 90 deletions

View File

@ -85,7 +85,7 @@ convenient accessors for all fields, e.g. `hp()`, `mana()`, etc:
*Note: That we never stored a `mana` value, so it will return the default.*
## Object based API.
## Object based API. {#flatbuffers_cpp_object_based_api}
FlatBuffers is all about memory efficiency, which is why its base API is written
around using as little as possible of it. This does make the API clumsier
@ -99,13 +99,79 @@ construction, access and mutation.
To use:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
auto monsterobj = UnpackMonster(buffer);
// Autogenerated class from table Monster.
MonsterT monsterobj;
// Deserialize from buffer into object.
UnPackTo(&monsterobj, flatbuffer);
// Update object directly like a C++ class instance.
cout << monsterobj->name; // This is now a std::string!
monsterobj->name = "Bob"; // Change the name.
// Serialize into new flatbuffer.
FlatBufferBuilder fbb;
CreateMonster(fbb, monsterobj.get()); // Serialize into new buffer.
Pack(fbb, &monsterobj);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The following attributes are specific to the object-based API code generation:
- `native_inline` (on a field): Because FlatBuffer tables and structs are
optionally present in a given buffer, they are best represented as pointers
(specifically std::unique_ptrs) in the native class since they can be null.
This attribute changes the member declaration to use the type directly
rather than wrapped in a unique_ptr.
- `native_default`: "value" (on a field): For members that are declared
"native_inline", the value specified with this attribute will be included
verbatim in the class constructor initializer list for this member.
- `native_type`' "type" (on a struct): In some cases, a more optimal C++ data
type exists for a given struct. For example, the following schema:
struct Vec2 {
x: float;
y: float;
}
generates the following Object-Based API class:
struct Vec2T : flatbuffers::NativeTable {
float x;
float y;
};
However, it can be useful to instead use a user-defined C++ type since it
can provide more functionality, eg.
struct vector2 {
float x = 0, y = 0;
vector2 operator+(vector2 rhs) const { ... }
vector2 operator-(vector2 rhs) const { ... }
float length() const { ... }
// etc.
};
The `native_type` attribute will replace the usage of the generated class
with the given type. So, continuing with the example, the generated
code would use |vector2| in place of |Vec2T| for all generated code.
However, becuase the native_type is unknown to flatbuffers, the user must
provide the following functions to aide in the serialization process:
namespace flatbuffers {
FlatbufferStruct Pack(const native_type& obj);
native_type UnPack(const FlatbufferStruct& obj);
}
Finally, the following top-level attribute
- native_include: "path" (at file level): Because the `native_type` attribute
can be used to introduce types that are unknown to flatbuffers, it may be
necessary to include "external" header files in the generated code. This
attribute can be used to directly add an #include directive to the top of
the generated code that includes the specified path directly.
# External references.
An additional feature of the object API is the ability to allow you to load

View File

@ -309,6 +309,10 @@ Current understood attributes:
to be stored in any particular order, they are often optimized for
space by sorting them to size. This attribute stops that from happening.
There should generally not be any reason to use this flag.
- 'native_*'. Several attributes have been added to support the [C++ object
Based API](@ref flatbuffers_cpp_object_based_api). All such attributes
are prefixed with the term "native_".
## JSON Parsing

View File

@ -459,6 +459,8 @@ class Parser : public ParserState {
known_attributes_["cpp_type"] = true;
known_attributes_["cpp_ptr_type"] = true;
known_attributes_["native_inline"] = true;
known_attributes_["native_type"] = true;
known_attributes_["native_default"] = true;
}
~Parser() {
@ -573,6 +575,7 @@ private:
std::map<std::string, bool> included_files_;
std::map<std::string, std::set<std::string>> files_included_per_file_;
std::vector<std::string> native_included_files_;
std::map<std::string, bool> known_attributes_;

View File

@ -241,7 +241,8 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VerifyEquipment(verifier, equipped(), equipped_type()) &&
verifier.EndTable();
}
MonsterT *UnPack(const flatbuffers::resolver_function_t *resolver = nullptr) const;
MonsterT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
void UnPackTo(MonsterT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
static flatbuffers::Offset<Monster> Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};
@ -371,7 +372,8 @@ struct Weapon FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VerifyField<int16_t>(verifier, VT_DAMAGE) &&
verifier.EndTable();
}
WeaponT *UnPack(const flatbuffers::resolver_function_t *resolver = nullptr) const;
WeaponT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
void UnPackTo(WeaponT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
static flatbuffers::Offset<Weapon> Pack(flatbuffers::FlatBufferBuilder &_fbb, const WeaponT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};
@ -418,19 +420,24 @@ inline flatbuffers::Offset<Weapon> CreateWeaponDirect(
flatbuffers::Offset<Weapon> CreateWeapon(flatbuffers::FlatBufferBuilder &_fbb, const WeaponT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
inline MonsterT *Monster::UnPack(const flatbuffers::resolver_function_t *resolver) const {
(void)resolver;
inline MonsterT *Monster::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
auto _o = new MonsterT();
UnPackTo(_o, _resolver);
return _o;
}
inline void Monster::UnPackTo(MonsterT *_o, const flatbuffers::resolver_function_t *_resolver) const {
(void)_o;
(void)_resolver;
{ auto _e = pos(); if (_e) _o->pos = std::unique_ptr<Vec3>(new Vec3(*_e)); };
{ auto _e = mana(); _o->mana = _e; };
{ auto _e = hp(); _o->hp = _e; };
{ auto _e = name(); if (_e) _o->name = _e->str(); };
{ auto _e = inventory(); if (_e) for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->inventory.push_back(_e->Get(_i)); } };
{ auto _e = color(); _o->color = _e; };
{ auto _e = weapons(); if (_e) for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->weapons.push_back(std::unique_ptr<WeaponT>(_e->Get(_i)->UnPack(resolver))); } };
{ auto _e = weapons(); if (_e) for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->weapons.push_back(std::unique_ptr<WeaponT>(_e->Get(_i)->UnPack(_resolver))); } };
{ auto _e = equipped_type(); _o->equipped.type = _e; };
{ auto _e = equipped(); if (_e) _o->equipped.table = EquipmentUnion::UnPack(_e, equipped_type(),resolver); };
return _o;
{ auto _e = equipped(); if (_e) _o->equipped.table = EquipmentUnion::UnPack(_e, equipped_type(),_resolver); };
}
inline flatbuffers::Offset<Monster> Monster::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
@ -440,25 +447,39 @@ inline flatbuffers::Offset<Monster> Monster::Pack(flatbuffers::FlatBufferBuilder
inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
(void)_rehasher;
(void)_o;
auto _pos = _o->pos ? _o->pos.get() : 0;
auto _mana = _o->mana;
auto _hp = _o->hp;
auto _name = _o->name.size() ? _fbb.CreateString(_o->name) : 0;
auto _inventory = _o->inventory.size() ? _fbb.CreateVector(_o->inventory) : 0;
auto _color = _o->color;
auto _weapons = _o->weapons.size() ? _fbb.CreateVector<flatbuffers::Offset<Weapon>>(_o->weapons.size(), [&](size_t i) { return CreateWeapon(_fbb, _o->weapons[i].get(), _rehasher); }) : 0;
auto _equipped_type = _o->equipped.type;
auto _equipped = _o->equipped.Pack(_fbb);
return CreateMonster(
_fbb,
_o->pos ? _o->pos.get() : 0,
_o->mana,
_o->hp,
_o->name.size() ? _fbb.CreateString(_o->name) : 0,
_o->inventory.size() ? _fbb.CreateVector(_o->inventory) : 0,
_o->color,
_o->weapons.size() ? _fbb.CreateVector<flatbuffers::Offset<Weapon>>(_o->weapons.size(), [&](size_t i) { return CreateWeapon(_fbb, _o->weapons[i].get(), _rehasher); }) : 0,
_o->equipped.type,
_o->equipped.Pack(_fbb));
_pos,
_mana,
_hp,
_name,
_inventory,
_color,
_weapons,
_equipped_type,
_equipped);
}
inline WeaponT *Weapon::UnPack(const flatbuffers::resolver_function_t *resolver) const {
(void)resolver;
inline WeaponT *Weapon::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
auto _o = new WeaponT();
UnPackTo(_o, _resolver);
return _o;
}
inline void Weapon::UnPackTo(WeaponT *_o, const flatbuffers::resolver_function_t *_resolver) const {
(void)_o;
(void)_resolver;
{ auto _e = name(); if (_e) _o->name = _e->str(); };
{ auto _e = damage(); _o->damage = _e; };
return _o;
}
inline flatbuffers::Offset<Weapon> Weapon::Pack(flatbuffers::FlatBufferBuilder &_fbb, const WeaponT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
@ -468,10 +489,12 @@ inline flatbuffers::Offset<Weapon> Weapon::Pack(flatbuffers::FlatBufferBuilder &
inline flatbuffers::Offset<Weapon> CreateWeapon(flatbuffers::FlatBufferBuilder &_fbb, const WeaponT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
(void)_rehasher;
(void)_o;
auto _name = _o->name.size() ? _fbb.CreateString(_o->name) : 0;
auto _damage = _o->damage;
return CreateWeapon(
_fbb,
_o->name.size() ? _fbb.CreateString(_o->name) : 0,
_o->damage);
_name,
_damage);
}
inline bool VerifyEquipment(flatbuffers::Verifier &verifier, const void *obj, Equipment type) {

View File

@ -60,6 +60,11 @@ class CppGenerator : public BaseGenerator {
void GenIncludeDependencies() {
int num_includes = 0;
for (auto it = parser_.native_included_files_.begin();
it != parser_.native_included_files_.end(); ++it) {
code_ += "#include \"" + *it + "\"";
num_includes++;
}
for (auto it = parser_.included_files_.begin();
it != parser_.included_files_.end(); ++it) {
const auto basename =
@ -384,8 +389,12 @@ class CppGenerator : public BaseGenerator {
return "std::vector<" + type_name + ">";
}
case BASE_TYPE_STRUCT: {
const auto type_name = WrapInNameSpace(*type.struct_def);
auto type_name = WrapInNameSpace(*type.struct_def);
if (IsStruct(type)) {
auto native_type = type.struct_def->attributes.Lookup("native_type");
if (native_type) {
type_name = native_type->constant;
}
if (invector || field.native_inline) {
return type_name;
} else {
@ -487,7 +496,15 @@ class CppGenerator : public BaseGenerator {
bool inclass) {
return NativeName(struct_def.name) + " *" +
(inclass ? "" : struct_def.name + "::") +
"UnPack(const flatbuffers::resolver_function_t *resolver" +
"UnPack(const flatbuffers::resolver_function_t *_resolver" +
(inclass ? " = nullptr" : "") + ") const";
}
static std::string TableUnPackToSignature(const StructDef &struct_def,
bool inclass) {
return "void " + (inclass ? "" : struct_def.name + "::") +
"UnPackTo(" + NativeName(struct_def.name) + " *" + "_o, " +
"const flatbuffers::resolver_function_t *_resolver" +
(inclass ? " = nullptr" : "") + ") const";
}
@ -889,6 +906,17 @@ class CppGenerator : public BaseGenerator {
}
initializer_list += field.name;
initializer_list += "(" + GetDefaultScalarValue(field) + ")";
} else if (field.value.type.base_type == BASE_TYPE_STRUCT) {
if (IsStruct(field.value.type)) {
auto native_default = field.attributes.Lookup("native_default");
if (native_default) {
if (!initializer_list.empty()) {
initializer_list += ",\n ";
}
initializer_list +=
field.name + "(" + native_default->constant + ")";
}
}
} else if (cpp_type) {
if (!initializer_list.empty()) {
initializer_list += ",\n ";
@ -1159,6 +1187,7 @@ class CppGenerator : public BaseGenerator {
if (parser_.opts.generate_object_based_api) {
// Generate the UnPack() pre declaration.
code_ += " " + TableUnPackSignature(struct_def, true) + ";";
code_ += " " + TableUnPackToSignature(struct_def, true) + ";";
code_ += " " + TablePackSignature(struct_def, true) + ";";
}
@ -1338,7 +1367,10 @@ class CppGenerator : public BaseGenerator {
case BASE_TYPE_STRUCT: {
const auto name = WrapInNameSpace(*type.struct_def);
if (IsStruct(type)) {
if (invector || afield.native_inline) {
auto native_type = type.struct_def->attributes.Lookup("native_type");
if (native_type) {
return "flatbuffers::UnPack(*" + val + ")";
} else if (invector || afield.native_inline) {
return "*" + val;
} else {
const auto ptype = GenTypeNativePtr(name, &afield, true);
@ -1346,7 +1378,7 @@ class CppGenerator : public BaseGenerator {
}
} else {
const auto ptype = GenTypeNativePtr(NativeName(name), &afield, true);
return ptype + "(" + val + "->UnPack(resolver))";
return ptype + "(" + val + "->UnPack(_resolver))";
}
}
default: {
@ -1395,7 +1427,7 @@ class CppGenerator : public BaseGenerator {
code += "_o->" + field.name + ".table = ";
code += field.value.type.enum_def->name + "Union::UnPack(";
code += "_e, " + field.name + UnionTypeFieldSuffix() + "(),";
code += "resolver);";
code += "_resolver);";
break;
}
default: {
@ -1406,8 +1438,8 @@ class CppGenerator : public BaseGenerator {
// (*resolver)(&_o->field, (hash_value_t)(_e));
// else
// _o->field = nullptr;
code += "if (resolver) ";
code += "(*resolver)";
code += "if (_resolver) ";
code += "(*_resolver)";
code += "(reinterpret_cast<void **>(&_o->" + field.name + "), ";
code += "static_cast<flatbuffers::hash_value_t>(_e));";
code += " else ";
@ -1514,7 +1546,11 @@ class CppGenerator : public BaseGenerator {
}
case BASE_TYPE_STRUCT: {
if (IsStruct(field.value.type)) {
if (field.native_inline) {
auto native_type =
field.value.type.struct_def->attributes.Lookup("native_type");
if (native_type) {
code += "flatbuffers::Pack(" + value + ")";
} else if (field.native_inline) {
code += "&" + value;
} else {
code += value + " ? " + value + GenPtrGet(field) + " : 0";
@ -1544,8 +1580,15 @@ class CppGenerator : public BaseGenerator {
if (parser_.opts.generate_object_based_api) {
// Generate the X::UnPack() method.
code_ += "inline " + TableUnPackSignature(struct_def, false) + " {";
code_ += " (void)resolver;";
code_ += " auto _o = new {{NATIVE_NAME}}();";
code_ += " UnPackTo(_o, _resolver);";
code_ += " return _o;";
code_ += "}";
code_ += "";
code_ += "inline " + TableUnPackToSignature(struct_def, false) + " {";
code_ += " (void)_o;";
code_ += " (void)_resolver;";
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
@ -1567,7 +1610,6 @@ class CppGenerator : public BaseGenerator {
auto postfix = " };";
code_ += std::string(prefix) + check + statement + postfix;
}
code_ += " return _o;";
code_ += "}";
code_ += "";
@ -1582,8 +1624,6 @@ class CppGenerator : public BaseGenerator {
code_ += "inline " + TableCreateSignature(struct_def, false) + " {";
code_ += " (void)_rehasher;";
code_ += " (void)_o;";
code_ += " return Create{{STRUCT_NAME}}(";
code_ += " _fbb\\";
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
@ -1591,8 +1631,35 @@ class CppGenerator : public BaseGenerator {
if (field.deprecated) {
continue;
}
code_ += " auto _" + field.name + " = " + GenCreateParam(field) + ";";
}
code_ += " return Create{{STRUCT_NAME}}(";
code_ += " _fbb\\";
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
auto &field = **it;
if (field.deprecated) {
continue;
}
bool pass_by_address = false;
if (field.value.type.base_type == BASE_TYPE_STRUCT) {
if (IsStruct(field.value.type)) {
auto native_type =
field.value.type.struct_def->attributes.Lookup("native_type");
if (native_type) {
pass_by_address = true;
}
}
}
// Call the CreateX function using values from |_o|.
code_ += ",\n " + GenCreateParam(field) + "\\";
if (pass_by_address) {
code_ += ",\n &_" + field.name + "\\";
} else {
code_ += ",\n _" + field.name + "\\";
}
}
code_ += ");";
code_ += "}";

View File

@ -174,7 +174,8 @@ std::string Namespace::GetFullyQualifiedName(const std::string &name,
TD(Include, 269, "include") \
TD(Attribute, 270, "attribute") \
TD(Null, 271, "null") \
TD(Service, 272, "rpc_service")
TD(Service, 272, "rpc_service") \
TD(NativeInclude, 273, "native_include")
#ifdef __GNUC__
__extension__ // Stop GCC complaining about trailing comma with -Wpendantic.
#endif
@ -432,6 +433,10 @@ CheckedError Parser::Next() {
token_ = kTokenService;
return NoError();
}
if (attribute_ == "native_include") {
token_ = kTokenNativeInclude;
return NoError();
}
// If not, it is a user-defined identifier:
token_ = kTokenIdentifier;
return NoError();
@ -1857,6 +1862,10 @@ CheckedError Parser::DoParse(const char *source, const char **include_paths,
(attribute_ == "option" || attribute_ == "syntax" ||
attribute_ == "package")) {
ECHECK(ParseProtoDecl());
} else if (Is(kTokenNativeInclude)) {
NEXT();
native_included_files_.emplace_back(attribute_);
EXPECT(kTokenStringConstant);
} else if (Is(kTokenInclude) ||
(opts.proto_mode &&
attribute_ == "import" &&

View File

@ -259,7 +259,8 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
return VerifyTableStart(verifier) &&
verifier.EndTable();
}
MonsterT *UnPack(const flatbuffers::resolver_function_t *resolver = nullptr) const;
MonsterT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
void UnPackTo(MonsterT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
static flatbuffers::Offset<Monster> Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};
@ -314,7 +315,8 @@ struct TestSimpleTableWithEnum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Ta
VerifyField<int8_t>(verifier, VT_COLOR) &&
verifier.EndTable();
}
TestSimpleTableWithEnumT *UnPack(const flatbuffers::resolver_function_t *resolver = nullptr) const;
TestSimpleTableWithEnumT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
void UnPackTo(TestSimpleTableWithEnumT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
static flatbuffers::Offset<TestSimpleTableWithEnum> Pack(flatbuffers::FlatBufferBuilder &_fbb, const TestSimpleTableWithEnumT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};
@ -390,7 +392,8 @@ struct Stat FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VerifyField<uint16_t>(verifier, VT_COUNT) &&
verifier.EndTable();
}
StatT *UnPack(const flatbuffers::resolver_function_t *resolver = nullptr) const;
StatT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
void UnPackTo(StatT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
static flatbuffers::Offset<Stat> Pack(flatbuffers::FlatBufferBuilder &_fbb, const StatT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};
@ -751,7 +754,8 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
verifier.VerifyVectorOfStrings(testarrayofstring2()) &&
verifier.EndTable();
}
MonsterT *UnPack(const flatbuffers::resolver_function_t *resolver = nullptr) const;
MonsterT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
void UnPackTo(MonsterT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
static flatbuffers::Offset<Monster> Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};
@ -985,12 +989,17 @@ flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb,
namespace Example2 {
inline MonsterT *Monster::UnPack(const flatbuffers::resolver_function_t *resolver) const {
(void)resolver;
inline MonsterT *Monster::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
auto _o = new MonsterT();
UnPackTo(_o, _resolver);
return _o;
}
inline void Monster::UnPackTo(MonsterT *_o, const flatbuffers::resolver_function_t *_resolver) const {
(void)_o;
(void)_resolver;
}
inline flatbuffers::Offset<Monster> Monster::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
return CreateMonster(_fbb, _o, _rehasher);
}
@ -1006,13 +1015,18 @@ inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder
namespace Example {
inline TestSimpleTableWithEnumT *TestSimpleTableWithEnum::UnPack(const flatbuffers::resolver_function_t *resolver) const {
(void)resolver;
inline TestSimpleTableWithEnumT *TestSimpleTableWithEnum::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
auto _o = new TestSimpleTableWithEnumT();
{ auto _e = color(); _o->color = _e; };
UnPackTo(_o, _resolver);
return _o;
}
inline void TestSimpleTableWithEnum::UnPackTo(TestSimpleTableWithEnumT *_o, const flatbuffers::resolver_function_t *_resolver) const {
(void)_o;
(void)_resolver;
{ auto _e = color(); _o->color = _e; };
}
inline flatbuffers::Offset<TestSimpleTableWithEnum> TestSimpleTableWithEnum::Pack(flatbuffers::FlatBufferBuilder &_fbb, const TestSimpleTableWithEnumT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
return CreateTestSimpleTableWithEnum(_fbb, _o, _rehasher);
}
@ -1020,18 +1034,24 @@ inline flatbuffers::Offset<TestSimpleTableWithEnum> TestSimpleTableWithEnum::Pac
inline flatbuffers::Offset<TestSimpleTableWithEnum> CreateTestSimpleTableWithEnum(flatbuffers::FlatBufferBuilder &_fbb, const TestSimpleTableWithEnumT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
(void)_rehasher;
(void)_o;
auto _color = _o->color;
return CreateTestSimpleTableWithEnum(
_fbb,
_o->color);
_color);
}
inline StatT *Stat::UnPack(const flatbuffers::resolver_function_t *resolver) const {
(void)resolver;
inline StatT *Stat::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
auto _o = new StatT();
UnPackTo(_o, _resolver);
return _o;
}
inline void Stat::UnPackTo(StatT *_o, const flatbuffers::resolver_function_t *_resolver) const {
(void)_o;
(void)_resolver;
{ auto _e = id(); if (_e) _o->id = _e->str(); };
{ auto _e = val(); _o->val = _e; };
{ auto _e = count(); _o->count = _e; };
return _o;
}
inline flatbuffers::Offset<Stat> Stat::Pack(flatbuffers::FlatBufferBuilder &_fbb, const StatT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
@ -1041,16 +1061,25 @@ inline flatbuffers::Offset<Stat> Stat::Pack(flatbuffers::FlatBufferBuilder &_fbb
inline flatbuffers::Offset<Stat> CreateStat(flatbuffers::FlatBufferBuilder &_fbb, const StatT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
(void)_rehasher;
(void)_o;
auto _id = _o->id.size() ? _fbb.CreateString(_o->id) : 0;
auto _val = _o->val;
auto _count = _o->count;
return CreateStat(
_fbb,
_o->id.size() ? _fbb.CreateString(_o->id) : 0,
_o->val,
_o->count);
_id,
_val,
_count);
}
inline MonsterT *Monster::UnPack(const flatbuffers::resolver_function_t *resolver) const {
(void)resolver;
inline MonsterT *Monster::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
auto _o = new MonsterT();
UnPackTo(_o, _resolver);
return _o;
}
inline void Monster::UnPackTo(MonsterT *_o, const flatbuffers::resolver_function_t *_resolver) const {
(void)_o;
(void)_resolver;
{ auto _e = pos(); if (_e) _o->pos = std::unique_ptr<Vec3>(new Vec3(*_e)); };
{ auto _e = mana(); _o->mana = _e; };
{ auto _e = hp(); _o->hp = _e; };
@ -1058,20 +1087,20 @@ inline MonsterT *Monster::UnPack(const flatbuffers::resolver_function_t *resolve
{ auto _e = inventory(); if (_e) for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->inventory.push_back(_e->Get(_i)); } };
{ auto _e = color(); _o->color = _e; };
{ auto _e = test_type(); _o->test.type = _e; };
{ auto _e = test(); if (_e) _o->test.table = AnyUnion::UnPack(_e, test_type(),resolver); };
{ auto _e = test(); if (_e) _o->test.table = AnyUnion::UnPack(_e, test_type(),_resolver); };
{ auto _e = test4(); if (_e) for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->test4.push_back(*_e->Get(_i)); } };
{ auto _e = testarrayofstring(); if (_e) for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofstring.push_back(_e->Get(_i)->str()); } };
{ auto _e = testarrayoftables(); if (_e) for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayoftables.push_back(std::unique_ptr<MonsterT>(_e->Get(_i)->UnPack(resolver))); } };
{ auto _e = enemy(); if (_e) _o->enemy = std::unique_ptr<MonsterT>(_e->UnPack(resolver)); };
{ auto _e = testarrayoftables(); if (_e) for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayoftables.push_back(std::unique_ptr<MonsterT>(_e->Get(_i)->UnPack(_resolver))); } };
{ auto _e = enemy(); if (_e) _o->enemy = std::unique_ptr<MonsterT>(_e->UnPack(_resolver)); };
{ auto _e = testnestedflatbuffer(); if (_e) for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testnestedflatbuffer.push_back(_e->Get(_i)); } };
{ auto _e = testempty(); if (_e) _o->testempty = std::unique_ptr<StatT>(_e->UnPack(resolver)); };
{ auto _e = testempty(); if (_e) _o->testempty = std::unique_ptr<StatT>(_e->UnPack(_resolver)); };
{ auto _e = testbool(); _o->testbool = _e; };
{ auto _e = testhashs32_fnv1(); _o->testhashs32_fnv1 = _e; };
{ auto _e = testhashu32_fnv1(); _o->testhashu32_fnv1 = _e; };
{ auto _e = testhashs64_fnv1(); _o->testhashs64_fnv1 = _e; };
{ auto _e = testhashu64_fnv1(); _o->testhashu64_fnv1 = _e; };
{ auto _e = testhashs32_fnv1a(); _o->testhashs32_fnv1a = _e; };
{ auto _e = testhashu32_fnv1a(); if (resolver) (*resolver)(reinterpret_cast<void **>(&_o->testhashu32_fnv1a), static_cast<flatbuffers::hash_value_t>(_e)); else _o->testhashu32_fnv1a = nullptr; };
{ auto _e = testhashu32_fnv1a(); if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->testhashu32_fnv1a), static_cast<flatbuffers::hash_value_t>(_e)); else _o->testhashu32_fnv1a = nullptr; };
{ auto _e = testhashs64_fnv1a(); _o->testhashs64_fnv1a = _e; };
{ auto _e = testhashu64_fnv1a(); _o->testhashu64_fnv1a = _e; };
{ auto _e = testarrayofbools(); if (_e) for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofbools.push_back(_e->Get(_i) != 0); } };
@ -1079,7 +1108,6 @@ inline MonsterT *Monster::UnPack(const flatbuffers::resolver_function_t *resolve
{ auto _e = testf2(); _o->testf2 = _e; };
{ auto _e = testf3(); _o->testf3 = _e; };
{ auto _e = testarrayofstring2(); if (_e) for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofstring2.push_back(_e->Get(_i)->str()); } };
return _o;
}
inline flatbuffers::Offset<Monster> Monster::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
@ -1089,36 +1117,64 @@ inline flatbuffers::Offset<Monster> Monster::Pack(flatbuffers::FlatBufferBuilder
inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
(void)_rehasher;
(void)_o;
auto _pos = _o->pos ? _o->pos.get() : 0;
auto _mana = _o->mana;
auto _hp = _o->hp;
auto _name = _fbb.CreateString(_o->name);
auto _inventory = _o->inventory.size() ? _fbb.CreateVector(_o->inventory) : 0;
auto _color = _o->color;
auto _test_type = _o->test.type;
auto _test = _o->test.Pack(_fbb);
auto _test4 = _o->test4.size() ? _fbb.CreateVectorOfStructs(_o->test4) : 0;
auto _testarrayofstring = _o->testarrayofstring.size() ? _fbb.CreateVectorOfStrings(_o->testarrayofstring) : 0;
auto _testarrayoftables = _o->testarrayoftables.size() ? _fbb.CreateVector<flatbuffers::Offset<Monster>>(_o->testarrayoftables.size(), [&](size_t i) { return CreateMonster(_fbb, _o->testarrayoftables[i].get(), _rehasher); }) : 0;
auto _enemy = _o->enemy ? CreateMonster(_fbb, _o->enemy.get(), _rehasher) : 0;
auto _testnestedflatbuffer = _o->testnestedflatbuffer.size() ? _fbb.CreateVector(_o->testnestedflatbuffer) : 0;
auto _testempty = _o->testempty ? CreateStat(_fbb, _o->testempty.get(), _rehasher) : 0;
auto _testbool = _o->testbool;
auto _testhashs32_fnv1 = _o->testhashs32_fnv1;
auto _testhashu32_fnv1 = _o->testhashu32_fnv1;
auto _testhashs64_fnv1 = _o->testhashs64_fnv1;
auto _testhashu64_fnv1 = _o->testhashu64_fnv1;
auto _testhashs32_fnv1a = _o->testhashs32_fnv1a;
auto _testhashu32_fnv1a = _rehasher ? static_cast<uint32_t>((*_rehasher)(_o->testhashu32_fnv1a)) : 0;
auto _testhashs64_fnv1a = _o->testhashs64_fnv1a;
auto _testhashu64_fnv1a = _o->testhashu64_fnv1a;
auto _testarrayofbools = _o->testarrayofbools.size() ? _fbb.CreateVector(_o->testarrayofbools) : 0;
auto _testf = _o->testf;
auto _testf2 = _o->testf2;
auto _testf3 = _o->testf3;
auto _testarrayofstring2 = _o->testarrayofstring2.size() ? _fbb.CreateVectorOfStrings(_o->testarrayofstring2) : 0;
return CreateMonster(
_fbb,
_o->pos ? _o->pos.get() : 0,
_o->mana,
_o->hp,
_fbb.CreateString(_o->name),
_o->inventory.size() ? _fbb.CreateVector(_o->inventory) : 0,
_o->color,
_o->test.type,
_o->test.Pack(_fbb),
_o->test4.size() ? _fbb.CreateVectorOfStructs(_o->test4) : 0,
_o->testarrayofstring.size() ? _fbb.CreateVectorOfStrings(_o->testarrayofstring) : 0,
_o->testarrayoftables.size() ? _fbb.CreateVector<flatbuffers::Offset<Monster>>(_o->testarrayoftables.size(), [&](size_t i) { return CreateMonster(_fbb, _o->testarrayoftables[i].get(), _rehasher); }) : 0,
_o->enemy ? CreateMonster(_fbb, _o->enemy.get(), _rehasher) : 0,
_o->testnestedflatbuffer.size() ? _fbb.CreateVector(_o->testnestedflatbuffer) : 0,
_o->testempty ? CreateStat(_fbb, _o->testempty.get(), _rehasher) : 0,
_o->testbool,
_o->testhashs32_fnv1,
_o->testhashu32_fnv1,
_o->testhashs64_fnv1,
_o->testhashu64_fnv1,
_o->testhashs32_fnv1a,
_rehasher ? static_cast<uint32_t>((*_rehasher)(_o->testhashu32_fnv1a)) : 0,
_o->testhashs64_fnv1a,
_o->testhashu64_fnv1a,
_o->testarrayofbools.size() ? _fbb.CreateVector(_o->testarrayofbools) : 0,
_o->testf,
_o->testf2,
_o->testf3,
_o->testarrayofstring2.size() ? _fbb.CreateVectorOfStrings(_o->testarrayofstring2) : 0);
_pos,
_mana,
_hp,
_name,
_inventory,
_color,
_test_type,
_test,
_test4,
_testarrayofstring,
_testarrayoftables,
_enemy,
_testnestedflatbuffer,
_testempty,
_testbool,
_testhashs32_fnv1,
_testhashu32_fnv1,
_testhashs64_fnv1,
_testhashu64_fnv1,
_testhashs32_fnv1a,
_testhashu32_fnv1a,
_testhashs64_fnv1a,
_testhashu64_fnv1a,
_testarrayofbools,
_testf,
_testf2,
_testf3,
_testarrayofstring2);
}
inline bool VerifyAny(flatbuffers::Verifier &verifier, const void *obj, Any type) {