mirror of
https://github.com/google/flatbuffers.git
synced 2025-04-09 00:12:15 +08:00
* [C++] #6501 - Problem when mapping a native type multiple times - idl.h: added "native_type_pack_name" - flatbuffers.h: added CreateVectorOfNativeStructs variants which receive a pointer to the serialization function - idl_gen_cpp.cpp: adapted code generation in case "native_type_pack_name" attribute is present - extended tests & docs; improved surrounding native_type docs a little * integrated review feedback
This commit is contained in:
parent
c992eafb5b
commit
78f0c0d1d9
@ -133,11 +133,11 @@ The following attributes are specific to the object-based API code generation:
|
||||
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_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_custom_alloc`:"custom_allocator" (on a table or struct): When using the
|
||||
- `native_custom_alloc("custom_allocator")` (on a table or struct): When using the
|
||||
object-based API all generated NativeTables that are allocated when unpacking
|
||||
your flatbuffer will use "custom allocator". The allocator is also used by
|
||||
any std::vector that appears in a table defined with `native_custom_alloc`.
|
||||
@ -148,12 +148,15 @@ The following attributes are specific to the object-based API code generation:
|
||||
|
||||
schema:
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
|
||||
table mytable(native_custom_alloc:"custom_allocator") {
|
||||
...
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
with custom_allocator defined before flatbuffers.h is included, as:
|
||||
with custom_allocator defined before `flatbuffers.h` is included, as:
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
|
||||
template <typename T> struct custom_allocator : public std::allocator<T> {
|
||||
|
||||
typedef T *pointer;
|
||||
@ -175,48 +178,73 @@ The following attributes are specific to the object-based API code generation:
|
||||
template <class U>
|
||||
custom_allocator(const custom_allocator<U>&) throw() {}
|
||||
};
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- `native_type`' "type" (on a struct): In some cases, a more optimal C++ data
|
||||
- `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;
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
|
||||
struct Vec2 {
|
||||
x: float;
|
||||
y: float;
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
generates the following Object-Based API class:
|
||||
|
||||
struct Vec2T : flatbuffers::NativeTable {
|
||||
float x;
|
||||
float y;
|
||||
};
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
|
||||
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.
|
||||
};
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
|
||||
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.
|
||||
code would use `vector2` in place of `Vec2T` for all generated code of
|
||||
the Object-Based API.
|
||||
|
||||
However, becuase the native_type is unknown to flatbuffers, the user must
|
||||
However, because 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);
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
|
||||
namespace flatbuffers {
|
||||
Vec2 Pack(const vector2& obj);
|
||||
vector2 UnPack(const Vec2& obj);
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Finally, the following top-level attribute
|
||||
- `native_type_pack_name("name")` (on a struct when `native_type` is
|
||||
specified, too): when you want to use the same `native_type` multiple times
|
||||
(e. g. with different precision) you must make the names of the Pack/UnPack
|
||||
functions unique, otherwise you will run into compile errors. This attribute
|
||||
appends a name to the expected Pack/UnPack functions. So when you
|
||||
specify `native_type_pack_name("Vec2")` in the above example you now need to
|
||||
implement these serialization functions instead:
|
||||
|
||||
- `native_include`: "path" (at file level): Because the `native_type` attribute
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
|
||||
namespace flatbuffers {
|
||||
Vec2 PackVec2(const vector2& obj);
|
||||
vector2 UnPackVec2(const Vec2& obj);
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Finally, the following top-level attributes:
|
||||
|
||||
- `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
|
||||
|
@ -1800,6 +1800,25 @@ class FlatBufferBuilder {
|
||||
return Offset<Vector<const T *>>(EndVector(len));
|
||||
}
|
||||
|
||||
/// @brief Serialize an array of native structs into a FlatBuffer `vector`.
|
||||
/// @tparam T The data type of the struct array elements.
|
||||
/// @tparam S The data type of the native struct array elements.
|
||||
/// @param[in] v A pointer to the array of type `S` to serialize into the
|
||||
/// buffer as a `vector`.
|
||||
/// @param[in] len The number of elements to serialize.
|
||||
/// @param[in] pack_func Pointer to a function to convert the native struct
|
||||
/// to the FlatBuffer struct.
|
||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||
/// where the vector is stored.
|
||||
template<typename T, typename S>
|
||||
Offset<Vector<const T *>> CreateVectorOfNativeStructs(
|
||||
const S *v, size_t len, T((*const pack_func)(const S &))) {
|
||||
FLATBUFFERS_ASSERT(pack_func);
|
||||
std::vector<T> vv(len);
|
||||
std::transform(v, v + len, vv.begin(), pack_func);
|
||||
return CreateVectorOfStructs<T>(data(vv), vv.size());
|
||||
}
|
||||
|
||||
/// @brief Serialize an array of native structs into a FlatBuffer `vector`.
|
||||
/// @tparam T The data type of the struct array elements.
|
||||
/// @tparam S The data type of the native struct array elements.
|
||||
@ -1812,9 +1831,7 @@ class FlatBufferBuilder {
|
||||
Offset<Vector<const T *>> CreateVectorOfNativeStructs(const S *v,
|
||||
size_t len) {
|
||||
extern T Pack(const S &);
|
||||
std::vector<T> vv(len);
|
||||
std::transform(v, v + len, vv.begin(), Pack);
|
||||
return CreateVectorOfStructs<T>(data(vv), vv.size());
|
||||
return CreateVectorOfNativeStructs(v, len, Pack);
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
@ -1871,6 +1888,22 @@ class FlatBufferBuilder {
|
||||
return CreateVectorOfStructs(data(v), v.size());
|
||||
}
|
||||
|
||||
/// @brief Serialize a `std::vector` of native structs into a FlatBuffer
|
||||
/// `vector`.
|
||||
/// @tparam T The data type of the `std::vector` struct elements.
|
||||
/// @tparam S The data type of the `std::vector` native struct elements.
|
||||
/// @param[in] v A const reference to the `std::vector` of structs to
|
||||
/// serialize into the buffer as a `vector`.
|
||||
/// @param[in] pack_func Pointer to a function to convert the native struct
|
||||
/// to the FlatBuffer struct.
|
||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||
/// where the vector is stored.
|
||||
template<typename T, typename S>
|
||||
Offset<Vector<const T *>> CreateVectorOfNativeStructs(
|
||||
const std::vector<S> &v, T((*const pack_func)(const S &))) {
|
||||
return CreateVectorOfNativeStructs<T, S>(data(v), v.size(), pack_func);
|
||||
}
|
||||
|
||||
/// @brief Serialize a `std::vector` of native structs into a FlatBuffer
|
||||
/// `vector`.
|
||||
/// @tparam T The data type of the `std::vector` struct elements.
|
||||
|
@ -809,6 +809,7 @@ class Parser : public ParserState {
|
||||
known_attributes_["native_inline"] = true;
|
||||
known_attributes_["native_custom_alloc"] = true;
|
||||
known_attributes_["native_type"] = true;
|
||||
known_attributes_["native_type_pack_name"] = true;
|
||||
known_attributes_["native_default"] = true;
|
||||
known_attributes_["flexbuffer"] = true;
|
||||
known_attributes_["private"] = true;
|
||||
|
@ -2621,9 +2621,14 @@ class CppGenerator : public BaseGenerator {
|
||||
}
|
||||
case BASE_TYPE_STRUCT: {
|
||||
if (IsStruct(type)) {
|
||||
auto native_type = type.struct_def->attributes.Lookup("native_type");
|
||||
const auto &struct_attrs = type.struct_def->attributes;
|
||||
const auto native_type = struct_attrs.Lookup("native_type");
|
||||
if (native_type) {
|
||||
return "flatbuffers::UnPack(*" + val + ")";
|
||||
std::string unpack_call = "flatbuffers::UnPack";
|
||||
const auto pack_name = struct_attrs.Lookup("native_type_pack_name");
|
||||
if (pack_name) { unpack_call += pack_name->constant; }
|
||||
unpack_call += "(*" + val + ")";
|
||||
return unpack_call;
|
||||
} else if (invector || afield.native_inline) {
|
||||
return "*" + val;
|
||||
} else {
|
||||
@ -2849,15 +2854,24 @@ class CppGenerator : public BaseGenerator {
|
||||
}
|
||||
case BASE_TYPE_STRUCT: {
|
||||
if (IsStruct(vector_type)) {
|
||||
auto native_type =
|
||||
field.value.type.struct_def->attributes.Lookup("native_type");
|
||||
const auto &struct_attrs =
|
||||
field.value.type.struct_def->attributes;
|
||||
const auto native_type = struct_attrs.Lookup("native_type");
|
||||
if (native_type) {
|
||||
code += "_fbb.CreateVectorOfNativeStructs<";
|
||||
code += WrapInNameSpace(*vector_type.struct_def) + ">";
|
||||
code += WrapInNameSpace(*vector_type.struct_def) + ", " +
|
||||
native_type->constant + ">";
|
||||
code += "(" + value;
|
||||
const auto pack_name =
|
||||
struct_attrs.Lookup("native_type_pack_name");
|
||||
if (pack_name) {
|
||||
code += ", flatbuffers::Pack" + pack_name->constant;
|
||||
}
|
||||
code += ")";
|
||||
} else {
|
||||
code += "_fbb.CreateVectorOfStructs";
|
||||
code += "(" + value + ")";
|
||||
}
|
||||
code += "(" + value + ")";
|
||||
} else {
|
||||
code += "_fbb.CreateVector<flatbuffers::Offset<";
|
||||
code += WrapInNameSpace(*vector_type.struct_def) + ">> ";
|
||||
@ -2932,10 +2946,14 @@ class CppGenerator : public BaseGenerator {
|
||||
}
|
||||
case BASE_TYPE_STRUCT: {
|
||||
if (IsStruct(field.value.type)) {
|
||||
auto native_type =
|
||||
field.value.type.struct_def->attributes.Lookup("native_type");
|
||||
const auto &struct_attribs = field.value.type.struct_def->attributes;
|
||||
const auto native_type = struct_attribs.Lookup("native_type");
|
||||
if (native_type) {
|
||||
code += "flatbuffers::Pack(" + value + ")";
|
||||
code += "flatbuffers::Pack";
|
||||
const auto pack_name =
|
||||
struct_attribs.Lookup("native_type_pack_name");
|
||||
if (pack_name) { code += pack_name->constant; }
|
||||
code += "(" + value + ")";
|
||||
} else if (field.native_inline) {
|
||||
code += "&" + value;
|
||||
} else {
|
||||
|
@ -8,8 +8,15 @@ struct Vector3D (native_type:"Native::Vector3D") {
|
||||
z:float;
|
||||
}
|
||||
|
||||
struct Vector3DAlt (native_type:"Native::Vector3D", native_type_pack_name:"Vector3DAlt") {
|
||||
a:float;
|
||||
b:float;
|
||||
c:float;
|
||||
}
|
||||
|
||||
table ApplicationData {
|
||||
vectors:[Vector3D];
|
||||
vectors_alt:[Vector3DAlt];
|
||||
}
|
||||
|
||||
root_type ApplicationData;
|
||||
|
@ -12,12 +12,16 @@ namespace Geometry {
|
||||
|
||||
struct Vector3D;
|
||||
|
||||
struct Vector3DAlt;
|
||||
|
||||
struct ApplicationData;
|
||||
struct ApplicationDataBuilder;
|
||||
struct ApplicationDataT;
|
||||
|
||||
inline const flatbuffers::TypeTable *Vector3DTypeTable();
|
||||
|
||||
inline const flatbuffers::TypeTable *Vector3DAltTypeTable();
|
||||
|
||||
inline const flatbuffers::TypeTable *ApplicationDataTypeTable();
|
||||
|
||||
FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Vector3D FLATBUFFERS_FINAL_CLASS {
|
||||
@ -61,9 +65,51 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Vector3D FLATBUFFERS_FINAL_CLASS {
|
||||
};
|
||||
FLATBUFFERS_STRUCT_END(Vector3D, 12);
|
||||
|
||||
FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Vector3DAlt FLATBUFFERS_FINAL_CLASS {
|
||||
private:
|
||||
float a_;
|
||||
float b_;
|
||||
float c_;
|
||||
|
||||
public:
|
||||
static const flatbuffers::TypeTable *MiniReflectTypeTable() {
|
||||
return Vector3DAltTypeTable();
|
||||
}
|
||||
Vector3DAlt()
|
||||
: a_(0),
|
||||
b_(0),
|
||||
c_(0) {
|
||||
}
|
||||
Vector3DAlt(float _a, float _b, float _c)
|
||||
: a_(flatbuffers::EndianScalar(_a)),
|
||||
b_(flatbuffers::EndianScalar(_b)),
|
||||
c_(flatbuffers::EndianScalar(_c)) {
|
||||
}
|
||||
float a() const {
|
||||
return flatbuffers::EndianScalar(a_);
|
||||
}
|
||||
void mutate_a(float _a) {
|
||||
flatbuffers::WriteScalar(&a_, _a);
|
||||
}
|
||||
float b() const {
|
||||
return flatbuffers::EndianScalar(b_);
|
||||
}
|
||||
void mutate_b(float _b) {
|
||||
flatbuffers::WriteScalar(&b_, _b);
|
||||
}
|
||||
float c() const {
|
||||
return flatbuffers::EndianScalar(c_);
|
||||
}
|
||||
void mutate_c(float _c) {
|
||||
flatbuffers::WriteScalar(&c_, _c);
|
||||
}
|
||||
};
|
||||
FLATBUFFERS_STRUCT_END(Vector3DAlt, 12);
|
||||
|
||||
struct ApplicationDataT : public flatbuffers::NativeTable {
|
||||
typedef ApplicationData TableType;
|
||||
std::vector<Native::Vector3D> vectors{};
|
||||
std::vector<Native::Vector3D> vectors_alt{};
|
||||
};
|
||||
|
||||
struct ApplicationData FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
@ -73,7 +119,8 @@ struct ApplicationData FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
return ApplicationDataTypeTable();
|
||||
}
|
||||
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
||||
VT_VECTORS = 4
|
||||
VT_VECTORS = 4,
|
||||
VT_VECTORS_ALT = 6
|
||||
};
|
||||
const flatbuffers::Vector<const Geometry::Vector3D *> *vectors() const {
|
||||
return GetPointer<const flatbuffers::Vector<const Geometry::Vector3D *> *>(VT_VECTORS);
|
||||
@ -81,10 +128,18 @@ struct ApplicationData FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
flatbuffers::Vector<const Geometry::Vector3D *> *mutable_vectors() {
|
||||
return GetPointer<flatbuffers::Vector<const Geometry::Vector3D *> *>(VT_VECTORS);
|
||||
}
|
||||
const flatbuffers::Vector<const Geometry::Vector3DAlt *> *vectors_alt() const {
|
||||
return GetPointer<const flatbuffers::Vector<const Geometry::Vector3DAlt *> *>(VT_VECTORS_ALT);
|
||||
}
|
||||
flatbuffers::Vector<const Geometry::Vector3DAlt *> *mutable_vectors_alt() {
|
||||
return GetPointer<flatbuffers::Vector<const Geometry::Vector3DAlt *> *>(VT_VECTORS_ALT);
|
||||
}
|
||||
bool Verify(flatbuffers::Verifier &verifier) const {
|
||||
return VerifyTableStart(verifier) &&
|
||||
VerifyOffset(verifier, VT_VECTORS) &&
|
||||
verifier.VerifyVector(vectors()) &&
|
||||
VerifyOffset(verifier, VT_VECTORS_ALT) &&
|
||||
verifier.VerifyVector(vectors_alt()) &&
|
||||
verifier.EndTable();
|
||||
}
|
||||
ApplicationDataT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
|
||||
@ -99,6 +154,9 @@ struct ApplicationDataBuilder {
|
||||
void add_vectors(flatbuffers::Offset<flatbuffers::Vector<const Geometry::Vector3D *>> vectors) {
|
||||
fbb_.AddOffset(ApplicationData::VT_VECTORS, vectors);
|
||||
}
|
||||
void add_vectors_alt(flatbuffers::Offset<flatbuffers::Vector<const Geometry::Vector3DAlt *>> vectors_alt) {
|
||||
fbb_.AddOffset(ApplicationData::VT_VECTORS_ALT, vectors_alt);
|
||||
}
|
||||
explicit ApplicationDataBuilder(flatbuffers::FlatBufferBuilder &_fbb)
|
||||
: fbb_(_fbb) {
|
||||
start_ = fbb_.StartTable();
|
||||
@ -112,19 +170,24 @@ struct ApplicationDataBuilder {
|
||||
|
||||
inline flatbuffers::Offset<ApplicationData> CreateApplicationData(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
flatbuffers::Offset<flatbuffers::Vector<const Geometry::Vector3D *>> vectors = 0) {
|
||||
flatbuffers::Offset<flatbuffers::Vector<const Geometry::Vector3D *>> vectors = 0,
|
||||
flatbuffers::Offset<flatbuffers::Vector<const Geometry::Vector3DAlt *>> vectors_alt = 0) {
|
||||
ApplicationDataBuilder builder_(_fbb);
|
||||
builder_.add_vectors_alt(vectors_alt);
|
||||
builder_.add_vectors(vectors);
|
||||
return builder_.Finish();
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<ApplicationData> CreateApplicationDataDirect(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
const std::vector<Geometry::Vector3D> *vectors = nullptr) {
|
||||
const std::vector<Geometry::Vector3D> *vectors = nullptr,
|
||||
const std::vector<Geometry::Vector3DAlt> *vectors_alt = nullptr) {
|
||||
auto vectors__ = vectors ? _fbb.CreateVectorOfStructs<Geometry::Vector3D>(*vectors) : 0;
|
||||
auto vectors_alt__ = vectors_alt ? _fbb.CreateVectorOfStructs<Geometry::Vector3DAlt>(*vectors_alt) : 0;
|
||||
return Geometry::CreateApplicationData(
|
||||
_fbb,
|
||||
vectors__);
|
||||
vectors__,
|
||||
vectors_alt__);
|
||||
}
|
||||
|
||||
flatbuffers::Offset<ApplicationData> CreateApplicationData(flatbuffers::FlatBufferBuilder &_fbb, const ApplicationDataT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
|
||||
@ -139,6 +202,7 @@ inline void ApplicationData::UnPackTo(ApplicationDataT *_o, const flatbuffers::r
|
||||
(void)_o;
|
||||
(void)_resolver;
|
||||
{ auto _e = vectors(); if (_e) { _o->vectors.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vectors[_i] = flatbuffers::UnPack(*_e->Get(_i)); } } }
|
||||
{ auto _e = vectors_alt(); if (_e) { _o->vectors_alt.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vectors_alt[_i] = flatbuffers::UnPackVector3DAlt(*_e->Get(_i)); } } }
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<ApplicationData> ApplicationData::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ApplicationDataT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
|
||||
@ -149,10 +213,12 @@ inline flatbuffers::Offset<ApplicationData> CreateApplicationData(flatbuffers::F
|
||||
(void)_rehasher;
|
||||
(void)_o;
|
||||
struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ApplicationDataT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
|
||||
auto _vectors = _o->vectors.size() ? _fbb.CreateVectorOfNativeStructs<Geometry::Vector3D>(_o->vectors) : 0;
|
||||
auto _vectors = _o->vectors.size() ? _fbb.CreateVectorOfNativeStructs<Geometry::Vector3D, Native::Vector3D>(_o->vectors) : 0;
|
||||
auto _vectors_alt = _o->vectors_alt.size() ? _fbb.CreateVectorOfNativeStructs<Geometry::Vector3DAlt, Native::Vector3D>(_o->vectors_alt, flatbuffers::PackVector3DAlt) : 0;
|
||||
return Geometry::CreateApplicationData(
|
||||
_fbb,
|
||||
_vectors);
|
||||
_vectors,
|
||||
_vectors_alt);
|
||||
}
|
||||
|
||||
inline const flatbuffers::TypeTable *Vector3DTypeTable() {
|
||||
@ -173,18 +239,39 @@ inline const flatbuffers::TypeTable *Vector3DTypeTable() {
|
||||
return &tt;
|
||||
}
|
||||
|
||||
inline const flatbuffers::TypeTable *ApplicationDataTypeTable() {
|
||||
inline const flatbuffers::TypeTable *Vector3DAltTypeTable() {
|
||||
static const flatbuffers::TypeCode type_codes[] = {
|
||||
{ flatbuffers::ET_SEQUENCE, 1, 0 }
|
||||
};
|
||||
static const flatbuffers::TypeFunction type_refs[] = {
|
||||
Geometry::Vector3DTypeTable
|
||||
{ flatbuffers::ET_FLOAT, 0, -1 },
|
||||
{ flatbuffers::ET_FLOAT, 0, -1 },
|
||||
{ flatbuffers::ET_FLOAT, 0, -1 }
|
||||
};
|
||||
static const int64_t values[] = { 0, 4, 8, 12 };
|
||||
static const char * const names[] = {
|
||||
"vectors"
|
||||
"a",
|
||||
"b",
|
||||
"c"
|
||||
};
|
||||
static const flatbuffers::TypeTable tt = {
|
||||
flatbuffers::ST_TABLE, 1, type_codes, type_refs, nullptr, nullptr, names
|
||||
flatbuffers::ST_STRUCT, 3, type_codes, nullptr, nullptr, values, names
|
||||
};
|
||||
return &tt;
|
||||
}
|
||||
|
||||
inline const flatbuffers::TypeTable *ApplicationDataTypeTable() {
|
||||
static const flatbuffers::TypeCode type_codes[] = {
|
||||
{ flatbuffers::ET_SEQUENCE, 1, 0 },
|
||||
{ flatbuffers::ET_SEQUENCE, 1, 1 }
|
||||
};
|
||||
static const flatbuffers::TypeFunction type_refs[] = {
|
||||
Geometry::Vector3DTypeTable,
|
||||
Geometry::Vector3DAltTypeTable
|
||||
};
|
||||
static const char * const names[] = {
|
||||
"vectors",
|
||||
"vectors_alt"
|
||||
};
|
||||
static const flatbuffers::TypeTable tt = {
|
||||
flatbuffers::ST_TABLE, 2, type_codes, type_refs, nullptr, nullptr, names
|
||||
};
|
||||
return &tt;
|
||||
}
|
||||
|
@ -10,4 +10,12 @@ Geometry::Vector3D Pack(const Native::Vector3D &obj) {
|
||||
const Native::Vector3D UnPack(const Geometry::Vector3D &obj) {
|
||||
return Native::Vector3D(obj.x(), obj.y(), obj.z());
|
||||
}
|
||||
|
||||
Geometry::Vector3DAlt PackVector3DAlt(const Native::Vector3D &obj) {
|
||||
return Geometry::Vector3DAlt(obj.x, obj.y, obj.z);
|
||||
}
|
||||
|
||||
const Native::Vector3D UnPackVector3DAlt(const Geometry::Vector3DAlt &obj) {
|
||||
return Native::Vector3D(obj.a(), obj.b(), obj.c());
|
||||
}
|
||||
} // namespace flatbuffers
|
||||
|
@ -22,11 +22,14 @@ struct Vector3D {
|
||||
|
||||
namespace Geometry {
|
||||
struct Vector3D;
|
||||
}
|
||||
struct Vector3DAlt;
|
||||
} // namespace Geometry
|
||||
|
||||
namespace flatbuffers {
|
||||
Geometry::Vector3D Pack(const Native::Vector3D &obj);
|
||||
const Native::Vector3D UnPack(const Geometry::Vector3D &obj);
|
||||
Geometry::Vector3DAlt PackVector3DAlt(const Native::Vector3D &obj);
|
||||
const Native::Vector3D UnPackVector3DAlt(const Geometry::Vector3DAlt &obj);
|
||||
} // namespace flatbuffers
|
||||
|
||||
#endif // VECTOR3D_PACK_H
|
||||
|
@ -3525,10 +3525,13 @@ void NativeTypeTest() {
|
||||
|
||||
Geometry::ApplicationDataT src_data;
|
||||
src_data.vectors.reserve(N);
|
||||
src_data.vectors_alt.reserve(N);
|
||||
|
||||
for (int i = 0; i < N; ++i) {
|
||||
src_data.vectors.push_back(
|
||||
Native::Vector3D(10 * i + 0.1f, 10 * i + 0.2f, 10 * i + 0.3f));
|
||||
src_data.vectors_alt.push_back(
|
||||
Native::Vector3D(20 * i + 0.1f, 20 * i + 0.2f, 20 * i + 0.3f));
|
||||
}
|
||||
|
||||
flatbuffers::FlatBufferBuilder fbb;
|
||||
@ -3537,10 +3540,15 @@ void NativeTypeTest() {
|
||||
auto dstDataT = Geometry::UnPackApplicationData(fbb.GetBufferPointer());
|
||||
|
||||
for (int i = 0; i < N; ++i) {
|
||||
Native::Vector3D &v = dstDataT->vectors[i];
|
||||
const Native::Vector3D &v = dstDataT->vectors[i];
|
||||
TEST_EQ(v.x, 10 * i + 0.1f);
|
||||
TEST_EQ(v.y, 10 * i + 0.2f);
|
||||
TEST_EQ(v.z, 10 * i + 0.3f);
|
||||
|
||||
const Native::Vector3D &v2 = dstDataT->vectors_alt[i];
|
||||
TEST_EQ(v2.x, 20 * i + 0.1f);
|
||||
TEST_EQ(v2.y, 20 * i + 0.2f);
|
||||
TEST_EQ(v2.z, 20 * i + 0.3f);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user