diff options
author | Khoi Dinh Trinh <khoidinhtrinh@gmail.com> | 2020-04-09 09:53:16 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-09 09:53:16 -0700 |
commit | 003e164057e6d4908d87c379c79a9ebdcb8bbc26 (patch) | |
tree | 7c88e490dc117fbd320481a6dd2f0333ec64aa46 | |
parent | 21cf300f4cc4f282dec869b23bf288e61578f0d0 (diff) | |
download | flatbuffers-003e164057e6d4908d87c379c79a9ebdcb8bbc26.tar.gz flatbuffers-003e164057e6d4908d87c379c79a9ebdcb8bbc26.tar.bz2 flatbuffers-003e164057e6d4908d87c379c79a9ebdcb8bbc26.zip |
[TS] Add Obj API (#5788)
* added basic code
* backup work
* got class property to work
* backup progress
* implementented fmt for creating code
* added docs for genFieldUtils
* back up work
* added base helper js func
* added union js code
* added unpackTo and base for pack
* added pack code
* added null check for packing struct list
* passes compile test
* fixed some spacing of generated functions
* added annotations for constructors
* added obj api unpack test
* tested pack to work
* merge branch
* separated js and ts test
* fixed union signature to include string
* fixed generator to support string union
* hardcoded fb builder name
* refactored struct vector creation
* work around createLong
* handle default value in constructor
* update typescript docs
* added notes about import flag
* fixed formatting stuffs
* undo TypescriptTest change
* refactored fmt
* updated generated code
* remove ignoring union_vector for js
* revert changes for .project
* revert changes for package.json
* don't generate js in ts test
* fixed android project file
* removed unused js function
* removed package-lock.json
* adjust createObjList to new signature
* changed regex to callback style
* fixed package.json
* used existing func for generating annotation
* changed ternary to !!
* added return type for lambda
* removed callback style for obj api generator
* fixed js file indentation
* removed unused header
* added tests for string only union
* handle string only union and refactor union conv func
* updated generated ts files
* renamed union conv func
* made js test create files like other languages
* removed union string only handling
* don't allow null in createObjectOffsetList
* updated generated ts code
* changed the line that triggers Windows build errors
* hopefully fix CI error
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | docs/source/TypeScriptUsage.md | 32 | ||||
-rw-r--r-- | js/flatbuffers.js | 115 | ||||
-rw-r--r-- | src/idl_gen_js_ts.cpp | 581 | ||||
-rw-r--r-- | tests/JavaScriptTest.js | 71 | ||||
-rwxr-xr-x | tests/JavaScriptTest.sh | 6 | ||||
-rw-r--r-- | tests/JavaScriptUnionVectorTest.js | 128 | ||||
-rwxr-xr-x | tests/TypeScriptTest.sh | 13 | ||||
-rw-r--r-- | tests/monster_test_generated.ts | 826 | ||||
-rw-r--r-- | tests/namespace_test/namespace_test1_generated.ts | 80 | ||||
-rw-r--r-- | tests/namespace_test/namespace_test2_generated.ts | 123 | ||||
-rw-r--r-- | tests/union_vector/union_vector_generated.ts | 238 |
12 files changed, 2158 insertions, 56 deletions
@@ -72,6 +72,7 @@ tests/monsterdata_rust_wire.mon tests/unicode_test.mon tests/ts/ tests/php/ +tests/js/ CMakeLists.txt.user CMakeScripts/** CTestTestfile.cmake diff --git a/docs/source/TypeScriptUsage.md b/docs/source/TypeScriptUsage.md index 02aa239e..0b9739ee 100644 --- a/docs/source/TypeScriptUsage.md +++ b/docs/source/TypeScriptUsage.md @@ -60,6 +60,38 @@ Now you can access values like this: let pos = monster.pos(); ~~~ +## 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 +(requiring pre-order construction of all data, and making mutation harder). + +For times when efficiency is less important a more convenient object based API +can be used (through `--gen-object-api`) that is able to unpack & pack a +FlatBuffer into objects and standard TS types. + +**When using the obj based API, the flatbuffers import need to be in the global namespace if you don't have `--no-fb-import` enabled** since creating default values require accessing the `flatbuffers.js` file. + +To use: + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.ts} + // Autogenerated class from table Monster. + let monsterobj = new MonsterT(); + + // Deserialize from buffer into object. + Monster.getRootAsMonster(flatbuffer).unpackTo(monsterobj); + // or + let monsterobj = Monster.getRootAsMonster(flatbuffer).unpack(); + + // Update object directly like a regular TS class instance. + console.log(monsterobj.name); + monsterobj.name = "Bob"; + + // Serialize into new flatbuffer. + let fbb = new flatbuffers.Builder(1); + Monster.finishMonsterBuffer(fbb, monsterobj.pack(fbb)); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ## Text parsing FlatBuffers in TypeScript There currently is no support for parsing text (Schema's and JSON) directly diff --git a/js/flatbuffers.js b/js/flatbuffers.js index 74cd35ab..596da800 100644 --- a/js/flatbuffers.js +++ b/js/flatbuffers.js @@ -55,6 +55,15 @@ flatbuffers.FILE_IDENTIFIER_LENGTH = 4; flatbuffers.SIZE_PREFIX_LENGTH = 4; /** + * @param {number} low + * @param {number} high + * @returns {flatbuffers.Long} + */ +flatbuffers.createLong = function(low, high) { + return flatbuffers.Long.create(low, high); +}; + +/** * @enum {number} */ flatbuffers.Encoding = { @@ -830,6 +839,52 @@ flatbuffers.Builder.prototype.createString = function(s) { flatbuffers.Builder.prototype.createLong = function(low, high) { return flatbuffers.Long.create(low, high); }; + +/** + * A helper function to pack an object + * + * @returns offset of obj + */ +flatbuffers.Builder.prototype.createObjectOffset = function(obj) { + if(obj === null) { + return 0 + } + + if(typeof obj === 'string') { + return this.createString(obj); + } else { + return obj.pack(this); + } +} + +/** + * A helper function to pack a list of object + * + * @returns list of offsets of each non null object + */ +flatbuffers.Builder.prototype.createObjectOffsetList = function(list) { + let ret = []; + + for(let i = 0; i < list.length; ++i) { + let val = list[i]; + + if(val !== null) { + ret.push(this.createObjectOffset(val)); + } else { + throw new Error( + 'FlatBuffers: Argument for createObjectOffsetList cannot contain null.'); + } + } + + return ret; +}; + +flatbuffers.Builder.prototype.createStructOffsetList = function(list, startFunc) { + startFunc(this, list.length); + this.createObjectOffsetList(list); + return this.endVector(); +} + //////////////////////////////////////////////////////////////////////////////// /// @cond FLATBUFFERS_INTERNAL /** @@ -1196,6 +1251,24 @@ flatbuffers.ByteBuffer.prototype.__string = function(offset, opt_encoding) { }; /** + * Handle unions that can contain string as its member, if a Table-derived type then initialize it, + * if a string then return a new one + * + * WARNING: strings are immutable in JS so we can't change the string that the user gave us, this + * makes the behaviour of __union_with_string different compared to __union + * + * @param {flatbuffers.Table|string} o + * @param {number} offset + * @returns {flatbuffers.Table|string} + */ +flatbuffers.ByteBuffer.prototype.__union_with_string = function(o, offset) { + if(typeof o === 'string') { + return this.__string(offset); + } + return this.__union(o, offset); +}; + +/** * Retrieve the relative offset stored at "offset" * @param {number} offset * @returns {number} @@ -1252,6 +1325,48 @@ flatbuffers.ByteBuffer.prototype.createLong = function(low, high) { return flatbuffers.Long.create(low, high); }; +/** + * A helper function for generating list for obj api + * @param listAccessor function that accepts an index and return data at that index + * @param {number} listLength + * @returns {any[]} + */ +flatbuffers.ByteBuffer.prototype.createScalarList = function(listAccessor, listLength) { + let ret = []; + for(let i = 0; i < listLength; ++i) { + if(listAccessor(i) !== null) { + ret.push(listAccessor(i)); + } + } + + return ret; +}; + +/** + * This function is here only to get around typescript type system + */ +flatbuffers.ByteBuffer.prototype.createStringList = function(listAccessor, listLength) { + return this.createScalarList(listAccessor, listLength); +}; + +/** + * A helper function for generating list for obj api + * @param listAccessor function that accepts an index and return data at that index + * @param listLength {number} listLength + * @param res any[] result list + */ +flatbuffers.ByteBuffer.prototype.createObjList = function(listAccessor, listLength) { + let ret = []; + for(let i = 0; i < listLength; ++i) { + let val = listAccessor(i); + if(val !== null) { + ret.push(val.unpack()); + } + } + + return ret; +}; + // Exports for Node.js and RequireJS this.flatbuffers = flatbuffers; diff --git a/src/idl_gen_js_ts.cpp b/src/idl_gen_js_ts.cpp index 6e459343..199e20ab 100644 --- a/src/idl_gen_js_ts.cpp +++ b/src/idl_gen_js_ts.cpp @@ -374,9 +374,16 @@ class JsTsGenerator : public BaseGenerator { std::make_pair(ev.union_type.struct_def->file, std::move(desc))); } } + code += "};"; - if (lang_.language == IDLOptions::kTs && !ns.empty()) { code += "}"; } - code += "};\n\n"; + if (lang_.language == IDLOptions::kTs) { + if (enum_def.is_union) { + code += GenUnionConvFunc(enum_def.underlying_type); + } + if (!ns.empty()) { code += "\n}"; } + } + + code += "\n\n"; } static std::string GenType(const Type &type) { @@ -404,7 +411,12 @@ class JsTsGenerator : public BaseGenerator { switch (type.base_type) { case BASE_TYPE_STRING: return GenBBAccess() + ".__string" + arguments; case BASE_TYPE_STRUCT: return GenBBAccess() + ".__struct" + arguments; - case BASE_TYPE_UNION: return GenBBAccess() + ".__union" + arguments; + case BASE_TYPE_UNION: + if (!UnionHasStringType(*type.enum_def) || + lang_.language == IDLOptions::kJs) { + return GenBBAccess() + ".__union" + arguments; + } + return GenBBAccess() + ".__union_with_string" + arguments; case BASE_TYPE_VECTOR: return GenGetter(type.VectorType(), arguments); default: { auto getter = @@ -426,7 +438,8 @@ class JsTsGenerator : public BaseGenerator { } std::string GenDefaultValue(const Value &value, const std::string &context) { - if (value.type.enum_def) { + if (value.type.enum_def && value.type.base_type != BASE_TYPE_UNION && + value.type.base_type != BASE_TYPE_VECTOR) { if (auto val = value.type.enum_def->FindByValue(value.constant)) { if (lang_.language == IDLOptions::kTs) { return GenPrefixedTypeName(WrapInNameSpace(*value.type.enum_def), @@ -446,7 +459,13 @@ class JsTsGenerator : public BaseGenerator { switch (value.type.base_type) { case BASE_TYPE_BOOL: return value.constant == "0" ? "false" : "true"; - case BASE_TYPE_STRING: return "null"; + case BASE_TYPE_STRING: + case BASE_TYPE_UNION: + case BASE_TYPE_STRUCT: { + return "null"; + } + + case BASE_TYPE_VECTOR: return "[]"; case BASE_TYPE_LONG: case BASE_TYPE_ULONG: { @@ -549,6 +568,10 @@ class JsTsGenerator : public BaseGenerator { return GenFileNamespacePrefix(file) + "." + typeName; } + std::string GenFullNameSpace(const Definition &def, const std::string &file) { + return GenPrefixedTypeName(GetNameSpace(def), file); + } + void GenStructArgs(const StructDef &struct_def, std::string *annotations, std::string *arguments, const std::string &nameprefix) { for (auto it = struct_def.fields.vec.begin(); @@ -668,6 +691,527 @@ class JsTsGenerator : public BaseGenerator { } } + static std::string GetObjApiClassName(const StructDef &sd, + const IDLOptions &opts) { + return GetObjApiClassName(sd.name, opts); + } + + static std::string GetObjApiClassName(const std::string &name, + const IDLOptions &opts) { + return opts.object_prefix + name + opts.object_suffix; + } + + bool UnionHasStringType(const EnumDef &union_enum) { + return std::any_of(union_enum.Vals().begin(), union_enum.Vals().end(), + [](const EnumVal *ev) { + return !(ev->IsZero()) && + (ev->union_type.base_type == BASE_TYPE_STRING); + }); + } + + std::string GenUnionGenericTypeTS(const EnumDef &union_enum) { + return std::string("T") + (UnionHasStringType(union_enum) ? "|string" : ""); + } + + std::string GenUnionTypeTS(const EnumDef &union_enum) { + std::string ret; + std::set<std::string> type_list; + + for (auto it = union_enum.Vals().begin(); it != union_enum.Vals().end(); + ++it) { + const auto &ev = **it; + if (ev.IsZero()) { continue; } + + std::string type = ""; + if (ev.union_type.base_type == BASE_TYPE_STRING) { + type = "string"; // no need to wrap string type in namespace + } else if (ev.union_type.base_type == BASE_TYPE_STRUCT) { + type = GenPrefixedTypeName(WrapInNameSpace(*(ev.union_type.struct_def)), + union_enum.file); + } else { + FLATBUFFERS_ASSERT(false); + } + type_list.insert(type); + } + + for (auto it = type_list.begin(); it != type_list.end(); ++it) { + ret += *it + ((std::next(it) == type_list.end()) ? "" : "|"); + } + + return ret; + } + + // Generate a TS union type based on a union's enum + std::string GenObjApiUnionTypeTS(const IDLOptions &opts, + const EnumDef &union_enum) { + std::string ret = ""; + std::set<std::string> type_list; + + for (auto it = union_enum.Vals().begin(); it != union_enum.Vals().end(); + ++it) { + const auto &ev = **it; + if (ev.IsZero()) { continue; } + + std::string type = ""; + if (ev.union_type.base_type == BASE_TYPE_STRING) { + type = "string"; // no need to wrap string type in namespace + } else if (ev.union_type.base_type == BASE_TYPE_STRUCT) { + type = GenPrefixedTypeName( + GetObjApiClassName(WrapInNameSpace(*(ev.union_type.struct_def)), + opts), + union_enum.file); + } else { + FLATBUFFERS_ASSERT(false); + } + type_list.insert(type); + } + + size_t totalPrinted = 0; + for (auto it = type_list.begin(); it != type_list.end(); ++it) { + ++totalPrinted; + ret += *it + ((totalPrinted == type_list.size()) ? "" : "|"); + } + + return ret; + } + + std::string GenUnionConvFuncName(const EnumDef &enum_def) { + return "unionTo" + enum_def.name; + } + + std::string GenUnionListConvFuncName(const EnumDef &enum_def) { + return "unionListTo" + enum_def.name; + } + + std::string GenUnionConvFunc(const Type &union_type) { + if (union_type.enum_def) { + const auto &enum_def = *union_type.enum_def; + + const auto valid_union_type = GenUnionTypeTS(enum_def); + const auto valid_union_type_with_null = valid_union_type + "|null"; + + auto ret = "\n\nexport function " + GenUnionConvFuncName(enum_def) + + "(\n type: " + enum_def.name + + ",\n accessor: (obj:" + valid_union_type + ") => " + + valid_union_type_with_null + + "\n): " + valid_union_type_with_null + " {\n"; + + const auto enum_type = GenPrefixedTypeName( + WrapInNameSpace(*(union_type.enum_def)), union_type.enum_def->file); + const auto &union_enum = *(union_type.enum_def); + + const auto union_enum_loop = [&](const std::string &accessor_str) { + ret += " switch(" + enum_type + "[type]) {\n"; + ret += " case 'NONE': return null; \n"; + + for (auto it = union_enum.Vals().begin(); it != union_enum.Vals().end(); + ++it) { + const auto &ev = **it; + if (ev.IsZero()) { continue; } + + ret += " case '" + ev.name + "': "; + + if (ev.union_type.base_type == BASE_TYPE_STRING) { + ret += "return " + accessor_str + "'') as string;"; + } else if (ev.union_type.base_type == BASE_TYPE_STRUCT) { + const auto type = GenPrefixedTypeName( + WrapInNameSpace(*(ev.union_type.struct_def)), union_enum.file); + ret += "return " + accessor_str + "new " + type + "())! as " + + type + ";"; + } else { + FLATBUFFERS_ASSERT(false); + } + ret += "\n"; + } + + ret += " default: return null;\n"; + ret += " }\n"; + }; + + union_enum_loop("accessor("); + ret += "}"; + + ret += "\n\nexport function " + GenUnionListConvFuncName(enum_def) + + "(\n type: " + enum_def.name + + ", \n accessor: (index: number, obj:" + valid_union_type + + ") => " + valid_union_type_with_null + + ", \n index: number\n): " + valid_union_type_with_null + " {\n"; + union_enum_loop("accessor(index, "); + ret += "}"; + + return ret; + } + FLATBUFFERS_ASSERT(0); + return ""; + } + + // Used for generating a short function that returns the correct class + // based on union enum type. Assume the context is inside the non object api + // type + std::string GenUnionValTS(const std::string &field_name, + const Type &union_type, + const bool is_array = false) { + if (union_type.enum_def) { + const auto &enum_def = *union_type.enum_def; + const auto enum_type = + GenPrefixedTypeName(WrapInNameSpace(enum_def), enum_def.file); + const std::string union_accessor = "this." + field_name; + + const auto union_has_string = UnionHasStringType(enum_def); + const auto field_binded_method = "this." + field_name + ".bind(this)"; + + std::string ret = ""; + + if (!is_array) { + const auto conversion_function = + GenPrefixedTypeName(WrapInNameSpace(enum_def.defined_namespace, + GenUnionConvFuncName(enum_def)), + enum_def.file); + const auto target_enum = "this." + field_name + "Type()"; + + ret = "(() => {\n"; + ret += " let temp = " + conversion_function + "(" + target_enum + + ", " + field_binded_method + ");\n"; + ret += " if(temp === null) { return null; }\n"; + ret += union_has_string + ? " if(typeof temp === 'string') { return temp; }\n" + : ""; + ret += " return temp.unpack()\n"; + ret += " })()"; + } else { + const auto conversion_function = GenPrefixedTypeName( + WrapInNameSpace(enum_def.defined_namespace, + GenUnionListConvFuncName(enum_def)), + enum_def.file); + const auto target_enum_accesor = "this." + field_name + "Type"; + const auto target_enum_length = target_enum_accesor + "Length()"; + + ret = "(() => {\n"; + ret += " let ret = [];\n"; + ret += " for(let targetEnumIndex = 0; targetEnumIndex < " + + target_enum_length + + "; " + "++targetEnumIndex) {\n"; + ret += " let targetEnum = " + target_enum_accesor + + "(targetEnumIndex);\n"; + ret += " if(targetEnum === null || " + enum_type + + "[targetEnum!] === 'NONE') { " + "continue; }\n\n"; + ret += " let temp = " + conversion_function + "(targetEnum, " + + field_binded_method + ", targetEnumIndex);\n"; + ret += " if(temp === null) { continue; }\n"; + ret += union_has_string ? " if(typeof temp === 'string') { " + "ret.push(temp); continue; }\n" + : ""; + ret += " ret.push(temp.unpack());\n"; + ret += " }\n"; + ret += " return ret;\n"; + ret += " })()"; + } + + return ret; + } + + FLATBUFFERS_ASSERT(0); + return ""; + } + + std::string GenNullCheckConditional(const std::string &nullCheckVar, + const std::string &trueVal, + const std::string &falseVal = "null") { + return "(" + nullCheckVar + " !== null ? " + trueVal + " : " + falseVal + + ")"; + } + + std::string GenStructMemberValueTS(const StructDef &struct_def, + const std::string &prefix, + const std::string &delimiter, + const bool nullCheck = true) { + std::string ret; + for (auto it = struct_def.fields.vec.begin(); + it != struct_def.fields.vec.end(); ++it) { + auto &field = **it; + + const auto curr_member_accessor = + prefix + "." + MakeCamel(field.name, false); + if (IsStruct(field.value.type)) { + ret += GenStructMemberValueTS(*field.value.type.struct_def, + curr_member_accessor, delimiter); + } else { + if (nullCheck) { + ret += + "(" + prefix + " === null ? 0 : " + curr_member_accessor + "!)"; + } else { + ret += curr_member_accessor; + } + } + + if (std::next(it) != struct_def.fields.vec.end()) { ret += delimiter; } + } + + return ret; + } + + void GenObjApi(const Parser &parser, StructDef &struct_def, + std::string &obj_api_unpack_func, std::string &obj_api_class) { + const auto class_name = GetObjApiClassName(struct_def, parser.opts); + + std::string unpack_func = + "\n/**\n * " + GenTypeAnnotation(kReturns, class_name, "") + + " */\nunpack(): " + class_name + " {\n return new " + class_name + + "(" + (struct_def.fields.vec.empty() ? "" : "\n"); + std::string unpack_to_func = + "/**\n * " + GenTypeAnnotation(kParam, class_name, "_o") + + " */\nunpackTo(_o: " + class_name + "): void {" + + +(struct_def.fields.vec.empty() ? "" : "\n"); + + std::string constructor_annotation = "/**\n * @constructor"; + constructor_annotation += (struct_def.fields.vec.empty() ? "" : "\n"); + std::string constructor_func = "constructor("; + constructor_func += (struct_def.fields.vec.empty() ? "" : "\n"); + + std::string pack_func_prototype = + "/**\n * " + + GenTypeAnnotation(kParam, "flatbuffers.Builder", "builder") + " * " + + GenTypeAnnotation(kReturns, "flatbuffers.Offset", "") + + " */\npack(builder:flatbuffers.Builder): flatbuffers.Offset {\n"; + std::string pack_func_offset_decl; + std::string pack_func_create_call = + " return " + Verbose(struct_def) + ".create" + Verbose(struct_def) + + "(builder" + (struct_def.fields.vec.empty() ? "" : ",\n "); + if (struct_def.fixed) { + // when packing struct, nested struct's members instead of the struct's + // offset are used + pack_func_create_call += + GenStructMemberValueTS(struct_def, "this", ",\n ", false) + "\n "; + } + + for (auto it = struct_def.fields.vec.begin(); + it != struct_def.fields.vec.end(); ++it) { + auto &field = **it; + if (field.deprecated) continue; + + const auto field_name = MakeCamel(field.name, false); + const std::string field_binded_method = + "this." + field_name + ".bind(this)"; + + std::string field_val; + std::string field_type; + // a string that declares a variable containing the + // offset for things that can't be generated inline + // empty otw + std::string field_offset_decl; + // a string that contains values for things that can be created inline or + // the variable name from field_offset_decl + std::string field_offset_val; + const auto field_default_val = + GenDefaultValue(field.value, "flatbuffers"); + + // Emit a scalar field + if (IsScalar(field.value.type.base_type) || + field.value.type.base_type == BASE_TYPE_STRING) { + if (field.value.type.enum_def) { + field_type += + GenPrefixedTypeName(GenTypeName(field.value.type, false, true), + field.value.type.enum_def->file); + } else { + field_type += GenTypeName(field.value.type, false, true); + } + field_val = "this." + field_name + "()"; + + if (field.value.type.base_type != BASE_TYPE_STRING) { + field_offset_val = "this." + field_name; + } else { + field_offset_decl = GenNullCheckConditional( + "this." + field_name, + "builder.createString(this." + field_name + "!)", "0"); + } + } + + // Emit an object field + else { + auto is_vector = false; + switch (field.value.type.base_type) { + case BASE_TYPE_STRUCT: { + const auto &sd = *field.value.type.struct_def; + field_type += GenPrefixedTypeName( + WrapInNameSpace(sd.defined_namespace, + GetObjApiClassName(sd, parser.opts)), + field.value.type.struct_def->file); + + const std::string field_accessor = "this." + field_name + "()"; + field_val = GenNullCheckConditional(field_accessor, + field_accessor + "!.unpack()"); + field_offset_val = GenNullCheckConditional( + "this." + field_name, "this." + field_name + "!.pack(builder)", + "0"); + + break; + } + + case BASE_TYPE_VECTOR: { + auto vectortype = field.value.type.VectorType(); + auto vectortypename = GenTypeName(vectortype, false); + is_vector = true; + + field_type = "("; + + switch (vectortype.base_type) { + case BASE_TYPE_STRUCT: { + const auto &sd = *field.value.type.struct_def; + field_type += GenPrefixedTypeName( + WrapInNameSpace(sd.defined_namespace, + GetObjApiClassName(sd, parser.opts)), + field.value.type.struct_def->file); + field_type += ")[]"; + + field_val = GenBBAccess() + ".createObjList(" + + field_binded_method + ", this." + field_name + + "Length())"; + + if (sd.fixed) { + field_offset_decl = "builder.createStructOffsetList(this." + + field_name + ", " + Verbose(struct_def) + + ".start" + MakeCamel(field_name) + + "Vector)"; + } else { + field_offset_decl = + Verbose(struct_def) + ".create" + MakeCamel(field_name) + + "Vector(builder, builder.createObjectOffsetList(" + + "this." + field_name + "))"; + } + + break; + } + + case BASE_TYPE_STRING: { + field_type += "string)[]"; + field_val = GenBBAccess() + ".createStringList(" + + field_binded_method + ", this." + field_name + + "Length())"; + field_offset_decl = + Verbose(struct_def) + ".create" + MakeCamel(field_name) + + "Vector(builder, builder.createObjectOffsetList(" + + "this." + field_name + "))"; + break; + } + + case BASE_TYPE_UNION: { + field_type += + GenObjApiUnionTypeTS(parser.opts, *(vectortype.enum_def)); + field_type += ")[]"; + field_val = GenUnionValTS(field_name, vectortype, true); + + field_offset_decl = + Verbose(struct_def) + ".create" + MakeCamel(field_name) + + "Vector(builder, builder.createObjectOffsetList(" + + "this." + field_name + "))"; + + break; + } + default: { + if (vectortype.enum_def) { + field_type += + GenPrefixedTypeName(GenTypeName(vectortype, false, true), + vectortype.enum_def->file); + } else { + field_type += vectortypename; + } + field_type += ")[]"; + field_val = GenBBAccess() + ".createScalarList(" + + field_binded_method + ", this." + field_name + + "Length())"; + + field_offset_decl = Verbose(struct_def) + ".create" + + MakeCamel(field_name) + + "Vector(builder, this." + field_name + ")"; + + break; + } + } + + break; + } + + case BASE_TYPE_UNION: { + field_type += + GenObjApiUnionTypeTS(parser.opts, *(field.value.type.enum_def)); + + field_val = GenUnionValTS(field_name, field.value.type); + field_offset_decl = + "builder.createObjectOffset(this." + field_name + ")"; + break; + } + + default: FLATBUFFERS_ASSERT(0); break; + } + + // length 0 vector is simply empty instead of null + field_type += is_vector ? "" : "|null"; + } + + if (!field_offset_decl.empty()) { + field_offset_decl = + " const " + field_name + " = " + field_offset_decl + ";"; + } + if (field_offset_val.empty()) { field_offset_val = field_name; } + + unpack_func += " " + field_val; + unpack_to_func += " _o." + field_name + " = " + field_val + ";"; + + constructor_annotation += + " * " + GenTypeAnnotation(kParam, field_type, field_name, false); + constructor_func += " public " + field_name + ": " + field_type + " = " + + field_default_val; + + if (!struct_def.fixed) { + if (!field_offset_decl.empty()) { + pack_func_offset_decl += field_offset_decl + "\n"; + } + pack_func_create_call += field_offset_val; + } + + if (std::next(it) != struct_def.fields.vec.end()) { + constructor_annotation += "\n"; + constructor_func += ",\n"; + + if (!struct_def.fixed) { pack_func_create_call += ",\n "; } + + unpack_func += ",\n"; + unpack_to_func += "\n"; + } else { + constructor_func += "\n"; + if (!struct_def.fixed) { + pack_func_offset_decl += (pack_func_offset_decl.empty() ? "" : "\n"); + pack_func_create_call += "\n "; + } + + unpack_func += "\n "; + unpack_to_func += "\n"; + } + } + + constructor_annotation += "\n */\n"; + constructor_func += "){};\n\n"; + + pack_func_create_call += ");"; + + obj_api_class = "\nexport class " + + GetObjApiClassName(struct_def, parser.opts) + " {\n"; + + obj_api_class += constructor_annotation + constructor_func; + + obj_api_class += pack_func_prototype + pack_func_offset_decl + + pack_func_create_call + "\n};"; + + obj_api_class += "\n}\n"; + + unpack_func += ");\n};"; + unpack_to_func += "};\n"; + + obj_api_unpack_func = unpack_func + "\n\n" + unpack_to_func; + } + // Generate an accessor struct with constructor for a flatbuffers struct. void GenStruct(const Parser &parser, StructDef &struct_def, std::string *code_ptr, std::string *exports_ptr, @@ -924,8 +1468,11 @@ class JsTsGenerator : public BaseGenerator { if (is_union) { prefix += "<T extends flatbuffers.Table>"; } prefix += "(index: number"; if (is_union) { - vectortypename = "T"; - code += prefix + ", obj:T"; + const auto union_type = + GenUnionGenericTypeTS(*(field.value.type.enum_def)); + + vectortypename = union_type; + code += prefix + ", obj:" + union_type; } else if (vectortype.base_type == BASE_TYPE_STRUCT) { vectortypename = GenPrefixedTypeName( vectortypename, vectortype.struct_def->file); @@ -1002,7 +1549,13 @@ class JsTsGenerator : public BaseGenerator { false)); if (lang_.language == IDLOptions::kTs) { code += MakeCamel(field.name, false); - code += "<T extends flatbuffers.Table>(obj:T):T|null {\n"; + + const auto &union_enum = *(field.value.type.enum_def); + const auto union_type = GenUnionGenericTypeTS(union_enum); + code += "<T extends flatbuffers.Table>(obj:" + union_type + + "):" + union_type + + "|null " + "{\n"; } else { code += object_name + ".prototype." + MakeCamel(field.name, false); @@ -1359,8 +1912,16 @@ class JsTsGenerator : public BaseGenerator { } if (lang_.language == IDLOptions::kTs) { + if (parser_.opts.generate_object_based_api) { + std::string obj_api_class; + std::string obj_api_unpack_func; + GenObjApi(parser_, struct_def, obj_api_unpack_func, obj_api_class); + + code += obj_api_unpack_func + "}\n" + obj_api_class; + } else { + code += "}\n"; + } if (!object_namespace.empty()) { code += "}\n"; } - code += "}\n"; } } @@ -1381,7 +1942,7 @@ class JsTsGenerator : public BaseGenerator { std::string Verbose(const StructDef &struct_def, const char *prefix = "") { return parser_.opts.js_ts_short_names ? "" : prefix + struct_def.name; } -}; +}; // namespace jsts } // namespace jsts bool GenerateJSTS(const Parser &parser, const std::string &path, diff --git a/tests/JavaScriptTest.js b/tests/JavaScriptTest.js index 7116daaf..8ffbed2f 100644 --- a/tests/JavaScriptTest.js +++ b/tests/JavaScriptTest.js @@ -3,8 +3,12 @@ var assert = require('assert'); var fs = require('fs'); var flatbuffers = require('../js/flatbuffers').flatbuffers; +global.flatbuffers = flatbuffers; + var MyGame = require(process.argv[2]).MyGame; +var isTsTest = !!process.env.FB_TS_TEST; + function main() { // First, let's test reading a FlatBuffer generated by C++ code: @@ -24,6 +28,10 @@ function main() { createMonster(fbb); serializeAndTest(fbb); + if(isTsTest) { + testObjApiPack(fbb); + } + // clear the builder, repeat tests var clearIterations = 100; var startingCapacity = fbb.bb.capacity(); @@ -31,6 +39,10 @@ function main() { fbb.clear(); createMonster(fbb); serializeAndTest(fbb); + + if(isTsTest) { + testObjApiPack(fbb); + } } // the capacity of our buffer shouldn't increase with the same size payload assert.strictEqual(fbb.bb.capacity(), startingCapacity); @@ -109,6 +121,56 @@ function testMutation(bb) { // TODO: There is not the availability to mutate structs or vectors. } +function testObjApiPack(fbb) { + fbb.clear(); + createMonster(fbb); + let monster_t = MyGame.Example.Monster.getRootAsMonster(fbb.dataBuffer()).unpack(); + fbb.clear(); + MyGame.Example.Monster.finishMonsterBuffer(fbb, monster_t.pack(fbb)); + serializeAndTest(fbb); +} + +function testObjApiUnpack(monster) { + assert.strictEqual(monster.hp, 80); + assert.strictEqual(monster.mana, 150); // default + + assert.strictEqual(monster.name, 'MyMonster'); + + let pos = monster.pos; + assert.strictEqual(pos.x, 1); + assert.strictEqual(pos.y, 2); + assert.strictEqual(pos.z, 3); + assert.strictEqual(pos.test1, 3); + assert.strictEqual(pos.test2, MyGame.Example.Color.Green); + let test3 = pos.test3; + assert.strictEqual(test3.a, 5); + assert.strictEqual(test3.b, 6); + + assert.strictEqual(monster.testType, MyGame.Example.Any.Monster); + let monster2 = monster.test; + assert.strictEqual(monster2 != null, true); + assert.strictEqual(monster2 instanceof MyGame.Example.MonsterT, true); + assert.strictEqual(monster2.name, 'Fred'); + + assert.strictEqual(monster.inventory.length, 5); + let invsum = 0; + for (let i = 0; i < monster.inventory.length; i++) { + invsum += monster.inventory[i]; + } + assert.strictEqual(invsum, 10); + + let test_0 = monster.test4[0]; + let test_1 = monster.test4[1]; + assert.strictEqual(monster.test4.length, 2); + assert.strictEqual(test_0.a + test_0.b + test_1.a + test_1.b, 100); + + assert.strictEqual(monster.testarrayofstring.length, 2); + assert.strictEqual(monster.testarrayofstring[0], 'test1'); + assert.strictEqual(monster.testarrayofstring[1], 'test2'); + + assert.strictEqual(monster.testbool, true); +} + function testBuffer(bb) { assert.ok(MyGame.Example.Monster.bufferHasIdentifier(bb)); @@ -158,6 +220,15 @@ function testBuffer(bb) { assert.strictEqual(monster.testarrayofstring(1), 'test2'); assert.strictEqual(monster.testbool(), true); + + if(isTsTest) { + let monster_t = monster.unpack(); + testObjApiUnpack(monster_t); + + let monster2_t = new MyGame.Example.MonsterT(); + monster.unpackTo(monster2_t); + testObjApiUnpack(monster2_t); + } } function test64bit() { diff --git a/tests/JavaScriptTest.sh b/tests/JavaScriptTest.sh index c0286a05..0762410c 100755 --- a/tests/JavaScriptTest.sh +++ b/tests/JavaScriptTest.sh @@ -16,4 +16,8 @@ pushd "$(dirname $0)" >/dev/null ../flatc -b -I include_test monster_test.fbs unicode_test.json -node JavaScriptTest ./monster_test_generated +../flatc --js -o js --gen-mutable --no-fb-import -I include_test monster_test.fbs +node JavaScriptTest ./js/monster_test_generated + +../flatc --js -o js --no-fb-import union_vector/union_vector.fbs +node JavaScriptUnionVectorTest ./js/union_vector_generated
\ No newline at end of file diff --git a/tests/JavaScriptUnionVectorTest.js b/tests/JavaScriptUnionVectorTest.js index d79669fa..f03a3279 100644 --- a/tests/JavaScriptUnionVectorTest.js +++ b/tests/JavaScriptUnionVectorTest.js @@ -3,53 +3,123 @@ var assert = require('assert'); var flatbuffers = require('../js/flatbuffers').flatbuffers; var Test = require(process.argv[2]); -function main() { - var fbb = new flatbuffers.Builder(); +var isTsTest = !!process.env.FB_TS_TEST; + +var charTypes = [ + Test.Character.Belle, + Test.Character.MuLan, + Test.Character.BookFan, +]; +if(isTsTest) { charTypes.push(Test.Character.Other); } + +function testMovieBuf(movie) { + assert.strictEqual(movie.charactersTypeLength(), charTypes.length); + assert.strictEqual(movie.charactersLength(), movie.charactersTypeLength()); + + for (var i = 0; i < charTypes.length; ++i) { + assert.strictEqual(movie.charactersType(i), charTypes[i]); + } + + var bookReader7 = movie.characters(0, new Test.BookReader()); + assert.strictEqual(bookReader7.booksRead(), 7); + + var attacker = movie.characters(1, new Test.Attacker()); + assert.strictEqual(attacker.swordAttackDamage(), 5); + + var bookReader2 = movie.characters(2, new Test.BookReader()); + assert.strictEqual(bookReader2.booksRead(), 2); + + if(isTsTest) { + var other = movie.characters(3, ''); + assert.strictEqual(other, "I am other"); + } +} + +function testMovieUnpack(movie) { + assert.strictEqual(movie.charactersType.length, charTypes.length); + assert.strictEqual(movie.characters.length, movie.charactersType.length); + + for (var i = 0; i < charTypes.length; ++i) { + assert.strictEqual(movie.charactersType[i], charTypes[i]); + } - var charTypes = [ - Test.Character.Belle, - Test.Character.MuLan, - Test.Character.BookFan, - ]; + var bookReader7 = movie.characters[0]; + assert.strictEqual(bookReader7 instanceof Test.BookReaderT, true); + assert.strictEqual(bookReader7.booksRead, 7); + + var attacker = movie.characters[1]; + assert.strictEqual(attacker instanceof Test.AttackerT, true); + assert.strictEqual(attacker.swordAttackDamage, 5); + + var bookReader2 = movie.characters[2]; + assert.strictEqual(bookReader2 instanceof Test.BookReaderT, true); + assert.strictEqual(bookReader2.booksRead, 2); + if(isTsTest) { + var other = movie.characters[3]; + assert.strictEqual(other, "I am other"); + } +} + +function createMovie(fbb) { Test.Attacker.startAttacker(fbb); Test.Attacker.addSwordAttackDamage(fbb, 5); var attackerOffset = Test.Attacker.endAttacker(fbb); var charTypesOffset = Test.Movie.createCharactersTypeVector(fbb, charTypes); - var charsOffset = Test.Movie.createCharactersVector( - fbb, - [ - Test.BookReader.createBookReader(fbb, 7), - attackerOffset, - Test.BookReader.createBookReader(fbb, 2), - ] - ); + var charsOffset = 0; + + if(isTsTest) { + let otherOffset = fbb.createString("I am other"); + + charsOffset = Test.Movie.createCharactersVector( + fbb, + [ + Test.BookReader.createBookReader(fbb, 7), + attackerOffset, + Test.BookReader.createBookReader(fbb, 2), + otherOffset + ] + ); + } else { + charsOffset = Test.Movie.createCharactersVector( + fbb, + [ + Test.BookReader.createBookReader(fbb, 7), + attackerOffset, + Test.BookReader.createBookReader(fbb, 2) + ] + ); + } Test.Movie.startMovie(fbb); Test.Movie.addCharactersType(fbb, charTypesOffset); Test.Movie.addCharacters(fbb, charsOffset); - Test.Movie.finishMovieBuffer(fbb, Test.Movie.endMovie(fbb)); + Test.Movie.finishMovieBuffer(fbb, Test.Movie.endMovie(fbb)) +} - var buf = new flatbuffers.ByteBuffer(fbb.asUint8Array()); +function main() { + var fbb = new flatbuffers.Builder(); - var movie = Test.Movie.getRootAsMovie(buf); + createMovie(fbb); - assert.strictEqual(movie.charactersTypeLength(), charTypes.length); - assert.strictEqual(movie.charactersLength(), movie.charactersTypeLength()); + var buf = new flatbuffers.ByteBuffer(fbb.asUint8Array()); - for (var i = 0; i < charTypes.length; ++i) { - assert.strictEqual(movie.charactersType(i), charTypes[i]); - } + var movie = Test.Movie.getRootAsMovie(buf); + testMovieBuf(movie); - var bookReader7 = movie.characters(0, new Test.BookReader()); - assert.strictEqual(bookReader7.booksRead(), 7); + if(isTsTest) { + testMovieUnpack(movie.unpack()); - var attacker = movie.characters(1, new Test.Attacker()); - assert.strictEqual(attacker.swordAttackDamage(), 5); + var movie_to = new Test.MovieT(); + movie.unpackTo(movie_to); + testMovieUnpack(movie_to); - var bookReader2 = movie.characters(2, new Test.BookReader()); - assert.strictEqual(bookReader2.booksRead(), 2); + fbb.clear(); + Test.Movie.finishMovieBuffer(fbb, movie_to.pack(fbb)); + var unpackBuf = new flatbuffers.ByteBuffer(fbb.asUint8Array()); + testMovieBuf(Test.Movie.getRootAsMovie(unpackBuf)); + } console.log('FlatBuffers union vector test: completed successfully'); } diff --git a/tests/TypeScriptTest.sh b/tests/TypeScriptTest.sh index fa650a4d..65255ef0 100755 --- a/tests/TypeScriptTest.sh +++ b/tests/TypeScriptTest.sh @@ -18,16 +18,17 @@ pushd "$(dirname $0)" >/dev/null npm install @types/flatbuffers -../flatc --ts --no-fb-import --gen-mutable -o ts -I include_test monster_test.fbs -../flatc -b -I include_test monster_test.fbs unicode_test.json +export FB_TS_TEST="TRUE" + +../flatc --ts --no-fb-import --gen-mutable --gen-object-api -o ts -I include_test monster_test.fbs +../flatc --gen-object-api -b -I include_test monster_test.fbs unicode_test.json tsc --strict --noUnusedParameters --noUnusedLocals --noImplicitReturns --strictNullChecks ts/monster_test_generated.ts node JavaScriptTest ./ts/monster_test_generated -../flatc --ts --js --no-fb-import -o ts union_vector/union_vector.fbs - -# test JS version first, then transpile and rerun for TS -node JavaScriptUnionVectorTest ./ts/union_vector_generated +../flatc --ts --no-fb-import --gen-object-api -o ts union_vector/union_vector.fbs tsc --strict --noUnusedParameters --noUnusedLocals --noImplicitReturns --strictNullChecks ts/union_vector_generated.ts node JavaScriptUnionVectorTest ./ts/union_vector_generated +unset FB_TS_TEST + npm uninstall @types/flatbuffers diff --git a/tests/monster_test_generated.ts b/tests/monster_test_generated.ts index 414bedbb..75688e34 100644 --- a/tests/monster_test_generated.ts +++ b/tests/monster_test_generated.ts @@ -19,7 +19,8 @@ export enum Color{ * \brief color Blue (1u << 3) */ Blue= 8 -}}; +}; +} /** * @enum {number} @@ -30,7 +31,8 @@ export enum Race{ Human= 0, Dwarf= 1, Elf= 2 -}}; +}; +} /** * @enum {number} @@ -41,7 +43,35 @@ export enum Any{ Monster= 1, TestSimpleTableWithEnum= 2, MyGame_Example2_Monster= 3 -}}; +}; + +export function unionToAny( + type: Any, + accessor: (obj:MyGame.Example.Monster|MyGame.Example.TestSimpleTableWithEnum|MyGame.Example2.Monster) => MyGame.Example.Monster|MyGame.Example.TestSimpleTableWithEnum|MyGame.Example2.Monster|null +): MyGame.Example.Monster|MyGame.Example.TestSimpleTableWithEnum|MyGame.Example2.Monster|null { + switch(MyGame.Example.Any[type]) { + case 'NONE': return null; + case 'Monster': return accessor(new MyGame.Example.Monster())! as MyGame.Example.Monster; + case 'TestSimpleTableWithEnum': return accessor(new MyGame.Example.TestSimpleTableWithEnum())! as MyGame.Example.TestSimpleTableWithEnum; + case 'MyGame_Example2_Monster': return accessor(new MyGame.Example2.Monster())! as MyGame.Example2.Monster; + default: return null; + } +} + +export function unionListToAny( + type: Any, + accessor: (index: number, obj:MyGame.Example.Monster|MyGame.Example.TestSimpleTableWithEnum|MyGame.Example2.Monster) => MyGame.Example.Monster|MyGame.Example.TestSimpleTableWithEnum|MyGame.Example2.Monster|null, + index: number +): MyGame.Example.Monster|MyGame.Example.TestSimpleTableWithEnum|MyGame.Example2.Monster|null { + switch(MyGame.Example.Any[type]) { + case 'NONE': return null; + case 'Monster': return accessor(index, new MyGame.Example.Monster())! as MyGame.Example.Monster; + case 'TestSimpleTableWithEnum': return accessor(index, new MyGame.Example.TestSimpleTableWithEnum())! as MyGame.Example.TestSimpleTableWithEnum; + case 'MyGame_Example2_Monster': return accessor(index, new MyGame.Example2.Monster())! as MyGame.Example2.Monster; + default: return null; + } +} +} /** * @enum {number} @@ -52,7 +82,35 @@ export enum AnyUniqueAliases{ M= 1, TS= 2, M2= 3 -}}; +}; + +export function unionToAnyUniqueAliases( + type: AnyUniqueAliases, + accessor: (obj:MyGame.Example.Monster|MyGame.Example.TestSimpleTableWithEnum|MyGame.Example2.Monster) => MyGame.Example.Monster|MyGame.Example.TestSimpleTableWithEnum|MyGame.Example2.Monster|null +): MyGame.Example.Monster|MyGame.Example.TestSimpleTableWithEnum|MyGame.Example2.Monster|null { + switch(MyGame.Example.AnyUniqueAliases[type]) { + case 'NONE': return null; + case 'M': return accessor(new MyGame.Example.Monster())! as MyGame.Example.Monster; + case 'TS': return accessor(new MyGame.Example.TestSimpleTableWithEnum())! as MyGame.Example.TestSimpleTableWithEnum; + case 'M2': return accessor(new MyGame.Example2.Monster())! as MyGame.Example2.Monster; + default: return null; + } +} + +export function unionListToAnyUniqueAliases( + type: AnyUniqueAliases, + accessor: (index: number, obj:MyGame.Example.Monster|MyGame.Example.TestSimpleTableWithEnum|MyGame.Example2.Monster) => MyGame.Example.Monster|MyGame.Example.TestSimpleTableWithEnum|MyGame.Example2.Monster|null, + index: number +): MyGame.Example.Monster|MyGame.Example.TestSimpleTableWithEnum|MyGame.Example2.Monster|null { + switch(MyGame.Example.AnyUniqueAliases[type]) { + case 'NONE': return null; + case 'M': return accessor(index, new MyGame.Example.Monster())! as MyGame.Example.Monster; + case 'TS': return accessor(index, new MyGame.Example.TestSimpleTableWithEnum())! as MyGame.Example.TestSimpleTableWithEnum; + case 'M2': return accessor(index, new MyGame.Example2.Monster())! as MyGame.Example2.Monster; + default: return null; + } +} +} /** * @enum {number} @@ -63,7 +121,35 @@ export enum AnyAmbiguousAliases{ M1= 1, M2= 2, M3= 3 -}}; +}; + +export function unionToAnyAmbiguousAliases( + type: AnyAmbiguousAliases, + accessor: (obj:MyGame.Example.Monster) => MyGame.Example.Monster|null +): MyGame.Example.Monster|null { + switch(MyGame.Example.AnyAmbiguousAliases[type]) { + case 'NONE': return null; + case 'M1': return accessor(new MyGame.Example.Monster())! as MyGame.Example.Monster; + case 'M2': return accessor(new MyGame.Example.Monster())! as MyGame.Example.Monster; + case 'M3': return accessor(new MyGame.Example.Monster())! as MyGame.Example.Monster; + default: return null; + } +} + +export function unionListToAnyAmbiguousAliases( + type: AnyAmbiguousAliases, + accessor: (index: number, obj:MyGame.Example.Monster) => MyGame.Example.Monster|null, + index: number +): MyGame.Example.Monster|null { + switch(MyGame.Example.AnyAmbiguousAliases[type]) { + case 'NONE': return null; + case 'M1': return accessor(index, new MyGame.Example.Monster())! as MyGame.Example.Monster; + case 'M2': return accessor(index, new MyGame.Example.Monster())! as MyGame.Example.Monster; + case 'M3': return accessor(index, new MyGame.Example.Monster())! as MyGame.Example.Monster; + default: return null; + } +} +} /** * @constructor @@ -123,6 +209,33 @@ static createInParentNamespace(builder:flatbuffers.Builder):flatbuffers.Offset { InParentNamespace.startInParentNamespace(builder); return InParentNamespace.endInParentNamespace(builder); } + +/** + * @returns InParentNamespaceT + */ +unpack(): InParentNamespaceT { + return new InParentNamespaceT(); +}; + +/** + * @param InParentNamespaceT _o + */ +unpackTo(_o: InParentNamespaceT): void {}; +} + +export class InParentNamespaceT { +/** + * @constructor + */ +constructor(){}; + +/** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ +pack(builder:flatbuffers.Builder): flatbuffers.Offset { + return InParentNamespace.createInParentNamespace(builder); +}; } } /** @@ -183,6 +296,33 @@ static createMonster(builder:flatbuffers.Builder):flatbuffers.Offset { Monster.startMonster(builder); return Monster.endMonster(builder); } + +/** + * @returns MonsterT + */ +unpack(): MonsterT { + return new MonsterT(); +}; + +/** + * @param MonsterT _o + */ +unpackTo(_o: MonsterT): void {}; +} + +export class MonsterT { +/** + * @constructor + */ +constructor(){}; + +/** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ +pack(builder:flatbuffers.Builder): flatbuffers.Offset { + return Monster.createMonster(builder); +}; } } /** @@ -262,6 +402,47 @@ static createTest(builder:flatbuffers.Builder, a: number, b: number):flatbuffers return builder.offset(); }; + +/** + * @returns TestT + */ +unpack(): TestT { + return new TestT( + this.a(), + this.b() + ); +}; + +/** + * @param TestT _o + */ +unpackTo(_o: TestT): void { + _o.a = this.a(); + _o.b = this.b(); +}; +} + +export class TestT { +/** + * @constructor + * @param number a + * @param number b + */ +constructor( + public a: number = 0, + public b: number = 0 +){}; + +/** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ +pack(builder:flatbuffers.Builder): flatbuffers.Offset { + return Test.createTest(builder, + this.a, + this.b + ); +}; } } /** @@ -354,6 +535,42 @@ static createTestSimpleTableWithEnum(builder:flatbuffers.Builder, color:MyGame.E TestSimpleTableWithEnum.addColor(builder, color); return TestSimpleTableWithEnum.endTestSimpleTableWithEnum(builder); } + +/** + * @returns TestSimpleTableWithEnumT + */ +unpack(): TestSimpleTableWithEnumT { + return new TestSimpleTableWithEnumT( + this.color() + ); +}; + +/** + * @param TestSimpleTableWithEnumT _o + */ +unpackTo(_o: TestSimpleTableWithEnumT): void { + _o.color = this.color(); +}; +} + +export class TestSimpleTableWithEnumT { +/** + * @constructor + * @param MyGame.Example.Color color + */ +constructor( + public color: MyGame.Example.Color = MyGame.Example.Color.Green +){}; + +/** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ +pack(builder:flatbuffers.Builder): flatbuffers.Offset { + return TestSimpleTableWithEnum.createTestSimpleTableWithEnum(builder, + this.color + ); +}; } } /** @@ -521,6 +738,68 @@ static createVec3(builder:flatbuffers.Builder, x: number, y: number, z: number, return builder.offset(); }; + +/** + * @returns Vec3T + */ +unpack(): Vec3T { + return new Vec3T( + this.x(), + this.y(), + this.z(), + this.test1(), + this.test2(), + (this.test3() !== null ? this.test3()!.unpack() : null) + ); +}; + +/** + * @param Vec3T _o + */ +unpackTo(_o: Vec3T): void { + _o.x = this.x(); + _o.y = this.y(); + _o.z = this.z(); + _o.test1 = this.test1(); + _o.test2 = this.test2(); + _o.test3 = (this.test3() !== null ? this.test3()!.unpack() : null); +}; +} + +export class Vec3T { +/** + * @constructor + * @param number x + * @param number y + * @param number z + * @param number test1 + * @param MyGame.Example.Color test2 + * @param MyGame.Example.TestT|null test3 + */ +constructor( + public x: number = 0.0, + public y: number = 0.0, + public z: number = 0.0, + public test1: number = 0.0, + public test2: MyGame.Example.Color = /** } */ (0), + public test3: MyGame.Example.TestT|null = null +){}; + +/** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ +pack(builder:flatbuffers.Builder): flatbuffers.Offset { + return Vec3.createVec3(builder, + this.x, + this.y, + this.z, + this.test1, + this.test2, + (this.test3 === null ? 0 : this.test3.a!), + (this.test3 === null ? 0 : this.test3.b!) + ); +}; } } /** @@ -599,6 +878,47 @@ static createAbility(builder:flatbuffers.Builder, id: number, distance: number): return builder.offset(); }; + +/** + * @returns AbilityT + */ +unpack(): AbilityT { + return new AbilityT( + this.id(), + this.distance() + ); +}; + +/** + * @param AbilityT _o + */ +unpackTo(_o: AbilityT): void { + _o.id = this.id(); + _o.distance = this.distance(); +}; +} + +export class AbilityT { +/** + * @constructor + * @param number id + * @param number distance + */ +constructor( + public id: number = 0, + public distance: number = 0 +){}; + +/** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ +pack(builder:flatbuffers.Builder): flatbuffers.Offset { + return Ability.createAbility(builder, + this.id, + this.distance + ); +}; } } /** @@ -743,6 +1063,54 @@ static createStat(builder:flatbuffers.Builder, idOffset:flatbuffers.Offset, val: Stat.addCount(builder, count); return Stat.endStat(builder); } + +/** + * @returns StatT + */ +unpack(): StatT { + return new StatT( + this.id(), + this.val(), + this.count() + ); +}; + +/** + * @param StatT _o + */ +unpackTo(_o: StatT): void { + _o.id = this.id(); + _o.val = this.val(); + _o.count = this.count(); +}; +} + +export class StatT { +/** + * @constructor + * @param string|Uint8Array|null id + * @param flatbuffers.Long val + * @param number count + */ +constructor( + public id: string|Uint8Array|null = null, + public val: flatbuffers.Long = flatbuffers.createLong(0, 0), + public count: number = 0 +){}; + +/** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ +pack(builder:flatbuffers.Builder): flatbuffers.Offset { + const id = (this.id !== null ? builder.createString(this.id!) : 0); + + return Stat.createStat(builder, + id, + this.val, + this.count + ); +}; } } /** @@ -835,6 +1203,42 @@ static createReferrable(builder:flatbuffers.Builder, id:flatbuffers.Long):flatbu Referrable.addId(builder, id); return Referrable.endReferrable(builder); } + +/** + * @returns ReferrableT + */ +unpack(): ReferrableT { + return new ReferrableT( + this.id() + ); +}; + +/** + * @param ReferrableT _o + */ +unpackTo(_o: ReferrableT): void { + _o.id = this.id(); +}; +} + +export class ReferrableT { +/** + * @constructor + * @param flatbuffers.Long id + */ +constructor( + public id: flatbuffers.Long = flatbuffers.createLong(0, 0) +){}; + +/** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ +pack(builder:flatbuffers.Builder): flatbuffers.Offset { + return Referrable.createReferrable(builder, + this.id + ); +}; } } /** @@ -2597,6 +3001,324 @@ static createMonster(builder:flatbuffers.Builder, posOffset:flatbuffers.Offset, Monster.addSignedEnum(builder, signedEnum); return Monster.endMonster(builder); } + +/** + * @returns MonsterT + */ +unpack(): MonsterT { + return new MonsterT( + (this.pos() !== null ? this.pos()!.unpack() : null), + this.mana(), + this.hp(), + this.name(), + this.bb!.createScalarList(this.inventory.bind(this), this.inventoryLength()), + this.color(), + this.testType(), + (() => { + let temp = MyGame.Example.unionToAny(this.testType(), this.test.bind(this)); + if(temp === null) { return null; } + return temp.unpack() + })(), + this.bb!.createObjList(this.test4.bind(this), this.test4Length()), + this.bb!.createStringList(this.testarrayofstring.bind(this), this.testarrayofstringLength()), + this.bb!.createObjList(this.testarrayoftables.bind(this), this.testarrayoftablesLength()), + (this.enemy() !== null ? this.enemy()!.unpack() : null), + this.bb!.createScalarList(this.testnestedflatbuffer.bind(this), this.testnestedflatbufferLength()), + (this.testempty() !== null ? this.testempty()!.unpack() : null), + this.testbool(), + this.testhashs32Fnv1(), + this.testhashu32Fnv1(), + this.testhashs64Fnv1(), + this.testhashu64Fnv1(), + this.testhashs32Fnv1a(), + this.testhashu32Fnv1a(), + this.testhashs64Fnv1a(), + this.testhashu64Fnv1a(), + this.bb!.createScalarList(this.testarrayofbools.bind(this), this.testarrayofboolsLength()), + this.testf(), + this.testf2(), + this.testf3(), + this.bb!.createStringList(this.testarrayofstring2.bind(this), this.testarrayofstring2Length()), + this.bb!.createObjList(this.testarrayofsortedstruct.bind(this), this.testarrayofsortedstructLength()), + this.bb!.createScalarList(this.flex.bind(this), this.flexLength()), + this.bb!.createObjList(this.test5.bind(this), this.test5Length()), + this.bb!.createScalarList(this.vectorOfLongs.bind(this), this.vectorOfLongsLength()), + this.bb!.createScalarList(this.vectorOfDoubles.bind(this), this.vectorOfDoublesLength()), + (this.parentNamespaceTest() !== null ? this.parentNamespaceTest()!.unpack() : null), + this.bb!.createObjList(this.vectorOfReferrables.bind(this), this.vectorOfReferrablesLength()), + this.singleWeakReference(), + this.bb!.createScalarList(this.vectorOfWeakReferences.bind(this), this.vectorOfWeakReferencesLength()), + this.bb!.createObjList(this.vectorOfStrongReferrables.bind(this), this.vectorOfStrongReferrablesLength()), + this.coOwningReference(), + this.bb!.createScalarList(this.vectorOfCoOwningReferences.bind(this), this.vectorOfCoOwningReferencesLength()), + this.nonOwningReference(), + this.bb!.createScalarList(this.vectorOfNonOwningReferences.bind(this), this.vectorOfNonOwningReferencesLength()), + this.anyUniqueType(), + (() => { + let temp = MyGame.Example.unionToAnyUniqueAliases(this.anyUniqueType(), this.anyUnique.bind(this)); + if(temp === null) { return null; } + return temp.unpack() + })(), + this.anyAmbiguousType(), + (() => { + let temp = MyGame.Example.unionToAnyAmbiguousAliases(this.anyAmbiguousType(), this.anyAmbiguous.bind(this)); + if(temp === null) { return null; } + return temp.unpack() + })(), + this.bb!.createScalarList(this.vectorOfEnums.bind(this), this.vectorOfEnumsLength()), + this.signedEnum() + ); +}; + +/** + * @param MonsterT _o + */ +unpackTo(_o: MonsterT): void { + _o.pos = (this.pos() !== null ? this.pos()!.unpack() : null); + _o.mana = this.mana(); + _o.hp = this.hp(); + _o.name = this.name(); + _o.inventory = this.bb!.createScalarList(this.inventory.bind(this), this.inventoryLength()); + _o.color = this.color(); + _o.testType = this.testType(); + _o.test = (() => { + let temp = MyGame.Example.unionToAny(this.testType(), this.test.bind(this)); + if(temp === null) { return null; } + return temp.unpack() + })(); + _o.test4 = this.bb!.createObjList(this.test4.bind(this), this.test4Length()); + _o.testarrayofstring = this.bb!.createStringList(this.testarrayofstring.bind(this), this.testarrayofstringLength()); + _o.testarrayoftables = this.bb!.createObjList(this.testarrayoftables.bind(this), this.testarrayoftablesLength()); + _o.enemy = (this.enemy() !== null ? this.enemy()!.unpack() : null); + _o.testnestedflatbuffer = this.bb!.createScalarList(this.testnestedflatbuffer.bind(this), this.testnestedflatbufferLength()); + _o.testempty = (this.testempty() !== null ? this.testempty()!.unpack() : null); + _o.testbool = this.testbool(); + _o.testhashs32Fnv1 = this.testhashs32Fnv1(); + _o.testhashu32Fnv1 = this.testhashu32Fnv1(); + _o.testhashs64Fnv1 = this.testhashs64Fnv1(); + _o.testhashu64Fnv1 = this.testhashu64Fnv1(); + _o.testhashs32Fnv1a = this.testhashs32Fnv1a(); + _o.testhashu32Fnv1a = this.testhashu32Fnv1a(); + _o.testhashs64Fnv1a = this.testhashs64Fnv1a(); + _o.testhashu64Fnv1a = this.testhashu64Fnv1a(); + _o.testarrayofbools = this.bb!.createScalarList(this.testarrayofbools.bind(this), this.testarrayofboolsLength()); + _o.testf = this.testf(); + _o.testf2 = this.testf2(); + _o.testf3 = this.testf3(); + _o.testarrayofstring2 = this.bb!.createStringList(this.testarrayofstring2.bind(this), this.testarrayofstring2Length()); + _o.testarrayofsortedstruct = this.bb!.createObjList(this.testarrayofsortedstruct.bind(this), this.testarrayofsortedstructLength()); + _o.flex = this.bb!.createScalarList(this.flex.bind(this), this.flexLength()); + _o.test5 = this.bb!.createObjList(this.test5.bind(this), this.test5Length()); + _o.vectorOfLongs = this.bb!.createScalarList(this.vectorOfLongs.bind(this), this.vectorOfLongsLength()); + _o.vectorOfDoubles = this.bb!.createScalarList(this.vectorOfDoubles.bind(this), this.vectorOfDoublesLength()); + _o.parentNamespaceTest = (this.parentNamespaceTest() !== null ? this.parentNamespaceTest()!.unpack() : null); + _o.vectorOfReferrables = this.bb!.createObjList(this.vectorOfReferrables.bind(this), this.vectorOfReferrablesLength()); + _o.singleWeakReference = this.singleWeakReference(); + _o.vectorOfWeakReferences = this.bb!.createScalarList(this.vectorOfWeakReferences.bind(this), this.vectorOfWeakReferencesLength()); + _o.vectorOfStrongReferrables = this.bb!.createObjList(this.vectorOfStrongReferrables.bind(this), this.vectorOfStrongReferrablesLength()); + _o.coOwningReference = this.coOwningReference(); + _o.vectorOfCoOwningReferences = this.bb!.createScalarList(this.vectorOfCoOwningReferences.bind(this), this.vectorOfCoOwningReferencesLength()); + _o.nonOwningReference = this.nonOwningReference(); + _o.vectorOfNonOwningReferences = this.bb!.createScalarList(this.vectorOfNonOwningReferences.bind(this), this.vectorOfNonOwningReferencesLength()); + _o.anyUniqueType = this.anyUniqueType(); + _o.anyUnique = (() => { + let temp = MyGame.Example.unionToAnyUniqueAliases(this.anyUniqueType(), this.anyUnique.bind(this)); + if(temp === null) { return null; } + return temp.unpack() + })(); + _o.anyAmbiguousType = this.anyAmbiguousType(); + _o.anyAmbiguous = (() => { + let temp = MyGame.Example.unionToAnyAmbiguousAliases(this.anyAmbiguousType(), this.anyAmbiguous.bind(this)); + if(temp === null) { return null; } + return temp.unpack() + })(); + _o.vectorOfEnums = this.bb!.createScalarList(this.vectorOfEnums.bind(this), this.vectorOfEnumsLength()); + _o.signedEnum = this.signedEnum(); +}; +} + +export class MonsterT { +/** + * @constructor + * @param MyGame.Example.Vec3T|null pos + * @param number mana + * @param number hp + * @param string|Uint8Array|null name + * @param (number)[] inventory + * @param MyGame.Example.Color color + * @param MyGame.Example.Any testType + * @param MyGame.Example.MonsterT|MyGame.Example.TestSimpleTableWithEnumT|MyGame.Example2.MonsterT|null test + * @param (MyGame.Example.TestT)[] test4 + * @param (string)[] testarrayofstring + * @param (MyGame.Example.MonsterT)[] testarrayoftables + * @param MyGame.Example.MonsterT|null enemy + * @param (number)[] testnestedflatbuffer + * @param MyGame.Example.StatT|null testempty + * @param boolean testbool + * @param number testhashs32Fnv1 + * @param number testhashu32Fnv1 + * @param flatbuffers.Long testhashs64Fnv1 + * @param flatbuffers.Long testhashu64Fnv1 + * @param number testhashs32Fnv1a + * @param number testhashu32Fnv1a + * @param flatbuffers.Long testhashs64Fnv1a + * @param flatbuffers.Long testhashu64Fnv1a + * @param (boolean)[] testarrayofbools + * @param number testf + * @param number testf2 + * @param number testf3 + * @param (string)[] testarrayofstring2 + * @param (MyGame.Example.AbilityT)[] testarrayofsortedstruct + * @param (number)[] flex + * @param (MyGame.Example.TestT)[] test5 + * @param (flatbuffers.Long)[] vectorOfLongs + * @param (number)[] vectorOfDoubles + * @param MyGame.InParentNamespaceT|null parentNamespaceTest + * @param (MyGame.Example.ReferrableT)[] vectorOfReferrables + * @param flatbuffers.Long singleWeakReference + * @param (flatbuffers.Long)[] vectorOfWeakReferences + * @param (MyGame.Example.ReferrableT)[] vectorOfStrongReferrables + * @param flatbuffers.Long coOwningReference + * @param (flatbuffers.Long)[] vectorOfCoOwningReferences + * @param flatbuffers.Long nonOwningReference + * @param (flatbuffers.Long)[] vectorOfNonOwningReferences + * @param MyGame.Example.AnyUniqueAliases anyUniqueType + * @param MyGame.Example.MonsterT|MyGame.Example.TestSimpleTableWithEnumT|MyGame.Example2.MonsterT|null anyUnique + * @param MyGame.Example.AnyAmbiguousAliases anyAmbiguousType + * @param MyGame.Example.MonsterT|null anyAmbiguous + * @param (MyGame.Example.Color)[] vectorOfEnums + * @param MyGame.Example.Race signedEnum + */ +constructor( + public pos: MyGame.Example.Vec3T|null = null, + public mana: number = 150, + public hp: number = 100, + public name: string|Uint8Array|null = null, + public inventory: (number)[] = [], + public color: MyGame.Example.Color = MyGame.Example.Color.Blue, + public testType: MyGame.Example.Any = MyGame.Example.Any.NONE, + public test: MyGame.Example.MonsterT|MyGame.Example.TestSimpleTableWithEnumT|MyGame.Example2.MonsterT|null = null, + public test4: (MyGame.Example.TestT)[] = [], + public testarrayofstring: (string)[] = [], + public testarrayoftables: (MyGame.Example.MonsterT)[] = [], + public enemy: MyGame.Example.MonsterT|null = null, + public testnestedflatbuffer: (number)[] = [], + public testempty: MyGame.Example.StatT|null = null, + public testbool: boolean = false, + public testhashs32Fnv1: number = 0, + public testhashu32Fnv1: number = 0, + public testhashs64Fnv1: flatbuffers.Long = flatbuffers.createLong(0, 0), + public testhashu64Fnv1: flatbuffers.Long = flatbuffers.createLong(0, 0), + public testhashs32Fnv1a: number = 0, + public testhashu32Fnv1a: number = 0, + public testhashs64Fnv1a: flatbuffers.Long = flatbuffers.createLong(0, 0), + public testhashu64Fnv1a: flatbuffers.Long = flatbuffers.createLong(0, 0), + public testarrayofbools: (boolean)[] = [], + public testf: number = 3.14159, + public testf2: number = 3.0, + public testf3: number = 0.0, + public testarrayofstring2: (string)[] = [], + public testarrayofsortedstruct: (MyGame.Example.AbilityT)[] = [], + public flex: (number)[] = [], + public test5: (MyGame.Example.TestT)[] = [], + public vectorOfLongs: (flatbuffers.Long)[] = [], + public vectorOfDoubles: (number)[] = [], + public parentNamespaceTest: MyGame.InParentNamespaceT|null = null, + public vectorOfReferrables: (MyGame.Example.ReferrableT)[] = [], + public singleWeakReference: flatbuffers.Long = flatbuffers.createLong(0, 0), + public vectorOfWeakReferences: (flatbuffers.Long)[] = [], + public vectorOfStrongReferrables: (MyGame.Example.ReferrableT)[] = [], + public coOwningReference: flatbuffers.Long = flatbuffers.createLong(0, 0), + public vectorOfCoOwningReferences: (flatbuffers.Long)[] = [], + public nonOwningReference: flatbuffers.Long = flatbuffers.createLong(0, 0), + public vectorOfNonOwningReferences: (flatbuffers.Long)[] = [], + public anyUniqueType: MyGame.Example.AnyUniqueAliases = MyGame.Example.AnyUniqueAliases.NONE, + public anyUnique: MyGame.Example.MonsterT|MyGame.Example.TestSimpleTableWithEnumT|MyGame.Example2.MonsterT|null = null, + public anyAmbiguousType: MyGame.Example.AnyAmbiguousAliases = MyGame.Example.AnyAmbiguousAliases.NONE, + public anyAmbiguous: MyGame.Example.MonsterT|null = null, + public vectorOfEnums: (MyGame.Example.Color)[] = [], + public signedEnum: MyGame.Example.Race = MyGame.Example.Race.None +){}; + +/** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ +pack(builder:flatbuffers.Builder): flatbuffers.Offset { + const name = (this.name !== null ? builder.createString(this.name!) : 0); + const inventory = Monster.createInventoryVector(builder, this.inventory); + const test = builder.createObjectOffset(this.test); + const test4 = builder.createStructOffsetList(this.test4, Monster.startTest4Vector); + const testarrayofstring = Monster.createTestarrayofstringVector(builder, builder.createObjectOffsetList(this.testarrayofstring)); + const testarrayoftables = Monster.createTestarrayoftablesVector(builder, builder.createObjectOffsetList(this.testarrayoftables)); + const testnestedflatbuffer = Monster.createTestnestedflatbufferVector(builder, this.testnestedflatbuffer); + const testarrayofbools = Monster.createTestarrayofboolsVector(builder, this.testarrayofbools); + const testarrayofstring2 = Monster.createTestarrayofstring2Vector(builder, builder.createObjectOffsetList(this.testarrayofstring2)); + const testarrayofsortedstruct = builder.createStructOffsetList(this.testarrayofsortedstruct, Monster.startTestarrayofsortedstructVector); + const flex = Monster.createFlexVector(builder, this.flex); + const test5 = builder.createStructOffsetList(this.test5, Monster.startTest5Vector); + const vectorOfLongs = Monster.createVectorOfLongsVector(builder, this.vectorOfLongs); + const vectorOfDoubles = Monster.createVectorOfDoublesVector(builder, this.vectorOfDoubles); + const vectorOfReferrables = Monster.createVectorOfReferrablesVector(builder, builder.createObjectOffsetList(this.vectorOfReferrables)); + const vectorOfWeakReferences = Monster.createVectorOfWeakReferencesVector(builder, this.vectorOfWeakReferences); + const vectorOfStrongReferrables = Monster.createVectorOfStrongReferrablesVector(builder, builder.createObjectOffsetList(this.vectorOfStrongReferrables)); + const vectorOfCoOwningReferences = Monster.createVectorOfCoOwningReferencesVector(builder, this.vectorOfCoOwningReferences); + const vectorOfNonOwningReferences = Monster.createVectorOfNonOwningReferencesVector(builder, this.vectorOfNonOwningReferences); + const anyUnique = builder.createObjectOffset(this.anyUnique); + const anyAmbiguous = builder.createObjectOffset(this.anyAmbiguous); + const vectorOfEnums = Monster.createVectorOfEnumsVector(builder, this.vectorOfEnums); + + return Monster.createMonster(builder, + (this.pos !== null ? this.pos!.pack(builder) : 0), + this.mana, + this.hp, + name, + inventory, + this.color, + this.testType, + test, + test4, + testarrayofstring, + testarrayoftables, + (this.enemy !== null ? this.enemy!.pack(builder) : 0), + testnestedflatbuffer, + (this.testempty !== null ? this.testempty!.pack(builder) : 0), + this.testbool, + this.testhashs32Fnv1, + this.testhashu32Fnv1, + this.testhashs64Fnv1, + this.testhashu64Fnv1, + this.testhashs32Fnv1a, + this.testhashu32Fnv1a, + this.testhashs64Fnv1a, + this.testhashu64Fnv1a, + testarrayofbools, + this.testf, + this.testf2, + this.testf3, + testarrayofstring2, + testarrayofsortedstruct, + flex, + test5, + vectorOfLongs, + vectorOfDoubles, + (this.parentNamespaceTest !== null ? this.parentNamespaceTest!.pack(builder) : 0), + vectorOfReferrables, + this.singleWeakReference, + vectorOfWeakReferences, + vectorOfStrongReferrables, + this.coOwningReference, + vectorOfCoOwningReferences, + this.nonOwningReference, + vectorOfNonOwningReferences, + this.anyUniqueType, + anyUnique, + this.anyAmbiguousType, + anyAmbiguous, + vectorOfEnums, + this.signedEnum + ); +}; } } /** @@ -3087,5 +3809,99 @@ static createTypeAliases(builder:flatbuffers.Builder, i8:number, u8:number, i16: TypeAliases.addVf64(builder, vf64Offset); return TypeAliases.endTypeAliases(builder); } + +/** + * @returns TypeAliasesT + */ +unpack(): TypeAliasesT { + return new TypeAliasesT( + this.i8(), + this.u8(), + this.i16(), + this.u16(), + this.i32(), + this.u32(), + this.i64(), + this.u64(), + this.f32(), + this.f64(), + this.bb!.createScalarList(this.v8.bind(this), this.v8Length()), + this.bb!.createScalarList(this.vf64.bind(this), this.vf64Length()) + ); +}; + +/** + * @param TypeAliasesT _o + */ +unpackTo(_o: TypeAliasesT): void { + _o.i8 = this.i8(); + _o.u8 = this.u8(); + _o.i16 = this.i16(); + _o.u16 = this.u16(); + _o.i32 = this.i32(); + _o.u32 = this.u32(); + _o.i64 = this.i64(); + _o.u64 = this.u64(); + _o.f32 = this.f32(); + _o.f64 = this.f64(); + _o.v8 = this.bb!.createScalarList(this.v8.bind(this), this.v8Length()); + _o.vf64 = this.bb!.createScalarList(this.vf64.bind(this), this.vf64Length()); +}; +} + +export class TypeAliasesT { +/** + * @constructor + * @param number i8 + * @param number u8 + * @param number i16 + * @param number u16 + * @param number i32 + * @param number u32 + * @param flatbuffers.Long i64 + * @param flatbuffers.Long u64 + * @param number f32 + * @param number f64 + * @param (number)[] v8 + * @param (number)[] vf64 + */ +constructor( + public i8: number = 0, + public u8: number = 0, + public i16: number = 0, + public u16: number = 0, + public i32: number = 0, + public u32: number = 0, + public i64: flatbuffers.Long = flatbuffers.createLong(0, 0), + public u64: flatbuffers.Long = flatbuffers.createLong(0, 0), + public f32: number = 0.0, + public f64: number = 0.0, + public v8: (number)[] = [], + public vf64: (number)[] = [] +){}; + +/** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ +pack(builder:flatbuffers.Builder): flatbuffers.Offset { + const v8 = TypeAliases.createV8Vector(builder, this.v8); + const vf64 = TypeAliases.createVf64Vector(builder, this.vf64); + + return TypeAliases.createTypeAliases(builder, + this.i8, + this.u8, + this.i16, + this.u16, + this.i32, + this.u32, + this.i64, + this.u64, + this.f32, + this.f64, + v8, + vf64 + ); +}; } } diff --git a/tests/namespace_test/namespace_test1_generated.ts b/tests/namespace_test/namespace_test1_generated.ts index 400a29bf..34489397 100644 --- a/tests/namespace_test/namespace_test1_generated.ts +++ b/tests/namespace_test/namespace_test1_generated.ts @@ -8,7 +8,8 @@ export enum EnumInNestedNS{ A= 0, B= 1, C= 2 -}}; +}; +} /** * @constructor @@ -100,6 +101,42 @@ static createTableInNestedNS(builder:flatbuffers.Builder, foo:number):flatbuffer TableInNestedNS.addFoo(builder, foo); return TableInNestedNS.endTableInNestedNS(builder); } + +/** + * @returns TableInNestedNST + */ +unpack(): TableInNestedNST { + return new TableInNestedNST( + this.foo() + ); +}; + +/** + * @param TableInNestedNST _o + */ +unpackTo(_o: TableInNestedNST): void { + _o.foo = this.foo(); +}; +} + +export class TableInNestedNST { +/** + * @constructor + * @param number foo + */ +constructor( + public foo: number = 0 +){}; + +/** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ +pack(builder:flatbuffers.Builder): flatbuffers.Offset { + return TableInNestedNS.createTableInNestedNS(builder, + this.foo + ); +}; } } /** @@ -178,5 +215,46 @@ static createStructInNestedNS(builder:flatbuffers.Builder, a: number, b: number) return builder.offset(); }; + +/** + * @returns StructInNestedNST + */ +unpack(): StructInNestedNST { + return new StructInNestedNST( + this.a(), + this.b() + ); +}; + +/** + * @param StructInNestedNST _o + */ +unpackTo(_o: StructInNestedNST): void { + _o.a = this.a(); + _o.b = this.b(); +}; +} + +export class StructInNestedNST { +/** + * @constructor + * @param number a + * @param number b + */ +constructor( + public a: number = 0, + public b: number = 0 +){}; + +/** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ +pack(builder:flatbuffers.Builder): flatbuffers.Offset { + return StructInNestedNS.createStructInNestedNS(builder, + this.a, + this.b + ); +}; } } diff --git a/tests/namespace_test/namespace_test2_generated.ts b/tests/namespace_test/namespace_test2_generated.ts index 5bfc0ddd..b8983b17 100644 --- a/tests/namespace_test/namespace_test2_generated.ts +++ b/tests/namespace_test/namespace_test2_generated.ts @@ -127,6 +127,52 @@ static createTableInFirstNS(builder:flatbuffers.Builder, fooTableOffset:flatbuff TableInFirstNS.addFooStruct(builder, fooStructOffset); return TableInFirstNS.endTableInFirstNS(builder); } + +/** + * @returns TableInFirstNST + */ +unpack(): TableInFirstNST { + return new TableInFirstNST( + (this.fooTable() !== null ? this.fooTable()!.unpack() : null), + this.fooEnum(), + (this.fooStruct() !== null ? this.fooStruct()!.unpack() : null) + ); +}; + +/** + * @param TableInFirstNST _o + */ +unpackTo(_o: TableInFirstNST): void { + _o.fooTable = (this.fooTable() !== null ? this.fooTable()!.unpack() : null); + _o.fooEnum = this.fooEnum(); + _o.fooStruct = (this.fooStruct() !== null ? this.fooStruct()!.unpack() : null); +}; +} + +export class TableInFirstNST { +/** + * @constructor + * @param NS8755221360535654258.NamespaceA.NamespaceB.TableInNestedNST|null fooTable + * @param NS8755221360535654258.NamespaceA.NamespaceB.EnumInNestedNS fooEnum + * @param NS8755221360535654258.NamespaceA.NamespaceB.StructInNestedNST|null fooStruct + */ +constructor( + public fooTable: NS8755221360535654258.NamespaceA.NamespaceB.TableInNestedNST|null = null, + public fooEnum: NS8755221360535654258.NamespaceA.NamespaceB.EnumInNestedNS = NS8755221360535654258.NamespaceA.NamespaceB.EnumInNestedNS.A, + public fooStruct: NS8755221360535654258.NamespaceA.NamespaceB.StructInNestedNST|null = null +){}; + +/** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ +pack(builder:flatbuffers.Builder): flatbuffers.Offset { + return TableInFirstNS.createTableInFirstNS(builder, + (this.fooTable !== null ? this.fooTable!.pack(builder) : 0), + this.fooEnum, + (this.fooStruct !== null ? this.fooStruct!.pack(builder) : 0) + ); +}; } } /** @@ -223,6 +269,47 @@ static createTableInC(builder:flatbuffers.Builder, referToA1Offset:flatbuffers.O TableInC.addReferToA2(builder, referToA2Offset); return TableInC.endTableInC(builder); } + +/** + * @returns TableInCT + */ +unpack(): TableInCT { + return new TableInCT( + (this.referToA1() !== null ? this.referToA1()!.unpack() : null), + (this.referToA2() !== null ? this.referToA2()!.unpack() : null) + ); +}; + +/** + * @param TableInCT _o + */ +unpackTo(_o: TableInCT): void { + _o.referToA1 = (this.referToA1() !== null ? this.referToA1()!.unpack() : null); + _o.referToA2 = (this.referToA2() !== null ? this.referToA2()!.unpack() : null); +}; +} + +export class TableInCT { +/** + * @constructor + * @param NamespaceA.TableInFirstNST|null referToA1 + * @param NamespaceA.SecondTableInAT|null referToA2 + */ +constructor( + public referToA1: NamespaceA.TableInFirstNST|null = null, + public referToA2: NamespaceA.SecondTableInAT|null = null +){}; + +/** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ +pack(builder:flatbuffers.Builder): flatbuffers.Offset { + return TableInC.createTableInC(builder, + (this.referToA1 !== null ? this.referToA1!.pack(builder) : 0), + (this.referToA2 !== null ? this.referToA2!.pack(builder) : 0) + ); +}; } } /** @@ -301,5 +388,41 @@ static createSecondTableInA(builder:flatbuffers.Builder, referToCOffset:flatbuff SecondTableInA.addReferToC(builder, referToCOffset); return SecondTableInA.endSecondTableInA(builder); } + +/** + * @returns SecondTableInAT + */ +unpack(): SecondTableInAT { + return new SecondTableInAT( + (this.referToC() !== null ? this.referToC()!.unpack() : null) + ); +}; + +/** + * @param SecondTableInAT _o + */ +unpackTo(_o: SecondTableInAT): void { + _o.referToC = (this.referToC() !== null ? this.referToC()!.unpack() : null); +}; +} + +export class SecondTableInAT { +/** + * @constructor + * @param NamespaceC.TableInCT|null referToC + */ +constructor( + public referToC: NamespaceC.TableInCT|null = null +){}; + +/** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ +pack(builder:flatbuffers.Builder): flatbuffers.Offset { + return SecondTableInA.createSecondTableInA(builder, + (this.referToC !== null ? this.referToC!.pack(builder) : 0) + ); +}; } } diff --git a/tests/union_vector/union_vector_generated.ts b/tests/union_vector/union_vector_generated.ts index 4c30b667..d8f9f4f3 100644 --- a/tests/union_vector/union_vector_generated.ts +++ b/tests/union_vector/union_vector_generated.ts @@ -13,6 +13,39 @@ export enum Character{ Unused= 6 }; +export function unionToCharacter( + type: Character, + accessor: (obj:Attacker|BookReader|Rapunzel|string) => Attacker|BookReader|Rapunzel|string|null +): Attacker|BookReader|Rapunzel|string|null { + switch(Character[type]) { + case 'NONE': return null; + case 'MuLan': return accessor(new Attacker())! as Attacker; + case 'Rapunzel': return accessor(new Rapunzel())! as Rapunzel; + case 'Belle': return accessor(new BookReader())! as BookReader; + case 'BookFan': return accessor(new BookReader())! as BookReader; + case 'Other': return accessor('') as string; + case 'Unused': return accessor('') as string; + default: return null; + } +} + +export function unionListToCharacter( + type: Character, + accessor: (index: number, obj:Attacker|BookReader|Rapunzel|string) => Attacker|BookReader|Rapunzel|string|null, + index: number +): Attacker|BookReader|Rapunzel|string|null { + switch(Character[type]) { + case 'NONE': return null; + case 'MuLan': return accessor(index, new Attacker())! as Attacker; + case 'Rapunzel': return accessor(index, new Rapunzel())! as Rapunzel; + case 'Belle': return accessor(index, new BookReader())! as BookReader; + case 'BookFan': return accessor(index, new BookReader())! as BookReader; + case 'Other': return accessor(index, '') as string; + case 'Unused': return accessor(index, '') as string; + default: return null; + } +} + /** * @constructor */ @@ -102,6 +135,42 @@ static createAttacker(builder:flatbuffers.Builder, swordAttackDamage:number):fla Attacker.addSwordAttackDamage(builder, swordAttackDamage); return Attacker.endAttacker(builder); } + +/** + * @returns AttackerT + */ +unpack(): AttackerT { + return new AttackerT( + this.swordAttackDamage() + ); +}; + +/** + * @param AttackerT _o + */ +unpackTo(_o: AttackerT): void { + _o.swordAttackDamage = this.swordAttackDamage(); +}; +} + +export class AttackerT { +/** + * @constructor + * @param number swordAttackDamage + */ +constructor( + public swordAttackDamage: number = 0 +){}; + +/** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ +pack(builder:flatbuffers.Builder): flatbuffers.Offset { + return Attacker.createAttacker(builder, + this.swordAttackDamage + ); +}; } /** * @constructor @@ -154,6 +223,42 @@ static createRapunzel(builder:flatbuffers.Builder, hair_length: number):flatbuff return builder.offset(); }; + +/** + * @returns RapunzelT + */ +unpack(): RapunzelT { + return new RapunzelT( + this.hairLength() + ); +}; + +/** + * @param RapunzelT _o + */ +unpackTo(_o: RapunzelT): void { + _o.hairLength = this.hairLength(); +}; +} + +export class RapunzelT { +/** + * @constructor + * @param number hairLength + */ +constructor( + public hairLength: number = 0 +){}; + +/** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ +pack(builder:flatbuffers.Builder): flatbuffers.Offset { + return Rapunzel.createRapunzel(builder, + this.hairLength + ); +}; } /** * @constructor @@ -206,6 +311,42 @@ static createBookReader(builder:flatbuffers.Builder, books_read: number):flatbuf return builder.offset(); }; + +/** + * @returns BookReaderT + */ +unpack(): BookReaderT { + return new BookReaderT( + this.booksRead() + ); +}; + +/** + * @param BookReaderT _o + */ +unpackTo(_o: BookReaderT): void { + _o.booksRead = this.booksRead(); +}; +} + +export class BookReaderT { +/** + * @constructor + * @param number booksRead + */ +constructor( + public booksRead: number = 0 +){}; + +/** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ +pack(builder:flatbuffers.Builder): flatbuffers.Offset { + return BookReader.createBookReader(builder, + this.booksRead + ); +}; } /** * @constructor @@ -264,9 +405,9 @@ mainCharacterType():Character { * @param flatbuffers.Table obj * @returns ?flatbuffers.Table */ -mainCharacter<T extends flatbuffers.Table>(obj:T):T|null { +mainCharacter<T extends flatbuffers.Table>(obj:T|string):T|string|null { var offset = this.bb!.__offset(this.bb_pos, 6); - return offset ? this.bb!.__union(obj, this.bb_pos + offset) : null; + return offset ? this.bb!.__union_with_string(obj, this.bb_pos + offset) : null; }; /** @@ -299,9 +440,9 @@ charactersTypeArray():Uint8Array|null { * @param flatbuffers.Table= obj * @returns ?flatbuffers.Table */ -characters<T extends flatbuffers.Table>(index: number, obj:T):T|null { +characters<T extends flatbuffers.Table>(index: number, obj:T|string):T|string|null { var offset = this.bb!.__offset(this.bb_pos, 10); - return offset ? this.bb!.__union(obj, this.bb!.__vector(this.bb_pos + offset) + index * 4) : null; + return offset ? this.bb!.__union_with_string(obj, this.bb!.__vector(this.bb_pos + offset) + index * 4) : null; }; /** @@ -426,4 +567,93 @@ static createMovie(builder:flatbuffers.Builder, mainCharacterType:Character, mai Movie.addCharacters(builder, charactersOffset); return Movie.endMovie(builder); } + +/** + * @returns MovieT + */ +unpack(): MovieT { + return new MovieT( + this.mainCharacterType(), + (() => { + let temp = unionToCharacter(this.mainCharacterType(), this.mainCharacter.bind(this)); + if(temp === null) { return null; } + if(typeof temp === 'string') { return temp; } + return temp.unpack() + })(), + this.bb!.createScalarList(this.charactersType.bind(this), this.charactersTypeLength()), + (() => { + let ret = []; + for(let targetEnumIndex = 0; targetEnumIndex < this.charactersTypeLength(); ++targetEnumIndex) { + let targetEnum = this.charactersType(targetEnumIndex); + if(targetEnum === null || Character[targetEnum!] === 'NONE') { continue; } + + let temp = unionListToCharacter(targetEnum, this.characters.bind(this), targetEnumIndex); + if(temp === null) { continue; } + if(typeof temp === 'string') { ret.push(temp); continue; } + ret.push(temp.unpack()); + } + return ret; + })() + ); +}; + +/** + * @param MovieT _o + */ +unpackTo(_o: MovieT): void { + _o.mainCharacterType = this.mainCharacterType(); + _o.mainCharacter = (() => { + let temp = unionToCharacter(this.mainCharacterType(), this.mainCharacter.bind(this)); + if(temp === null) { return null; } + if(typeof temp === 'string') { return temp; } + return temp.unpack() + })(); + _o.charactersType = this.bb!.createScalarList(this.charactersType.bind(this), this.charactersTypeLength()); + _o.characters = (() => { + let ret = []; + for(let targetEnumIndex = 0; targetEnumIndex < this.charactersTypeLength(); ++targetEnumIndex) { + let targetEnum = this.charactersType(targetEnumIndex); + if(targetEnum === null || Character[targetEnum!] === 'NONE') { continue; } + + let temp = unionListToCharacter(targetEnum, this.characters.bind(this), targetEnumIndex); + if(temp === null) { continue; } + if(typeof temp === 'string') { ret.push(temp); continue; } + ret.push(temp.unpack()); + } + return ret; + })(); +}; +} + +export class MovieT { +/** + * @constructor + * @param Character mainCharacterType + * @param AttackerT|BookReaderT|RapunzelT|string|null mainCharacter + * @param (Character)[] charactersType + * @param (AttackerT|BookReaderT|RapunzelT|string)[] characters + */ +constructor( + public mainCharacterType: Character = Character.NONE, + public mainCharacter: AttackerT|BookReaderT|RapunzelT|string|null = null, + public charactersType: (Character)[] = [], + public characters: (AttackerT|BookReaderT|RapunzelT|string)[] = [] +){}; + +/** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ +pack(builder:flatbuffers.Builder): flatbuffers.Offset { + const mainCharacter = builder.createObjectOffset(this.mainCharacter); + const charactersType = Movie.createCharactersTypeVector(builder, this.charactersType); + const characters = Movie.createCharactersVector(builder, builder.createObjectOffsetList(this.characters)); + + return Movie.createMovie(builder, + this.mainCharacterType, + mainCharacter, + charactersType, + characters + ); +}; } |