forked from BigfootDev/flatbuffers
Added support for mini-reflection tables.
Change-Id: I83453d074685fa57bbf1c7c87b1d9392ce972085 Tested: on Linux.
This commit is contained in:
@@ -34,6 +34,7 @@ set(FlatBuffers_Library_SRCS
|
||||
include/flatbuffers/stl_emulation.h
|
||||
include/flatbuffers/flexbuffers.h
|
||||
include/flatbuffers/registry.h
|
||||
include/flatbuffers/minireflect.h
|
||||
src/code_generators.cpp
|
||||
src/idl_parser.cpp
|
||||
src/idl_gen_text.cpp
|
||||
@@ -200,6 +201,7 @@ function(compile_flatbuffers_schema_to_cpp SRC_FBS)
|
||||
COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}" -c --no-includes --gen-mutable
|
||||
--gen-object-api -o "${SRC_FBS_DIR}"
|
||||
--cpp-ptr-type flatbuffers::unique_ptr # Used to test with C++98 STLs
|
||||
--reflect-names
|
||||
-I "${CMAKE_CURRENT_SOURCE_DIR}/tests/include_test"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}"
|
||||
DEPENDS flatc)
|
||||
|
||||
@@ -125,5 +125,8 @@ Additional options:
|
||||
|
||||
- `--keep-prefix` : Keep original prefix of schema include statement.
|
||||
|
||||
- `--reflect-types` : Add minimal type reflection to code generation.
|
||||
- `--reflect-names` : Add minimal type/name reflection.
|
||||
|
||||
NOTE: short-form options for generators are deprecated, use the long form
|
||||
whenever possible.
|
||||
|
||||
@@ -231,6 +231,30 @@ schema, as well as a lot of helper functions.
|
||||
And example of usage, for the time being, can be found in
|
||||
`test.cpp/ReflectionTest()`.
|
||||
|
||||
## Mini Reflection
|
||||
|
||||
A more limited form of reflection is available for direct inclusion in
|
||||
generated code, which doesn't any (binary) schema access at all. It was designed
|
||||
to keep the overhead of reflection as low as possible (on the order of 2-6
|
||||
bytes per field added to your executable), but doesn't contain all the
|
||||
information the (binary) schema contains.
|
||||
|
||||
You add this information to your generated code by specifying `--reflect-types`
|
||||
(or instead `--reflect-names` if you also want field / enum names).
|
||||
|
||||
You can now use this information, for example to print a FlatBuffer to text:
|
||||
|
||||
auto s = flatbuffers::FlatBufferToString(flatbuf, MonsterTypeTable());
|
||||
|
||||
`MonsterTypeTable()` is declared in the generated code for each type. The
|
||||
string produced is very similar to the JSON produced by the `Parser` based
|
||||
text generator.
|
||||
|
||||
You'll need `flatbuffers/minireflect.h` for this functionality. In there is also
|
||||
a convenient visitor/iterator so you can write your own output / functionality
|
||||
based on the mini reflection tables without having to know the FlatBuffers or
|
||||
reflection encoding.
|
||||
|
||||
## Storing maps / dictionaries in a FlatBuffer
|
||||
|
||||
FlatBuffers doesn't support maps natively, but there is support to
|
||||
|
||||
@@ -2066,6 +2066,73 @@ inline int LookupEnum(const char **names, const char *name) {
|
||||
#error Unknown compiler, please define structure alignment macros
|
||||
#endif
|
||||
|
||||
// Minimal reflection via code generation.
|
||||
// Besides full-fat reflection (see reflection.h) and parsing/printing by
|
||||
// loading schemas (see idl.h), we can also have code generation for mimimal
|
||||
// reflection data which allows pretty-printing and other uses without needing
|
||||
// a schema or a parser.
|
||||
// Generate code with --reflect-types (types only) or --reflect-names (names
|
||||
// also) to enable.
|
||||
// See minireflect.h for utilities using this functionality.
|
||||
|
||||
// These types are organized slightly differently as the ones in idl.h.
|
||||
enum SequenceType { ST_TABLE, ST_STRUCT, ST_UNION, ST_ENUM };
|
||||
|
||||
// Scalars have the same order as in idl.h
|
||||
#define FLATBUFFERS_GEN_ELEMENTARY_TYPES(ET) \
|
||||
ET(ET_UTYPE) \
|
||||
ET(ET_BOOL) \
|
||||
ET(ET_CHAR) \
|
||||
ET(ET_UCHAR) \
|
||||
ET(ET_SHORT) \
|
||||
ET(ET_USHORT) \
|
||||
ET(ET_INT) \
|
||||
ET(ET_UINT) \
|
||||
ET(ET_LONG) \
|
||||
ET(ET_ULONG) \
|
||||
ET(ET_FLOAT) \
|
||||
ET(ET_DOUBLE) \
|
||||
ET(ET_STRING) \
|
||||
ET(ET_SEQUENCE) // See SequenceType.
|
||||
|
||||
enum ElementaryType {
|
||||
#define FLATBUFFERS_ET(E) E,
|
||||
FLATBUFFERS_GEN_ELEMENTARY_TYPES(FLATBUFFERS_ET)
|
||||
#undef FLATBUFFERS_ET
|
||||
};
|
||||
|
||||
inline const char **ElementaryTypeNames() {
|
||||
static const char *names[] = {
|
||||
#define FLATBUFFERS_ET(E) #E,
|
||||
FLATBUFFERS_GEN_ELEMENTARY_TYPES(FLATBUFFERS_ET)
|
||||
#undef FLATBUFFERS_ET
|
||||
};
|
||||
return names;
|
||||
}
|
||||
|
||||
// Basic type info cost just 16bits per field!
|
||||
struct TypeCode {
|
||||
uint16_t base_type : 4; // ElementaryType
|
||||
uint16_t is_vector : 1;
|
||||
int16_t sequence_ref : 11; // Index into type_refs below, or -1 for none.
|
||||
};
|
||||
|
||||
static_assert(sizeof(TypeCode) == 2, "TypeCode");
|
||||
|
||||
struct TypeTable;
|
||||
|
||||
// Signature of the static method present in each type.
|
||||
typedef TypeTable *(*TypeFunction)();
|
||||
|
||||
struct TypeTable {
|
||||
SequenceType st;
|
||||
size_t num_elems; // of each of the arrays below.
|
||||
const TypeCode *type_codes;
|
||||
const TypeFunction *type_refs;
|
||||
const int32_t *values; // Only set for non-consecutive enum/union or structs.
|
||||
const char **names; // Only set if compiled with --reflect-names.
|
||||
};
|
||||
|
||||
// String which identifies the current version of FlatBuffers.
|
||||
// flatbuffer_version_string is used by Google developers to identify which
|
||||
// applications uploaded to Google Play are using this library. This allows
|
||||
|
||||
@@ -396,6 +396,10 @@ struct IDLOptions {
|
||||
|
||||
Language lang;
|
||||
|
||||
enum MiniReflect { kNone, kTypes, kTypesAndNames };
|
||||
|
||||
MiniReflect mini_reflect;
|
||||
|
||||
// The corresponding language bit will be set if a language is included
|
||||
// for code generation.
|
||||
unsigned long lang_to_generate;
|
||||
@@ -426,6 +430,7 @@ struct IDLOptions {
|
||||
reexport_ts_modules(true),
|
||||
protobuf_ascii_alike(false),
|
||||
lang(IDLOptions::kJava),
|
||||
mini_reflect(IDLOptions::kNone),
|
||||
lang_to_generate(0) {}
|
||||
};
|
||||
|
||||
|
||||
352
include/flatbuffers/minireflect.h
Normal file
352
include/flatbuffers/minireflect.h
Normal file
@@ -0,0 +1,352 @@
|
||||
/*
|
||||
* Copyright 2017 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FLATBUFFERS_MINIREFLECT_H_
|
||||
#define FLATBUFFERS_MINIREFLECT_H_
|
||||
|
||||
#include "flatbuffers/flatbuffers.h"
|
||||
#include "flatbuffers/util.h"
|
||||
|
||||
namespace flatbuffers {
|
||||
|
||||
// Utilities that can be used with the "mini reflection" tables present
|
||||
// in generated code with --reflect-types (only types) or --reflect-names
|
||||
// (also names).
|
||||
// This allows basic reflection functionality such as pretty-printing
|
||||
// that does not require the use of the schema parser or loading of binary
|
||||
// schema files at runtime (reflection.h).
|
||||
|
||||
// For any of the functions below that take `const TypeTable *`, you pass
|
||||
// `FooTypeTable()` if the type of the root is `Foo`.
|
||||
|
||||
// First, a generic iterator that can be used by multiple algorithms.
|
||||
|
||||
struct IterationVisitor {
|
||||
// These mark the scope of a table or struct.
|
||||
virtual void StartSequence() {}
|
||||
virtual void EndSequence() {}
|
||||
// Called for each field regardless of wether it is present or not.
|
||||
// If not present, val == nullptr. set_idx is the index of all set fields.
|
||||
virtual void Field(size_t /*field_idx*/, size_t /*set_idx*/,
|
||||
ElementaryType /*type*/, bool /*is_vector*/,
|
||||
const TypeTable * /*type_table*/, const char * /*name*/,
|
||||
const uint8_t * /*val*/) {}
|
||||
// Called for a value that is actually present, after a field, or as part
|
||||
// of a vector.
|
||||
virtual void UType(uint8_t, const char *) {}
|
||||
virtual void Bool(bool) {}
|
||||
virtual void Char(int8_t, const char *) {}
|
||||
virtual void UChar(uint8_t, const char *) {}
|
||||
virtual void Short(int16_t, const char *) {}
|
||||
virtual void UShort(uint16_t, const char *) {}
|
||||
virtual void Int(int32_t, const char *) {}
|
||||
virtual void UInt(uint32_t, const char *) {}
|
||||
virtual void Long(int64_t) {}
|
||||
virtual void ULong(uint64_t) {}
|
||||
virtual void Float(float) {}
|
||||
virtual void Double(double) {}
|
||||
virtual void String(const String *) {}
|
||||
virtual void Unknown(const uint8_t *) {} // From a future version.
|
||||
// These mark the scope of a vector.
|
||||
virtual void StartVector() {}
|
||||
virtual void EndVector() {}
|
||||
virtual void Element(size_t /*i*/, ElementaryType /*type*/,
|
||||
const TypeTable * /*type_table*/,
|
||||
const uint8_t * /*val*/)
|
||||
{}
|
||||
virtual ~IterationVisitor() {}
|
||||
};
|
||||
|
||||
inline size_t InlineSize(ElementaryType type, const TypeTable *type_table) {
|
||||
switch (type) {
|
||||
case ET_UTYPE:
|
||||
case ET_BOOL:
|
||||
case ET_CHAR:
|
||||
case ET_UCHAR:
|
||||
return 1;
|
||||
case ET_SHORT:
|
||||
case ET_USHORT:
|
||||
return 2;
|
||||
case ET_INT:
|
||||
case ET_UINT:
|
||||
case ET_FLOAT:
|
||||
case ET_STRING:
|
||||
return 4;
|
||||
case ET_LONG:
|
||||
case ET_ULONG:
|
||||
case ET_DOUBLE:
|
||||
return 8;
|
||||
case ET_SEQUENCE:
|
||||
switch (type_table->st) {
|
||||
case ST_TABLE:
|
||||
case ST_UNION:
|
||||
return 4;
|
||||
case ST_STRUCT:
|
||||
return type_table->values[type_table->num_elems];
|
||||
default:
|
||||
assert(false);
|
||||
return 1;
|
||||
}
|
||||
default:
|
||||
assert(false);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
inline int32_t LookupEnum(int32_t enum_val, const int32_t *values,
|
||||
size_t num_values) {
|
||||
if (!values) return enum_val;
|
||||
for (size_t i = 0; i < num_values; i++) {
|
||||
if (enum_val == values[i]) return static_cast<int32_t>(i);
|
||||
}
|
||||
return -1; // Unknown enum value.
|
||||
}
|
||||
|
||||
template<typename T> const char *EnumName(T tval, const TypeTable *type_table) {
|
||||
if (!type_table || !type_table->names) return nullptr;
|
||||
auto i = LookupEnum(static_cast<int32_t>(tval), type_table->values,
|
||||
type_table->num_elems);
|
||||
if (i >= 0 && i < static_cast<int32_t>(type_table->num_elems)) {
|
||||
return type_table->names[i];
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void IterateObject(const uint8_t *obj, const TypeTable *type_table,
|
||||
IterationVisitor *visitor);
|
||||
|
||||
inline void IterateValue(ElementaryType type, const uint8_t *val,
|
||||
const TypeTable *type_table,
|
||||
const uint8_t *prev_val,
|
||||
soffset_t vector_index,
|
||||
IterationVisitor *visitor) {
|
||||
switch (type) {
|
||||
case ET_UTYPE: {
|
||||
auto tval = *reinterpret_cast<const uint8_t *>(val);
|
||||
visitor->UType(tval, EnumName(tval, type_table));
|
||||
break;
|
||||
}
|
||||
case ET_BOOL: {
|
||||
visitor->Bool(*reinterpret_cast<const uint8_t *>(val) != 0);
|
||||
break;
|
||||
}
|
||||
case ET_CHAR: {
|
||||
auto tval = *reinterpret_cast<const int8_t *>(val);
|
||||
visitor->Char(tval, EnumName(tval, type_table));
|
||||
break;
|
||||
}
|
||||
case ET_UCHAR: {
|
||||
auto tval = *reinterpret_cast<const uint8_t *>(val);
|
||||
visitor->UChar(tval, EnumName(tval, type_table));
|
||||
break;
|
||||
}
|
||||
case ET_SHORT: {
|
||||
auto tval = *reinterpret_cast<const int16_t *>(val);
|
||||
visitor->Short(tval, EnumName(tval, type_table));
|
||||
break;
|
||||
}
|
||||
case ET_USHORT: {
|
||||
auto tval = *reinterpret_cast<const uint16_t *>(val);
|
||||
visitor->UShort(tval, EnumName(tval, type_table));
|
||||
break;
|
||||
}
|
||||
case ET_INT: {
|
||||
auto tval = *reinterpret_cast<const int32_t *>(val);
|
||||
visitor->Int(tval, EnumName(tval, type_table));
|
||||
break;
|
||||
}
|
||||
case ET_UINT: {
|
||||
auto tval = *reinterpret_cast<const uint32_t *>(val);
|
||||
visitor->UInt(tval, EnumName(tval, type_table));
|
||||
break;
|
||||
}
|
||||
case ET_LONG: {
|
||||
visitor->Long(*reinterpret_cast<const int64_t *>(val));
|
||||
break;
|
||||
}
|
||||
case ET_ULONG: {
|
||||
visitor->ULong(*reinterpret_cast<const uint64_t *>(val));
|
||||
break;
|
||||
}
|
||||
case ET_FLOAT: {
|
||||
visitor->Float(*reinterpret_cast<const float *>(val));
|
||||
break;
|
||||
}
|
||||
case ET_DOUBLE: {
|
||||
visitor->Double(*reinterpret_cast<const double *>(val));
|
||||
break;
|
||||
}
|
||||
case ET_STRING: {
|
||||
val += ReadScalar<uoffset_t>(val);
|
||||
visitor->String(reinterpret_cast<const String *>(val));
|
||||
break;
|
||||
}
|
||||
case ET_SEQUENCE: {
|
||||
switch (type_table->st) {
|
||||
case ST_TABLE:
|
||||
val += ReadScalar<uoffset_t>(val);
|
||||
IterateObject(val, type_table, visitor);
|
||||
break;
|
||||
case ST_STRUCT:
|
||||
IterateObject(val, type_table, visitor);
|
||||
break;
|
||||
case ST_UNION: {
|
||||
val += ReadScalar<uoffset_t>(val);
|
||||
assert(prev_val);
|
||||
auto union_type = *prev_val; // Always a uint8_t.
|
||||
if (vector_index >= 0) {
|
||||
auto type_vec = reinterpret_cast<const Vector<uint8_t> *>(prev_val);
|
||||
union_type = type_vec->Get(static_cast<uoffset_t>(vector_index));
|
||||
}
|
||||
auto type_code_idx = LookupEnum(union_type, type_table->values,
|
||||
type_table->num_elems);
|
||||
if (type_code_idx >= 0 && type_code_idx <
|
||||
static_cast<int32_t>(type_table->num_elems)) {
|
||||
auto type_code = type_table->type_codes[type_code_idx];
|
||||
switch (type_code.base_type) {
|
||||
case ET_SEQUENCE: {
|
||||
auto ref = type_table->type_refs[type_code.sequence_ref]();
|
||||
IterateObject(val, ref, visitor);
|
||||
break;
|
||||
}
|
||||
case ET_STRING:
|
||||
visitor->String(reinterpret_cast<const String *>(val));
|
||||
break;
|
||||
default:
|
||||
visitor->Unknown(val);
|
||||
}
|
||||
} else {
|
||||
visitor->Unknown(val);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ST_ENUM:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
visitor->Unknown(val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void IterateObject(const uint8_t *obj, const TypeTable *type_table,
|
||||
IterationVisitor *visitor) {
|
||||
visitor->StartSequence();
|
||||
const uint8_t *prev_val = nullptr;
|
||||
size_t set_idx = 0;
|
||||
for (size_t i = 0; i < type_table->num_elems; i++) {
|
||||
auto type_code = type_table->type_codes[i];
|
||||
auto type = static_cast<ElementaryType>(type_code.base_type);
|
||||
auto is_vector = type_code.is_vector != 0;
|
||||
auto ref_idx = type_code.sequence_ref;
|
||||
const TypeTable *ref = nullptr;
|
||||
if (ref_idx >= 0) {
|
||||
ref = type_table->type_refs[ref_idx]();
|
||||
}
|
||||
auto name = type_table->names ? type_table->names[i] : nullptr;
|
||||
const uint8_t *val = nullptr;
|
||||
if (type_table->st == ST_TABLE) {
|
||||
val = reinterpret_cast<const Table *>(obj)->GetAddressOf(
|
||||
FieldIndexToOffset(static_cast<voffset_t>(i)));
|
||||
} else {
|
||||
val = obj + type_table->values[i];
|
||||
}
|
||||
visitor->Field(i, set_idx, type, is_vector, ref, name, val);
|
||||
if (val) {
|
||||
set_idx++;
|
||||
if (is_vector) {
|
||||
val += ReadScalar<uoffset_t>(val);
|
||||
auto vec = reinterpret_cast<const Vector<uint8_t> *>(val);
|
||||
visitor->StartVector();
|
||||
auto elem_ptr = vec->Data();
|
||||
for (size_t j = 0; j < vec->size(); j++) {
|
||||
visitor->Element(j, type, ref, elem_ptr);
|
||||
IterateValue(type, elem_ptr, ref, prev_val, static_cast<soffset_t>(j),
|
||||
visitor);
|
||||
elem_ptr += InlineSize(type, ref);
|
||||
}
|
||||
visitor->EndVector();
|
||||
} else {
|
||||
IterateValue(type, val, ref, prev_val, -1, visitor);
|
||||
}
|
||||
}
|
||||
prev_val = val;
|
||||
}
|
||||
visitor->EndSequence();
|
||||
}
|
||||
|
||||
inline void IterateFlatBuffer(const uint8_t *buffer,
|
||||
const TypeTable *type_table,
|
||||
IterationVisitor *callback) {
|
||||
IterateObject(GetRoot<uint8_t>(buffer), type_table, callback);
|
||||
}
|
||||
|
||||
// Outputting a Flatbuffer to a string. Tries to conform as close to JSON /
|
||||
// the output generated by idl_gen_text.cpp.
|
||||
|
||||
struct ToStringVisitor : public IterationVisitor {
|
||||
std::string s;
|
||||
void StartSequence() { s += "{ "; }
|
||||
void EndSequence() { s += " }"; }
|
||||
void Field(size_t /*field_idx*/, size_t set_idx, ElementaryType /*type*/,
|
||||
bool /*is_vector*/, const TypeTable * /*type_table*/,
|
||||
const char *name, const uint8_t *val) {
|
||||
if (!val) return;
|
||||
if (set_idx) s += ", ";
|
||||
if (name) { s += name; s += ": "; }
|
||||
}
|
||||
template<typename T> void Named(T x, const char *name) {
|
||||
if (name) s+= name;
|
||||
else s+= NumToString(x);
|
||||
}
|
||||
void UType(uint8_t x, const char *name) { Named(x, name); }
|
||||
void Bool(bool x) { s+= x ? "true" : "false"; }
|
||||
void Char(int8_t x, const char *name) { Named(x, name); }
|
||||
void UChar(uint8_t x, const char *name) { Named(x, name); }
|
||||
void Short(int16_t x, const char *name) { Named(x, name); }
|
||||
void UShort(uint16_t x, const char *name) { Named(x, name); }
|
||||
void Int(int32_t x, const char *name) { Named(x, name); }
|
||||
void UInt(uint32_t x, const char *name) { Named(x, name); }
|
||||
void Long(int64_t x) { s+= NumToString(x); }
|
||||
void ULong(uint64_t x) { s+= NumToString(x); }
|
||||
void Float(float x) { s+= NumToString(x); }
|
||||
void Double(double x) { s+= NumToString(x); }
|
||||
void String(const struct String *str) {
|
||||
EscapeString(str->c_str(), str->size(), &s, true);
|
||||
}
|
||||
void Unknown(const uint8_t *) { s += "(?)"; }
|
||||
void StartVector() { s += "[ "; }
|
||||
void EndVector() { s += " ]"; }
|
||||
void Element(size_t i, ElementaryType /*type*/,
|
||||
const TypeTable * /*type_table*/, const uint8_t * /*val*/) {
|
||||
if (i) s += ", ";
|
||||
}
|
||||
};
|
||||
|
||||
inline std::string FlatBufferToString(const uint8_t *buffer,
|
||||
const TypeTable *type_table) {
|
||||
ToStringVisitor tostring_visitor;
|
||||
IterateFlatBuffer(buffer, type_table, &tostring_visitor);
|
||||
return tostring_visitor.s;
|
||||
}
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
#endif // FLATBUFFERS_MINIREFLECT_H_
|
||||
@@ -605,6 +605,120 @@ inline void EquipmentUnion::Reset() {
|
||||
type = Equipment_NONE;
|
||||
}
|
||||
|
||||
flatbuffers::TypeTable *Vec3TypeTable();
|
||||
|
||||
flatbuffers::TypeTable *MonsterTypeTable();
|
||||
|
||||
flatbuffers::TypeTable *WeaponTypeTable();
|
||||
|
||||
flatbuffers::TypeTable *ColorTypeTable() {
|
||||
static flatbuffers::TypeCode type_codes[] = {
|
||||
{ flatbuffers::ET_CHAR, 0, 0 },
|
||||
{ flatbuffers::ET_CHAR, 0, 0 },
|
||||
{ flatbuffers::ET_CHAR, 0, 0 }
|
||||
};
|
||||
static flatbuffers::TypeFunction type_refs[] = {
|
||||
ColorTypeTable
|
||||
};
|
||||
static const char *names[] = {
|
||||
"Red",
|
||||
"Green",
|
||||
"Blue"
|
||||
};
|
||||
static flatbuffers::TypeTable tt = {
|
||||
flatbuffers::ST_ENUM, 3, type_codes, type_refs, nullptr, names
|
||||
};
|
||||
return &tt;
|
||||
}
|
||||
|
||||
flatbuffers::TypeTable *EquipmentTypeTable() {
|
||||
static flatbuffers::TypeCode type_codes[] = {
|
||||
{ flatbuffers::ET_SEQUENCE, 0, -1 },
|
||||
{ flatbuffers::ET_SEQUENCE, 0, 0 }
|
||||
};
|
||||
static flatbuffers::TypeFunction type_refs[] = {
|
||||
WeaponTypeTable
|
||||
};
|
||||
static const char *names[] = {
|
||||
"NONE",
|
||||
"Weapon"
|
||||
};
|
||||
static flatbuffers::TypeTable tt = {
|
||||
flatbuffers::ST_UNION, 2, type_codes, type_refs, nullptr, names
|
||||
};
|
||||
return &tt;
|
||||
}
|
||||
|
||||
flatbuffers::TypeTable *Vec3TypeTable() {
|
||||
static flatbuffers::TypeCode type_codes[] = {
|
||||
{ flatbuffers::ET_FLOAT, 0, -1 },
|
||||
{ flatbuffers::ET_FLOAT, 0, -1 },
|
||||
{ flatbuffers::ET_FLOAT, 0, -1 }
|
||||
};
|
||||
static const int32_t values[] = { 0, 4, 8, 12 };
|
||||
static const char *names[] = {
|
||||
"x",
|
||||
"y",
|
||||
"z"
|
||||
};
|
||||
static flatbuffers::TypeTable tt = {
|
||||
flatbuffers::ST_STRUCT, 3, type_codes, nullptr, values, names
|
||||
};
|
||||
return &tt;
|
||||
}
|
||||
|
||||
flatbuffers::TypeTable *MonsterTypeTable() {
|
||||
static flatbuffers::TypeCode type_codes[] = {
|
||||
{ flatbuffers::ET_SEQUENCE, 0, 0 },
|
||||
{ flatbuffers::ET_SHORT, 0, -1 },
|
||||
{ flatbuffers::ET_SHORT, 0, -1 },
|
||||
{ flatbuffers::ET_STRING, 0, -1 },
|
||||
{ flatbuffers::ET_BOOL, 0, -1 },
|
||||
{ flatbuffers::ET_UCHAR, 1, -1 },
|
||||
{ flatbuffers::ET_CHAR, 0, 1 },
|
||||
{ flatbuffers::ET_SEQUENCE, 1, 2 },
|
||||
{ flatbuffers::ET_UTYPE, 0, 3 },
|
||||
{ flatbuffers::ET_SEQUENCE, 0, 3 }
|
||||
};
|
||||
static flatbuffers::TypeFunction type_refs[] = {
|
||||
Vec3TypeTable,
|
||||
ColorTypeTable,
|
||||
WeaponTypeTable,
|
||||
EquipmentTypeTable
|
||||
};
|
||||
static const char *names[] = {
|
||||
"pos",
|
||||
"mana",
|
||||
"hp",
|
||||
"name",
|
||||
"friendly",
|
||||
"inventory",
|
||||
"color",
|
||||
"weapons",
|
||||
"equipped_type",
|
||||
"equipped"
|
||||
};
|
||||
static flatbuffers::TypeTable tt = {
|
||||
flatbuffers::ST_TABLE, 10, type_codes, type_refs, nullptr, names
|
||||
};
|
||||
return &tt;
|
||||
}
|
||||
|
||||
flatbuffers::TypeTable *WeaponTypeTable() {
|
||||
static flatbuffers::TypeCode type_codes[] = {
|
||||
{ flatbuffers::ET_STRING, 0, -1 },
|
||||
{ flatbuffers::ET_SHORT, 0, -1 }
|
||||
};
|
||||
static const char *names[] = {
|
||||
"name",
|
||||
"damage"
|
||||
};
|
||||
static flatbuffers::TypeTable tt = {
|
||||
flatbuffers::ST_TABLE, 2, type_codes, nullptr, nullptr, names
|
||||
};
|
||||
return &tt;
|
||||
}
|
||||
|
||||
inline const MyGame::Sample::Monster *GetMonster(const void *buf) {
|
||||
return flatbuffers::GetRoot<MyGame::Sample::Monster>(buf);
|
||||
}
|
||||
|
||||
@@ -111,6 +111,8 @@ std::string FlatCompiler::GetUsageString(const char* program_name) const {
|
||||
" --keep-prefix Keep original prefix of schema include statement.\n"
|
||||
" --no-fb-import Don't include flatbuffers import statement for TypeScript.\n"
|
||||
" --no-ts-reexport Don't re-export imported dependencies for TypeScript.\n"
|
||||
" --reflect-types Add minimal type reflection to code generation.\n"
|
||||
" --reflect-names Add minimal type/name reflection.\n"
|
||||
"FILEs may be schemas (must end in .fbs), or JSON files (conforming to preceding\n"
|
||||
"schema). FILEs after the -- must be binary flatbuffer format files.\n"
|
||||
"Output files are named using the base file name of the input,\n"
|
||||
@@ -243,6 +245,10 @@ int FlatCompiler::Compile(int argc, const char** argv) {
|
||||
opts.skip_flatbuffers_import = true;
|
||||
} else if(arg == "--no-ts-reexport") {
|
||||
opts.reexport_ts_modules = false;
|
||||
} else if(arg == "--reflect-types") {
|
||||
opts.mini_reflect = IDLOptions::kTypes;
|
||||
} else if(arg == "--reflect-names") {
|
||||
opts.mini_reflect = IDLOptions::kTypesAndNames;
|
||||
} else {
|
||||
for (size_t i = 0; i < params_.num_generators; ++i) {
|
||||
if (arg == params_.generators[i].generator_opt_long ||
|
||||
|
||||
@@ -169,6 +169,37 @@ class CppGenerator : public BaseGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
// Generate code for mini reflection.
|
||||
if (parser_.opts.mini_reflect != IDLOptions::kNone) {
|
||||
// To break cyclic dependencies, first pre-declare all tables/structs.
|
||||
for (auto it = parser_.structs_.vec.begin();
|
||||
it != parser_.structs_.vec.end(); ++it) {
|
||||
const auto &struct_def = **it;
|
||||
if (!struct_def.generated) {
|
||||
SetNameSpace(struct_def.defined_namespace);
|
||||
GenMiniReflectPre(&struct_def);
|
||||
}
|
||||
}
|
||||
// Then the unions/enums that may refer to them.
|
||||
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
|
||||
++it) {
|
||||
const auto &enum_def = **it;
|
||||
if (!enum_def.generated) {
|
||||
SetNameSpace(enum_def.defined_namespace);
|
||||
GenMiniReflect(nullptr, &enum_def);
|
||||
}
|
||||
}
|
||||
// Then the full tables/structs.
|
||||
for (auto it = parser_.structs_.vec.begin();
|
||||
it != parser_.structs_.vec.end(); ++it) {
|
||||
const auto &struct_def = **it;
|
||||
if (!struct_def.generated) {
|
||||
SetNameSpace(struct_def.defined_namespace);
|
||||
GenMiniReflect(&struct_def, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Generate convenient global helper functions:
|
||||
if (parser_.root_struct_def_) {
|
||||
auto &struct_def = *parser_.root_struct_def_;
|
||||
@@ -559,6 +590,140 @@ class CppGenerator : public BaseGenerator {
|
||||
(inclass ? " = nullptr" : "") + ") const";
|
||||
}
|
||||
|
||||
void GenMiniReflectPre(const StructDef *struct_def) {
|
||||
code_.SetValue("NAME", struct_def->name);
|
||||
code_ += "flatbuffers::TypeTable *{{NAME}}TypeTable();";
|
||||
code_ += "";
|
||||
}
|
||||
|
||||
void GenMiniReflect(const StructDef *struct_def,
|
||||
const EnumDef *enum_def) {
|
||||
code_.SetValue("NAME", struct_def ? struct_def->name : enum_def->name);
|
||||
code_.SetValue("SEQ_TYPE", struct_def
|
||||
? (struct_def->fixed ? "ST_STRUCT" : "ST_TABLE")
|
||||
: (enum_def->is_union ? "ST_UNION" : "ST_ENUM"));
|
||||
auto num_fields = struct_def
|
||||
? struct_def->fields.vec.size()
|
||||
: enum_def->vals.vec.size();
|
||||
code_.SetValue("NUM_FIELDS", NumToString(num_fields));
|
||||
std::vector<std::string> names;
|
||||
std::vector<Type> types;
|
||||
bool consecutive_enum_from_zero = true;
|
||||
if (struct_def) {
|
||||
for (auto it = struct_def->fields.vec.begin();
|
||||
it != struct_def->fields.vec.end(); ++it) {
|
||||
const auto &field = **it;
|
||||
names.push_back(field.name);
|
||||
types.push_back(field.value.type);
|
||||
}
|
||||
} else {
|
||||
for (auto it = enum_def->vals.vec.begin(); it != enum_def->vals.vec.end();
|
||||
++it) {
|
||||
const auto &ev = **it;
|
||||
names.push_back(ev.name);
|
||||
types.push_back(enum_def->is_union ? ev.union_type
|
||||
: Type(enum_def->underlying_type));
|
||||
if (static_cast<int64_t>(it - enum_def->vals.vec.begin()) != ev.value) {
|
||||
consecutive_enum_from_zero = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
std::string ts;
|
||||
std::vector<std::string> type_refs;
|
||||
for (auto it = types.begin(); it != types.end(); ++it) {
|
||||
auto &type = *it;
|
||||
if (!ts.empty()) ts += ",\n ";
|
||||
auto is_vector = type.base_type == BASE_TYPE_VECTOR;
|
||||
auto bt = is_vector ? type.element : type.base_type;
|
||||
auto et = IsScalar(bt) || bt == BASE_TYPE_STRING
|
||||
? bt - BASE_TYPE_UTYPE + ET_UTYPE
|
||||
: ET_SEQUENCE;
|
||||
int ref_idx = -1;
|
||||
std::string ref_name = type.struct_def
|
||||
? WrapInNameSpace(*type.struct_def)
|
||||
: type.enum_def
|
||||
? WrapInNameSpace(*type.enum_def)
|
||||
: "";
|
||||
if (!ref_name.empty()) {
|
||||
auto rit = type_refs.begin();
|
||||
for (; rit != type_refs.end(); ++rit) {
|
||||
if (*rit == ref_name) {
|
||||
ref_idx = static_cast<int>(rit - type_refs.begin());
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (rit == type_refs.end()) {
|
||||
ref_idx = static_cast<int>(type_refs.size());
|
||||
type_refs.push_back(ref_name);
|
||||
}
|
||||
}
|
||||
ts += "{ flatbuffers::" + std::string(ElementaryTypeNames()[et]) + ", " +
|
||||
NumToString(is_vector) + ", " + NumToString(ref_idx) + " }";
|
||||
}
|
||||
std::string rs;
|
||||
for (auto it = type_refs.begin(); it != type_refs.end(); ++it) {
|
||||
if (!rs.empty()) rs += ",\n ";
|
||||
rs += *it + "TypeTable";
|
||||
}
|
||||
std::string ns;
|
||||
for (auto it = names.begin(); it != names.end(); ++it) {
|
||||
if (!ns.empty()) ns += ",\n ";
|
||||
ns += "\"" + *it + "\"";
|
||||
}
|
||||
std::string vs;
|
||||
if (enum_def && !consecutive_enum_from_zero) {
|
||||
for (auto it = enum_def->vals.vec.begin(); it != enum_def->vals.vec.end();
|
||||
++it) {
|
||||
const auto &ev = **it;
|
||||
if (!vs.empty()) vs += ", ";
|
||||
vs += NumToString(ev.value);
|
||||
}
|
||||
} else if (struct_def && struct_def->fixed) {
|
||||
for (auto it = struct_def->fields.vec.begin();
|
||||
it != struct_def->fields.vec.end(); ++it) {
|
||||
const auto &field = **it;
|
||||
vs += NumToString(field.value.offset);
|
||||
vs += ", ";
|
||||
}
|
||||
vs += NumToString(struct_def->bytesize);
|
||||
}
|
||||
code_.SetValue("TYPES", ts);
|
||||
code_.SetValue("REFS", rs);
|
||||
code_.SetValue("NAMES", ns);
|
||||
code_.SetValue("VALUES", vs);
|
||||
code_ += "flatbuffers::TypeTable *{{NAME}}TypeTable() {";
|
||||
if (num_fields) {
|
||||
code_ += " static flatbuffers::TypeCode type_codes[] = {";
|
||||
code_ += " {{TYPES}}";
|
||||
code_ += " };";
|
||||
}
|
||||
if (!type_refs.empty()) {
|
||||
code_ += " static flatbuffers::TypeFunction type_refs[] = {";
|
||||
code_ += " {{REFS}}";
|
||||
code_ += " };";
|
||||
}
|
||||
if (!vs.empty()) {
|
||||
code_ += " static const int32_t values[] = { {{VALUES}} };";
|
||||
}
|
||||
auto has_names = num_fields &&
|
||||
parser_.opts.mini_reflect == IDLOptions::kTypesAndNames;
|
||||
if (has_names) {
|
||||
code_ += " static const char *names[] = {";
|
||||
code_ += " {{NAMES}}";
|
||||
code_ += " };";
|
||||
}
|
||||
code_ += " static flatbuffers::TypeTable tt = {";
|
||||
code_ += std::string(" flatbuffers::{{SEQ_TYPE}}, {{NUM_FIELDS}}, ") +
|
||||
(num_fields ? "type_codes, " : "nullptr, ") +
|
||||
(!type_refs.empty() ? "type_refs, ": "nullptr, " ) +
|
||||
(!vs.empty() ? "values, " : "nullptr, ") +
|
||||
(has_names ? "names" : "nullptr");
|
||||
code_ += " };";
|
||||
code_ += " return &tt;";
|
||||
code_ += "}";
|
||||
code_ += "";
|
||||
}
|
||||
|
||||
// Generate an enum declaration,
|
||||
// an enum string lookup table,
|
||||
// and an enum array of values
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
set buildtype=Release
|
||||
if "%1"=="-b" set buildtype=%2
|
||||
|
||||
..\%buildtype%\flatc.exe --cpp --java --csharp --go --binary --python --js --ts --php --grpc --gen-mutable --gen-object-api --no-includes --cpp-ptr-type flatbuffers::unique_ptr --no-fb-import -I include_test monster_test.fbs monsterdata_test.json
|
||||
..\%buildtype%\flatc.exe --cpp --java --csharp --go --binary --python --js --ts --php --gen-mutable --no-fb-import --cpp-ptr-type flatbuffers::unique_ptr -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs
|
||||
..\%buildtype%\flatc.exe --cpp --js --ts --php --gen-mutable --gen-object-api --cpp-ptr-type flatbuffers::unique_ptr -o union_vector ./union_vector/union_vector.fbs
|
||||
..\%buildtype%\flatc.exe --cpp --java --csharp --go --binary --python --js --ts --php --grpc --gen-mutable --reflect-names --gen-object-api --no-includes --cpp-ptr-type flatbuffers::unique_ptr --no-fb-import -I include_test monster_test.fbs monsterdata_test.json
|
||||
..\%buildtype%\flatc.exe --cpp --java --csharp --go --binary --python --js --ts --php --gen-mutable --reflect-names --no-fb-import --cpp-ptr-type flatbuffers::unique_ptr -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs
|
||||
..\%buildtype%\flatc.exe --cpp --js --ts --php --gen-mutable --reflect-names --gen-object-api --cpp-ptr-type flatbuffers::unique_ptr -o union_vector ./union_vector/union_vector.fbs
|
||||
..\%buildtype%\flatc.exe -b --schema --bfbs-comments -I include_test monster_test.fbs
|
||||
..\%buildtype%\flatc.exe --jsonschema --schema -I include_test monster_test.fbs
|
||||
cd ../samples
|
||||
|
||||
@@ -14,11 +14,11 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
../flatc --cpp --java --csharp --go --binary --python --js --ts --php --grpc --gen-mutable --gen-object-api --no-includes --cpp-ptr-type flatbuffers::unique_ptr --no-fb-import -I include_test monster_test.fbs monsterdata_test.json
|
||||
../flatc --cpp --java --csharp --go --binary --python --js --ts --php --gen-mutable --no-fb-import --cpp-ptr-type flatbuffers::unique_ptr -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs
|
||||
../flatc --cpp --js --ts --php --gen-mutable --gen-object-api --cpp-ptr-type flatbuffers::unique_ptr -o union_vector ./union_vector/union_vector.fbs
|
||||
../flatc --cpp --java --csharp --go --binary --python --js --ts --php --grpc --gen-mutable --reflect-names --gen-object-api --no-includes --cpp-ptr-type flatbuffers::unique_ptr --no-fb-import -I include_test monster_test.fbs monsterdata_test.json
|
||||
../flatc --cpp --java --csharp --go --binary --python --js --ts --php --gen-mutable --reflect-names --no-fb-import --cpp-ptr-type flatbuffers::unique_ptr -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs
|
||||
../flatc --cpp --js --ts --php --gen-mutable --reflect-names --gen-object-api --cpp-ptr-type flatbuffers::unique_ptr -o union_vector ./union_vector/union_vector.fbs
|
||||
../flatc -b --schema --bfbs-comments -I include_test monster_test.fbs
|
||||
../flatc --jsonschema --schema -I include_test monster_test.fbs
|
||||
cd ../samples
|
||||
../flatc --cpp --gen-mutable --gen-object-api --cpp-ptr-type flatbuffers::unique_ptr monster.fbs
|
||||
../flatc --cpp --gen-mutable --reflect-names --gen-object-api --cpp-ptr-type flatbuffers::unique_ptr monster.fbs
|
||||
cd ../reflection
|
||||
|
||||
Binary file not shown.
@@ -1899,6 +1899,318 @@ inline void AnyUnion::Reset() {
|
||||
type = Any_NONE;
|
||||
}
|
||||
|
||||
} // namespace Example
|
||||
|
||||
flatbuffers::TypeTable *InParentNamespaceTypeTable();
|
||||
|
||||
namespace Example2 {
|
||||
|
||||
flatbuffers::TypeTable *MonsterTypeTable();
|
||||
|
||||
} // namespace Example2
|
||||
|
||||
namespace Example {
|
||||
|
||||
flatbuffers::TypeTable *TestTypeTable();
|
||||
|
||||
flatbuffers::TypeTable *TestSimpleTableWithEnumTypeTable();
|
||||
|
||||
flatbuffers::TypeTable *Vec3TypeTable();
|
||||
|
||||
flatbuffers::TypeTable *AbilityTypeTable();
|
||||
|
||||
flatbuffers::TypeTable *StatTypeTable();
|
||||
|
||||
flatbuffers::TypeTable *MonsterTypeTable();
|
||||
|
||||
flatbuffers::TypeTable *TypeAliasesTypeTable();
|
||||
|
||||
flatbuffers::TypeTable *ColorTypeTable() {
|
||||
static flatbuffers::TypeCode type_codes[] = {
|
||||
{ flatbuffers::ET_CHAR, 0, 0 },
|
||||
{ flatbuffers::ET_CHAR, 0, 0 },
|
||||
{ flatbuffers::ET_CHAR, 0, 0 }
|
||||
};
|
||||
static flatbuffers::TypeFunction type_refs[] = {
|
||||
ColorTypeTable
|
||||
};
|
||||
static const int32_t values[] = { 1, 2, 8 };
|
||||
static const char *names[] = {
|
||||
"Red",
|
||||
"Green",
|
||||
"Blue"
|
||||
};
|
||||
static flatbuffers::TypeTable tt = {
|
||||
flatbuffers::ST_ENUM, 3, type_codes, type_refs, values, names
|
||||
};
|
||||
return &tt;
|
||||
}
|
||||
|
||||
flatbuffers::TypeTable *AnyTypeTable() {
|
||||
static flatbuffers::TypeCode type_codes[] = {
|
||||
{ flatbuffers::ET_SEQUENCE, 0, -1 },
|
||||
{ flatbuffers::ET_SEQUENCE, 0, 0 },
|
||||
{ flatbuffers::ET_SEQUENCE, 0, 1 },
|
||||
{ flatbuffers::ET_SEQUENCE, 0, 2 }
|
||||
};
|
||||
static flatbuffers::TypeFunction type_refs[] = {
|
||||
MonsterTypeTable,
|
||||
TestSimpleTableWithEnumTypeTable,
|
||||
MyGame::Example2::MonsterTypeTable
|
||||
};
|
||||
static const char *names[] = {
|
||||
"NONE",
|
||||
"Monster",
|
||||
"TestSimpleTableWithEnum",
|
||||
"MyGame_Example2_Monster"
|
||||
};
|
||||
static flatbuffers::TypeTable tt = {
|
||||
flatbuffers::ST_UNION, 4, type_codes, type_refs, nullptr, names
|
||||
};
|
||||
return &tt;
|
||||
}
|
||||
|
||||
} // namespace Example
|
||||
|
||||
flatbuffers::TypeTable *InParentNamespaceTypeTable() {
|
||||
static flatbuffers::TypeTable tt = {
|
||||
flatbuffers::ST_TABLE, 0, nullptr, nullptr, nullptr, nullptr
|
||||
};
|
||||
return &tt;
|
||||
}
|
||||
|
||||
namespace Example2 {
|
||||
|
||||
flatbuffers::TypeTable *MonsterTypeTable() {
|
||||
static flatbuffers::TypeTable tt = {
|
||||
flatbuffers::ST_TABLE, 0, nullptr, nullptr, nullptr, nullptr
|
||||
};
|
||||
return &tt;
|
||||
}
|
||||
|
||||
} // namespace Example2
|
||||
|
||||
namespace Example {
|
||||
|
||||
flatbuffers::TypeTable *TestTypeTable() {
|
||||
static flatbuffers::TypeCode type_codes[] = {
|
||||
{ flatbuffers::ET_SHORT, 0, -1 },
|
||||
{ flatbuffers::ET_CHAR, 0, -1 }
|
||||
};
|
||||
static const int32_t values[] = { 0, 2, 4 };
|
||||
static const char *names[] = {
|
||||
"a",
|
||||
"b"
|
||||
};
|
||||
static flatbuffers::TypeTable tt = {
|
||||
flatbuffers::ST_STRUCT, 2, type_codes, nullptr, values, names
|
||||
};
|
||||
return &tt;
|
||||
}
|
||||
|
||||
flatbuffers::TypeTable *TestSimpleTableWithEnumTypeTable() {
|
||||
static flatbuffers::TypeCode type_codes[] = {
|
||||
{ flatbuffers::ET_CHAR, 0, 0 }
|
||||
};
|
||||
static flatbuffers::TypeFunction type_refs[] = {
|
||||
ColorTypeTable
|
||||
};
|
||||
static const char *names[] = {
|
||||
"color"
|
||||
};
|
||||
static flatbuffers::TypeTable tt = {
|
||||
flatbuffers::ST_TABLE, 1, type_codes, type_refs, nullptr, names
|
||||
};
|
||||
return &tt;
|
||||
}
|
||||
|
||||
flatbuffers::TypeTable *Vec3TypeTable() {
|
||||
static flatbuffers::TypeCode type_codes[] = {
|
||||
{ flatbuffers::ET_FLOAT, 0, -1 },
|
||||
{ flatbuffers::ET_FLOAT, 0, -1 },
|
||||
{ flatbuffers::ET_FLOAT, 0, -1 },
|
||||
{ flatbuffers::ET_DOUBLE, 0, -1 },
|
||||
{ flatbuffers::ET_CHAR, 0, 0 },
|
||||
{ flatbuffers::ET_SEQUENCE, 0, 1 }
|
||||
};
|
||||
static flatbuffers::TypeFunction type_refs[] = {
|
||||
ColorTypeTable,
|
||||
TestTypeTable
|
||||
};
|
||||
static const int32_t values[] = { 0, 4, 8, 16, 24, 26, 32 };
|
||||
static const char *names[] = {
|
||||
"x",
|
||||
"y",
|
||||
"z",
|
||||
"test1",
|
||||
"test2",
|
||||
"test3"
|
||||
};
|
||||
static flatbuffers::TypeTable tt = {
|
||||
flatbuffers::ST_STRUCT, 6, type_codes, type_refs, values, names
|
||||
};
|
||||
return &tt;
|
||||
}
|
||||
|
||||
flatbuffers::TypeTable *AbilityTypeTable() {
|
||||
static flatbuffers::TypeCode type_codes[] = {
|
||||
{ flatbuffers::ET_UINT, 0, -1 },
|
||||
{ flatbuffers::ET_UINT, 0, -1 }
|
||||
};
|
||||
static const int32_t values[] = { 0, 4, 8 };
|
||||
static const char *names[] = {
|
||||
"id",
|
||||
"distance"
|
||||
};
|
||||
static flatbuffers::TypeTable tt = {
|
||||
flatbuffers::ST_STRUCT, 2, type_codes, nullptr, values, names
|
||||
};
|
||||
return &tt;
|
||||
}
|
||||
|
||||
flatbuffers::TypeTable *StatTypeTable() {
|
||||
static flatbuffers::TypeCode type_codes[] = {
|
||||
{ flatbuffers::ET_STRING, 0, -1 },
|
||||
{ flatbuffers::ET_LONG, 0, -1 },
|
||||
{ flatbuffers::ET_USHORT, 0, -1 }
|
||||
};
|
||||
static const char *names[] = {
|
||||
"id",
|
||||
"val",
|
||||
"count"
|
||||
};
|
||||
static flatbuffers::TypeTable tt = {
|
||||
flatbuffers::ST_TABLE, 3, type_codes, nullptr, nullptr, names
|
||||
};
|
||||
return &tt;
|
||||
}
|
||||
|
||||
flatbuffers::TypeTable *MonsterTypeTable() {
|
||||
static flatbuffers::TypeCode type_codes[] = {
|
||||
{ flatbuffers::ET_SEQUENCE, 0, 0 },
|
||||
{ flatbuffers::ET_SHORT, 0, -1 },
|
||||
{ flatbuffers::ET_SHORT, 0, -1 },
|
||||
{ flatbuffers::ET_STRING, 0, -1 },
|
||||
{ flatbuffers::ET_BOOL, 0, -1 },
|
||||
{ flatbuffers::ET_UCHAR, 1, -1 },
|
||||
{ flatbuffers::ET_CHAR, 0, 1 },
|
||||
{ flatbuffers::ET_UTYPE, 0, 2 },
|
||||
{ flatbuffers::ET_SEQUENCE, 0, 2 },
|
||||
{ flatbuffers::ET_SEQUENCE, 1, 3 },
|
||||
{ flatbuffers::ET_STRING, 1, -1 },
|
||||
{ flatbuffers::ET_SEQUENCE, 1, 4 },
|
||||
{ flatbuffers::ET_SEQUENCE, 0, 4 },
|
||||
{ flatbuffers::ET_UCHAR, 1, -1 },
|
||||
{ flatbuffers::ET_SEQUENCE, 0, 5 },
|
||||
{ flatbuffers::ET_BOOL, 0, -1 },
|
||||
{ flatbuffers::ET_INT, 0, -1 },
|
||||
{ flatbuffers::ET_UINT, 0, -1 },
|
||||
{ flatbuffers::ET_LONG, 0, -1 },
|
||||
{ flatbuffers::ET_ULONG, 0, -1 },
|
||||
{ flatbuffers::ET_INT, 0, -1 },
|
||||
{ flatbuffers::ET_UINT, 0, -1 },
|
||||
{ flatbuffers::ET_LONG, 0, -1 },
|
||||
{ flatbuffers::ET_ULONG, 0, -1 },
|
||||
{ flatbuffers::ET_BOOL, 1, -1 },
|
||||
{ flatbuffers::ET_FLOAT, 0, -1 },
|
||||
{ flatbuffers::ET_FLOAT, 0, -1 },
|
||||
{ flatbuffers::ET_FLOAT, 0, -1 },
|
||||
{ flatbuffers::ET_STRING, 1, -1 },
|
||||
{ flatbuffers::ET_SEQUENCE, 1, 6 },
|
||||
{ flatbuffers::ET_UCHAR, 1, -1 },
|
||||
{ flatbuffers::ET_SEQUENCE, 1, 3 },
|
||||
{ flatbuffers::ET_LONG, 1, -1 },
|
||||
{ flatbuffers::ET_DOUBLE, 1, -1 },
|
||||
{ flatbuffers::ET_SEQUENCE, 0, 7 }
|
||||
};
|
||||
static flatbuffers::TypeFunction type_refs[] = {
|
||||
Vec3TypeTable,
|
||||
ColorTypeTable,
|
||||
AnyTypeTable,
|
||||
TestTypeTable,
|
||||
MonsterTypeTable,
|
||||
StatTypeTable,
|
||||
AbilityTypeTable,
|
||||
MyGame::InParentNamespaceTypeTable
|
||||
};
|
||||
static const char *names[] = {
|
||||
"pos",
|
||||
"mana",
|
||||
"hp",
|
||||
"name",
|
||||
"friendly",
|
||||
"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",
|
||||
"testarrayofsortedstruct",
|
||||
"flex",
|
||||
"test5",
|
||||
"vector_of_longs",
|
||||
"vector_of_doubles",
|
||||
"parent_namespace_test"
|
||||
};
|
||||
static flatbuffers::TypeTable tt = {
|
||||
flatbuffers::ST_TABLE, 35, type_codes, type_refs, nullptr, names
|
||||
};
|
||||
return &tt;
|
||||
}
|
||||
|
||||
flatbuffers::TypeTable *TypeAliasesTypeTable() {
|
||||
static flatbuffers::TypeCode type_codes[] = {
|
||||
{ flatbuffers::ET_CHAR, 0, -1 },
|
||||
{ flatbuffers::ET_UCHAR, 0, -1 },
|
||||
{ flatbuffers::ET_SHORT, 0, -1 },
|
||||
{ flatbuffers::ET_USHORT, 0, -1 },
|
||||
{ flatbuffers::ET_INT, 0, -1 },
|
||||
{ flatbuffers::ET_UINT, 0, -1 },
|
||||
{ flatbuffers::ET_LONG, 0, -1 },
|
||||
{ flatbuffers::ET_ULONG, 0, -1 },
|
||||
{ flatbuffers::ET_FLOAT, 0, -1 },
|
||||
{ flatbuffers::ET_DOUBLE, 0, -1 },
|
||||
{ flatbuffers::ET_CHAR, 1, -1 },
|
||||
{ flatbuffers::ET_DOUBLE, 1, -1 }
|
||||
};
|
||||
static const char *names[] = {
|
||||
"i8",
|
||||
"u8",
|
||||
"i16",
|
||||
"u16",
|
||||
"i32",
|
||||
"u32",
|
||||
"i64",
|
||||
"u64",
|
||||
"f32",
|
||||
"f64",
|
||||
"v8",
|
||||
"vf64"
|
||||
};
|
||||
static flatbuffers::TypeTable tt = {
|
||||
flatbuffers::ST_TABLE, 12, type_codes, nullptr, nullptr, names
|
||||
};
|
||||
return &tt;
|
||||
}
|
||||
|
||||
inline const MyGame::Example::Monster *GetMonster(const void *buf) {
|
||||
return flatbuffers::GetRoot<MyGame::Example::Monster>(buf);
|
||||
}
|
||||
|
||||
@@ -119,6 +119,59 @@ inline flatbuffers::Offset<TableInNestedNS> CreateTableInNestedNS(
|
||||
return builder_.Finish();
|
||||
}
|
||||
|
||||
flatbuffers::TypeTable *TableInNestedNSTypeTable();
|
||||
|
||||
flatbuffers::TypeTable *StructInNestedNSTypeTable();
|
||||
|
||||
flatbuffers::TypeTable *EnumInNestedNSTypeTable() {
|
||||
static flatbuffers::TypeCode type_codes[] = {
|
||||
{ flatbuffers::ET_CHAR, 0, 0 },
|
||||
{ flatbuffers::ET_CHAR, 0, 0 },
|
||||
{ flatbuffers::ET_CHAR, 0, 0 }
|
||||
};
|
||||
static flatbuffers::TypeFunction type_refs[] = {
|
||||
EnumInNestedNSTypeTable
|
||||
};
|
||||
static const char *names[] = {
|
||||
"A",
|
||||
"B",
|
||||
"C"
|
||||
};
|
||||
static flatbuffers::TypeTable tt = {
|
||||
flatbuffers::ST_ENUM, 3, type_codes, type_refs, nullptr, names
|
||||
};
|
||||
return &tt;
|
||||
}
|
||||
|
||||
flatbuffers::TypeTable *TableInNestedNSTypeTable() {
|
||||
static flatbuffers::TypeCode type_codes[] = {
|
||||
{ flatbuffers::ET_INT, 0, -1 }
|
||||
};
|
||||
static const char *names[] = {
|
||||
"foo"
|
||||
};
|
||||
static flatbuffers::TypeTable tt = {
|
||||
flatbuffers::ST_TABLE, 1, type_codes, nullptr, nullptr, names
|
||||
};
|
||||
return &tt;
|
||||
}
|
||||
|
||||
flatbuffers::TypeTable *StructInNestedNSTypeTable() {
|
||||
static flatbuffers::TypeCode type_codes[] = {
|
||||
{ flatbuffers::ET_INT, 0, -1 },
|
||||
{ flatbuffers::ET_INT, 0, -1 }
|
||||
};
|
||||
static const int32_t values[] = { 0, 4, 8 };
|
||||
static const char *names[] = {
|
||||
"a",
|
||||
"b"
|
||||
};
|
||||
static flatbuffers::TypeTable tt = {
|
||||
flatbuffers::ST_STRUCT, 2, type_codes, nullptr, values, names
|
||||
};
|
||||
return &tt;
|
||||
}
|
||||
|
||||
} // namespace NamespaceB
|
||||
} // namespace NamespaceA
|
||||
|
||||
|
||||
@@ -212,6 +212,85 @@ namespace NamespaceC {
|
||||
|
||||
namespace NamespaceA {
|
||||
|
||||
flatbuffers::TypeTable *TableInFirstNSTypeTable();
|
||||
|
||||
} // namespace NamespaceA
|
||||
|
||||
namespace NamespaceC {
|
||||
|
||||
flatbuffers::TypeTable *TableInCTypeTable();
|
||||
|
||||
} // namespace NamespaceC
|
||||
|
||||
namespace NamespaceA {
|
||||
|
||||
flatbuffers::TypeTable *SecondTableInATypeTable();
|
||||
|
||||
flatbuffers::TypeTable *TableInFirstNSTypeTable() {
|
||||
static flatbuffers::TypeCode type_codes[] = {
|
||||
{ flatbuffers::ET_SEQUENCE, 0, 0 },
|
||||
{ flatbuffers::ET_CHAR, 0, 1 },
|
||||
{ flatbuffers::ET_SEQUENCE, 0, 2 }
|
||||
};
|
||||
static flatbuffers::TypeFunction type_refs[] = {
|
||||
NamespaceA::NamespaceB::TableInNestedNSTypeTable,
|
||||
NamespaceA::NamespaceB::EnumInNestedNSTypeTable,
|
||||
NamespaceA::NamespaceB::StructInNestedNSTypeTable
|
||||
};
|
||||
static const char *names[] = {
|
||||
"foo_table",
|
||||
"foo_enum",
|
||||
"foo_struct"
|
||||
};
|
||||
static flatbuffers::TypeTable tt = {
|
||||
flatbuffers::ST_TABLE, 3, type_codes, type_refs, nullptr, names
|
||||
};
|
||||
return &tt;
|
||||
}
|
||||
|
||||
} // namespace NamespaceA
|
||||
|
||||
namespace NamespaceC {
|
||||
|
||||
flatbuffers::TypeTable *TableInCTypeTable() {
|
||||
static flatbuffers::TypeCode type_codes[] = {
|
||||
{ flatbuffers::ET_SEQUENCE, 0, 0 },
|
||||
{ flatbuffers::ET_SEQUENCE, 0, 1 }
|
||||
};
|
||||
static flatbuffers::TypeFunction type_refs[] = {
|
||||
NamespaceA::TableInFirstNSTypeTable,
|
||||
NamespaceA::SecondTableInATypeTable
|
||||
};
|
||||
static const char *names[] = {
|
||||
"refer_to_a1",
|
||||
"refer_to_a2"
|
||||
};
|
||||
static flatbuffers::TypeTable tt = {
|
||||
flatbuffers::ST_TABLE, 2, type_codes, type_refs, nullptr, names
|
||||
};
|
||||
return &tt;
|
||||
}
|
||||
|
||||
} // namespace NamespaceC
|
||||
|
||||
namespace NamespaceA {
|
||||
|
||||
flatbuffers::TypeTable *SecondTableInATypeTable() {
|
||||
static flatbuffers::TypeCode type_codes[] = {
|
||||
{ flatbuffers::ET_SEQUENCE, 0, 0 }
|
||||
};
|
||||
static flatbuffers::TypeFunction type_refs[] = {
|
||||
NamespaceC::TableInCTypeTable
|
||||
};
|
||||
static const char *names[] = {
|
||||
"refer_to_c"
|
||||
};
|
||||
static flatbuffers::TypeTable tt = {
|
||||
flatbuffers::ST_TABLE, 1, type_codes, type_refs, nullptr, names
|
||||
};
|
||||
return &tt;
|
||||
}
|
||||
|
||||
} // namespace NamespaceA
|
||||
|
||||
#endif // FLATBUFFERS_GENERATED_NAMESPACETEST2_NAMESPACEA_H_
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "flatbuffers/idl.h"
|
||||
#include "flatbuffers/util.h"
|
||||
#include "flatbuffers/registry.h"
|
||||
#include "flatbuffers/minireflect.h"
|
||||
|
||||
#include "monster_test_generated.h"
|
||||
#include "namespace_test/namespace_test1_generated.h"
|
||||
@@ -46,8 +47,9 @@ int testing_fails = 0;
|
||||
|
||||
void TestFail(const char *expval, const char *val, const char *exp,
|
||||
const char *file, int line) {
|
||||
TEST_OUTPUT_LINE("TEST FAILED: %s:%d, %s (%s) != %s", file, line,
|
||||
exp, expval, val);
|
||||
TEST_OUTPUT_LINE("VALUE: \"%s\"", expval);
|
||||
TEST_OUTPUT_LINE("EXPECTED: \"%s\"", val);
|
||||
TEST_OUTPUT_LINE("TEST FAILED: %s:%d, %s", file, line, exp);
|
||||
assert(0);
|
||||
testing_fails++;
|
||||
}
|
||||
@@ -561,11 +563,7 @@ void ParseAndGenerateTextTest() {
|
||||
std::string jsongen;
|
||||
auto result = GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
||||
TEST_EQ(result, true);
|
||||
|
||||
if (jsongen != jsonfile) {
|
||||
TEST_OUTPUT_LINE("%s----------------\n%s", jsongen.c_str(), jsonfile.c_str());
|
||||
TEST_NOTNULL(NULL);
|
||||
}
|
||||
TEST_EQ_STR(jsongen.c_str(), jsonfile.c_str());
|
||||
|
||||
// We can also do the above using the convenient Registry that knows about
|
||||
// a set of file_identifiers mapped to schemas.
|
||||
@@ -772,6 +770,34 @@ void ReflectionTest(uint8_t *flatbuf, size_t length) {
|
||||
fbb.GetBufferPointer(), fbb.GetSize()), true);
|
||||
}
|
||||
|
||||
void MiniReflectFlatBuffersTest(uint8_t *flatbuf) {
|
||||
auto s = flatbuffers::FlatBufferToString(flatbuf, MonsterTypeTable());
|
||||
TEST_EQ_STR(s.c_str(),
|
||||
"{ "
|
||||
"pos: { x: 1.0, y: 2.0, z: 3.0, test1: 0.0, test2: Red, test3: "
|
||||
"{ a: 10, b: 20 } }, "
|
||||
"hp: 80, "
|
||||
"name: \"MyMonster\", "
|
||||
"inventory: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ], "
|
||||
"test_type: Monster, "
|
||||
"test: { name: \"Fred\" }, "
|
||||
"test4: [ { a: 10, b: 20 }, { a: 30, b: 40 } ], "
|
||||
"testarrayofstring: [ \"bob\", \"fred\", \"bob\", \"fred\" ], "
|
||||
"testarrayoftables: [ { hp: 1000, name: \"Barney\" }, { name: \"Fred\" }, "
|
||||
"{ name: \"Wilma\" } ], "
|
||||
// TODO(wvo): should really print this nested buffer correctly.
|
||||
"testnestedflatbuffer: [ 20, 0, 0, 0, 77, 79, 78, 83, 12, 0, 12, 0, 0, 0, "
|
||||
"4, 0, 6, 0, 8, 0, 12, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 13, 0, 0, 0, 78, "
|
||||
"101, 115, 116, 101, 100, 77, 111, 110, 115, 116, 101, 114, 0, 0, 0 ], "
|
||||
"testarrayofstring2: [ \"jane\", \"mary\" ], "
|
||||
"testarrayofsortedstruct: [ { id: 1, distance: 10 }, "
|
||||
"{ id: 2, distance: 20 }, { id: 3, distance: 30 }, "
|
||||
"{ id: 4, distance: 40 } ], "
|
||||
"flex: [ 210, 4, 5, 2 ], "
|
||||
"test5: [ { a: 10, b: 20 }, { a: 30, b: 40 } ] "
|
||||
"}");
|
||||
}
|
||||
|
||||
// Parse a .proto schema, output as .fbs
|
||||
void ParseProtoTest() {
|
||||
// load the .proto and the golden file from disk
|
||||
@@ -800,11 +826,7 @@ void ParseProtoTest() {
|
||||
// Ensure generated file is parsable.
|
||||
flatbuffers::Parser parser2;
|
||||
TEST_EQ(parser2.Parse(fbs.c_str(), nullptr), true);
|
||||
|
||||
if (fbs != goldenfile) {
|
||||
TEST_OUTPUT_LINE("%s----------------\n%s", fbs.c_str(), goldenfile.c_str());
|
||||
TEST_NOTNULL(NULL);
|
||||
}
|
||||
TEST_EQ_STR(fbs.c_str(), goldenfile.c_str());
|
||||
}
|
||||
|
||||
template<typename T> void CompareTableFieldValue(flatbuffers::Table *table,
|
||||
@@ -1248,10 +1270,9 @@ void UnicodeTest() {
|
||||
parser.opts.indent_step = -1;
|
||||
auto result = GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
||||
TEST_EQ(result, true);
|
||||
TEST_EQ(jsongen,
|
||||
std::string(
|
||||
TEST_EQ_STR(jsongen.c_str(),
|
||||
"{F: \"\\u20AC\\u00A2\\u30E6\\u30FC\\u30B6\\u30FC"
|
||||
"\\u5225\\u30B5\\u30A4\\u30C8\\u20AC\\u0080\\uD83D\\uDE0E\"}"));
|
||||
"\\u5225\\u30B5\\u30A4\\u30C8\\u20AC\\u0080\\uD83D\\uDE0E\"}");
|
||||
}
|
||||
|
||||
void UnicodeTestAllowNonUTF8() {
|
||||
@@ -1265,10 +1286,9 @@ void UnicodeTestAllowNonUTF8() {
|
||||
parser.opts.indent_step = -1;
|
||||
auto result = GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
||||
TEST_EQ(result, true);
|
||||
TEST_EQ(jsongen,
|
||||
std::string(
|
||||
TEST_EQ_STR(jsongen.c_str(),
|
||||
"{F: \"\\u20AC\\u00A2\\u30E6\\u30FC\\u30B6\\u30FC"
|
||||
"\\u5225\\u30B5\\u30A4\\u30C8\\u0001\\x80\\u0080\\uD83D\\uDE0E\"}"));
|
||||
"\\u5225\\u30B5\\u30A4\\u30C8\\u0001\\x80\\u0080\\uD83D\\uDE0E\"}");
|
||||
}
|
||||
|
||||
void UnicodeTestGenerateTextFailsOnNonUTF8() {
|
||||
@@ -1300,7 +1320,7 @@ void UnicodeSurrogatesTest() {
|
||||
parser.builder_.GetBufferPointer());
|
||||
auto string = root->GetPointer<flatbuffers::String *>(
|
||||
flatbuffers::FieldIndexToOffset(0));
|
||||
TEST_EQ(strcmp(string->c_str(), "\xF0\x9F\x92\xA9"), 0);
|
||||
TEST_EQ_STR(string->c_str(), "\xF0\x9F\x92\xA9");
|
||||
}
|
||||
|
||||
void UnicodeInvalidSurrogatesTest() {
|
||||
@@ -1437,7 +1457,7 @@ void UnknownFieldsTest() {
|
||||
parser.opts.indent_step = -1;
|
||||
auto result = GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
||||
TEST_EQ(result, true);
|
||||
TEST_EQ(jsongen == "{str: \"test\",i: 10}", true);
|
||||
TEST_EQ_STR(jsongen.c_str(), "{str: \"test\",i: 10}");
|
||||
}
|
||||
|
||||
void ParseUnionTest() {
|
||||
@@ -1548,6 +1568,14 @@ void UnionVectorTest() {
|
||||
auto repacked_movie = GetMovie(fbb.GetBufferPointer());
|
||||
|
||||
TestMovie(repacked_movie);
|
||||
|
||||
auto s = flatbuffers::FlatBufferToString(fbb.GetBufferPointer(),
|
||||
MovieTypeTable());
|
||||
TEST_EQ_STR(s.c_str(),
|
||||
"{ main_character_type: Rapunzel, main_character: { hair_length: 6 }, "
|
||||
"characters_type: [ Belle, MuLan, BookFan, Other, Unused ], "
|
||||
"characters: [ { books_read: 7 }, { sword_attack_damage: 5 }, "
|
||||
"{ books_read: 2 }, \"Other\", \"Unused\" ] }");
|
||||
}
|
||||
|
||||
void ConformTest() {
|
||||
@@ -1774,6 +1802,8 @@ int main(int /*argc*/, const char * /*argv*/[]) {
|
||||
|
||||
ObjectFlatBuffersTest(flatbuf.data());
|
||||
|
||||
MiniReflectFlatBuffersTest(flatbuf.data());
|
||||
|
||||
SizePrefixedTest();
|
||||
|
||||
#ifndef FLATBUFFERS_NO_FILE_TESTS
|
||||
|
||||
@@ -600,6 +600,107 @@ inline void CharacterUnion::Reset() {
|
||||
type = Character_NONE;
|
||||
}
|
||||
|
||||
flatbuffers::TypeTable *AttackerTypeTable();
|
||||
|
||||
flatbuffers::TypeTable *RapunzelTypeTable();
|
||||
|
||||
flatbuffers::TypeTable *BookReaderTypeTable();
|
||||
|
||||
flatbuffers::TypeTable *MovieTypeTable();
|
||||
|
||||
flatbuffers::TypeTable *CharacterTypeTable() {
|
||||
static flatbuffers::TypeCode type_codes[] = {
|
||||
{ flatbuffers::ET_SEQUENCE, 0, -1 },
|
||||
{ flatbuffers::ET_SEQUENCE, 0, 0 },
|
||||
{ flatbuffers::ET_SEQUENCE, 0, 1 },
|
||||
{ flatbuffers::ET_SEQUENCE, 0, 2 },
|
||||
{ flatbuffers::ET_SEQUENCE, 0, 2 },
|
||||
{ flatbuffers::ET_STRING, 0, -1 },
|
||||
{ flatbuffers::ET_STRING, 0, -1 }
|
||||
};
|
||||
static flatbuffers::TypeFunction type_refs[] = {
|
||||
AttackerTypeTable,
|
||||
RapunzelTypeTable,
|
||||
BookReaderTypeTable
|
||||
};
|
||||
static const char *names[] = {
|
||||
"NONE",
|
||||
"MuLan",
|
||||
"Rapunzel",
|
||||
"Belle",
|
||||
"BookFan",
|
||||
"Other",
|
||||
"Unused"
|
||||
};
|
||||
static flatbuffers::TypeTable tt = {
|
||||
flatbuffers::ST_UNION, 7, type_codes, type_refs, nullptr, names
|
||||
};
|
||||
return &tt;
|
||||
}
|
||||
|
||||
flatbuffers::TypeTable *AttackerTypeTable() {
|
||||
static flatbuffers::TypeCode type_codes[] = {
|
||||
{ flatbuffers::ET_INT, 0, -1 }
|
||||
};
|
||||
static const char *names[] = {
|
||||
"sword_attack_damage"
|
||||
};
|
||||
static flatbuffers::TypeTable tt = {
|
||||
flatbuffers::ST_TABLE, 1, type_codes, nullptr, nullptr, names
|
||||
};
|
||||
return &tt;
|
||||
}
|
||||
|
||||
flatbuffers::TypeTable *RapunzelTypeTable() {
|
||||
static flatbuffers::TypeCode type_codes[] = {
|
||||
{ flatbuffers::ET_INT, 0, -1 }
|
||||
};
|
||||
static const int32_t values[] = { 0, 4 };
|
||||
static const char *names[] = {
|
||||
"hair_length"
|
||||
};
|
||||
static flatbuffers::TypeTable tt = {
|
||||
flatbuffers::ST_STRUCT, 1, type_codes, nullptr, values, names
|
||||
};
|
||||
return &tt;
|
||||
}
|
||||
|
||||
flatbuffers::TypeTable *BookReaderTypeTable() {
|
||||
static flatbuffers::TypeCode type_codes[] = {
|
||||
{ flatbuffers::ET_INT, 0, -1 }
|
||||
};
|
||||
static const int32_t values[] = { 0, 4 };
|
||||
static const char *names[] = {
|
||||
"books_read"
|
||||
};
|
||||
static flatbuffers::TypeTable tt = {
|
||||
flatbuffers::ST_STRUCT, 1, type_codes, nullptr, values, names
|
||||
};
|
||||
return &tt;
|
||||
}
|
||||
|
||||
flatbuffers::TypeTable *MovieTypeTable() {
|
||||
static flatbuffers::TypeCode type_codes[] = {
|
||||
{ flatbuffers::ET_UTYPE, 0, 0 },
|
||||
{ flatbuffers::ET_SEQUENCE, 0, 0 },
|
||||
{ flatbuffers::ET_UTYPE, 1, 0 },
|
||||
{ flatbuffers::ET_SEQUENCE, 1, 0 }
|
||||
};
|
||||
static flatbuffers::TypeFunction type_refs[] = {
|
||||
CharacterTypeTable
|
||||
};
|
||||
static const char *names[] = {
|
||||
"main_character_type",
|
||||
"main_character",
|
||||
"characters_type",
|
||||
"characters"
|
||||
};
|
||||
static flatbuffers::TypeTable tt = {
|
||||
flatbuffers::ST_TABLE, 4, type_codes, type_refs, nullptr, names
|
||||
};
|
||||
return &tt;
|
||||
}
|
||||
|
||||
inline const Movie *GetMovie(const void *buf) {
|
||||
return flatbuffers::GetRoot<Movie>(buf);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user