diff --git a/docs/source/tutorial.md b/docs/source/tutorial.md
index 0f06d9a2d..cfa0b1c99 100644
--- a/docs/source/tutorial.md
+++ b/docs/source/tutorial.md
@@ -290,7 +290,8 @@ generally involves two things:
// Convenient namespace macro to manage long namespace prefix.
#undef ns
- #define ns(x) FLATBUFFERS_WRAP_NAMESPACE(MyGame_Sample, x) // Specified in the schema.
+ // Specified in the schema.
+ #define ns(x) FLATBUFFERS_WRAP_NAMESPACE(MyGame_Sample, x)
// A helper to simplify creating vectors from C-arrays.
#define c_vec_len(V) (sizeof(V)/sizeof((V)[0]))
@@ -337,10 +338,10 @@ generally involves two things:
var flatbuffers = require('/js/flatbuffers').flatbuffers;
var MyGame = require('./monster_generated').MyGame; // Generated by `flatc`.
- //--------------------------------------------------------------------------//
+ //------------------------------------------------------------------------//
- // The following code is for browser-based HTML/JavaScript. Use the above code
- // for JavaScript module loaders (e.g. Node.js).
+ // The following code is for browser-based HTML/JavaScript. Use the above
+ // code for JavaScript module loaders (e.g. Node.js).
// Generated by `flatc`.
```
@@ -377,8 +378,8 @@ generally involves two things:
=== "PHP"
```php
- // It is recommended that your use PSR autoload when using FlatBuffers in PHP.
- // Here is an example from `SampleBinary.php`:
+ // It is recommended that your use PSR autoload when using FlatBuffers in
+ // PHP. Here is an example from `SampleBinary.php`:
function __autoload($class_name) {
// The last segment of the class name matches the file name.
$class = substr($class_name, strrpos($class_name, "\\") + 1);
@@ -494,6 +495,10 @@ for it. The builder will automatically resize the backing buffer when necessary.
=== "C"
```c
+ flatcc_builder_t builder, *B;
+ B = &builder;
+ // Initialize the builder object.
+ flatcc_builder_init(B);
```
=== "C#"
@@ -506,61 +511,85 @@ for it. The builder will automatically resize the backing buffer when necessary.
=== "Dart"
```dart
+ // Construct a Builder with 1024 byte backing array.
+ var builder = new fb.Builder(initialSize: 1024);
```
=== "Go"
```go
+ // Construct a Builder with 1024 byte backing array.
+ builder := flatbuffers.NewBuilder(1024)
```
=== "Java"
```java
+ // Construct a Builder with 1024 byte backing array.
+ FlatBufferBuilder builder = new FlatBufferBuilder(1024);
```
=== "JavaScript"
```javascript
+ // Construct a Builder with 1024 byte backing array.
+ var builder = new flatbuffers.Builder(1024);
```
=== "Kotlin"
```kotlin
+ // Construct a Builder with 1024 byte backing array.
+ val builder = FlatBufferBuilder(1024)
```
=== "Lobster"
```lobster
+ // Construct a Builder with 1024 byte backing array.
+ let builder = flatbuffers_builder {}
```
=== "Lua"
```lua
+ -- Construct a Builder with 1024 byte backing array.
+ local builder = flatbuffers.Builder(1024)
```
=== "PHP"
```php
+ // Construct a Builder with 1024 byte backing array.
+ $builder = new Google\FlatBuffers\FlatbufferBuilder(1024);
```
=== "Python"
```py
+ # Construct a Builder with 1024 byte backing array.
+ builder = flatbuffers.Builder(1024)
```
=== "Rust"
```rust
+ // Construct a Builder with 1024 byte backing array.
+ let mut builder = flatbuffers::FlatBufferBuilder::with_capacity(1024);
```
=== "Swift"
```swift
+ // Construct a Builder with 1024 byte backing array.
+ let builder = FlatBufferBuilder(initialSize: 1024)
```
=== "TypeScript"
```ts
+ // Construct a Builder with 1024 byte backing array.
+ let builder = new flatbuffers.Builder(1024);
```
Once a Builder is available, data can be serialized to it via the Builder APIs
@@ -570,7 +599,8 @@ and the generated code.
In this tutorial, we are building `Monsters` and `Weapons` for a computer game.
A `Weapon` is represented by a flatbuffer `table` with some fields. One field is
-the `name` field, which is type `string`.
+the `name` field, which is type `string` and the other `damage` field is a
+numerical scalar.
```c title="monster.fbs" linenums="28"
table Weapon {
@@ -583,7 +613,9 @@ table Weapon {
Since `string` is a reference type, we first need to serialize it before
assigning it to the `name` field of the `Weapon` table. This is done through the
-Builder `CreateString` method:
+Builder `CreateString` method.
+
+Let's serialize two weapon strings.
=== "C++"
@@ -592,9 +624,16 @@ Builder `CreateString` method:
flatbuffers::Offset weapon_two_name = builder.CreateString("Axe");
```
+ `flatbuffers::Offset<>` is a just a "typed" integer tied to a particular
+ type. It helps make the numerical offset more strongly typed.
+
=== "C"
```c
+ flatbuffers_string_ref_t weapon_one_name
+ = flatbuffers_string_create_str(B, "Sword");
+ flatbuffers_string_ref_t weapon_two_name
+ = flatbuffers_string_create_str(B, "Axe");
```
=== "C#"
@@ -607,61 +646,85 @@ Builder `CreateString` method:
=== "Dart"
```dart
+ final int weaponOneName = builder.writeString("Sword");
+ final int weaponTwoName = builder.writeString("Axe");
```
=== "Go"
```go
+ weaponOne := builder.CreateString("Sword")
+ weaponTwo := builder.CreateString("Axe")
```
=== "Java"
```java
+ int weaponOneName = builder.createString("Sword")
+ int weaponTwoName = builder.createString("Axe");
```
=== "JavaScript"
```javascript
+ var weaponOne = builder.createString('Sword');
+ var weaponTwo = builder.createString('Axe');
```
=== "Kotlin"
```kotlin
+ val weaponOneName = builder.createString("Sword")
+ val weaponTwoName = builder.createString("Axe")
```
=== "Lobster"
```lobster
+ let weapon_one = builder.CreateString("Sword")
+ let weapon_two = builder.CreateString("Axe")
```
=== "Lua"
```lua
+ local weaponOne = builder:CreateString("Sword")
+ local weaponTwo = builder:CreateString("Axe")
```
=== "PHP"
```php
+ $weapon_one_name = $builder->createString("Sword")
+ $weapon_two_name = $builder->createString("Axe");
```
=== "Python"
```py
+ weapon_one = builder.CreateString('Sword')
+ weapon_two = builder.CreateString('Axe')
```
=== "Rust"
```rust
+ let weapon_one_name = builder.create_string("Sword");
+ let weapon_two_name = builder.create_string("Axe");
```
=== "Swift"
```swift
+ let weapon1Name = builder.create(string: "Sword")
+ let weapon2Name = builder.create(string: "Axe")
```
=== "TypeScript"
- ```ts
+ ```ts
+ let weaponOne = builder.createString('Sword');
+ let weaponTwo = builder.createString('Axe');
```
@@ -672,10 +735,10 @@ the buffer.
#### Tables
-Now that we have some names serialized, we can serialize `Weapons`. Here we will
-use one of the generated helper functions that was emitted by `flatc`. The
-`CreateWeapon` function takes in the Builder object, as well as the offset to
-the weapon's name and a numerical value for the damage field.
+Now that we have some names serialized, we can serialize the `Weapon` tables.
+Here we will use one of the generated helper functions that was emitted by
+`flatc`. The `CreateWeapon` function takes in the Builder object, as well as the
+offset to the weapon's name and a numerical value for the damage field.
=== "C++"
@@ -683,7 +746,8 @@ the weapon's name and a numerical value for the damage field.
short weapon_one_damage = 3;
short weapon_two_damage = 5;
- // Use the `CreateWeapon()` shortcut to create Weapons with all the fields set.
+ // Use the `CreateWeapon()` shortcut to create Weapons with all the fields
+ // set.
flatbuffers::Offset sword =
CreateWeapon(builder, weapon_one_name, weapon_one_damage);
flatbuffers::Offset axe =
@@ -693,6 +757,13 @@ the weapon's name and a numerical value for the damage field.
=== "C"
```c
+ uint16_t weapon_one_damage = 3;
+ uint16_t weapon_two_damage = 5;
+
+ ns(Weapon_ref_t) sword
+ = ns(Weapon_create(B, weapon_one_name, weapon_one_damage));
+ ns(Weapon_ref_t) axe
+ = ns(Weapon_create(B, weapon_two_name, weapon_two_damage));
```
=== "C#"
@@ -701,7 +772,8 @@ the weapon's name and a numerical value for the damage field.
short weaponOneDamage = 3;
short weaponTwoDamage = 5;
- // Use the `CreateWeapon()` helper function to create the weapons, since we set every field.
+ // Use the `CreateWeapon()` helper function to create the weapons, since we
+ // set every field.
Offset sword =
Weapon.CreateWeapon(builder, weaponOneName, weaponOneDamage);
Offset axe =
@@ -711,61 +783,193 @@ the weapon's name and a numerical value for the damage field.
=== "Dart"
```dart
+ final int weaponOneDamage = 3;
+ final int weaponTwoDamage = 5;
+
+ final swordBuilder = new myGame.WeaponBuilder(builder)
+ ..begin()
+ ..addNameOffset(weaponOneName)
+ ..addDamage(weaponOneDamage);
+ final int sword = swordBuilder.finish();
+
+ final axeBuilder = new myGame.WeaponBuilder(builder)
+ ..begin()
+ ..addNameOffset(weaponTwoName)
+ ..addDamage(weaponTwoDamage);
+ final int axe = axeBuilder.finish();
+ ```
+
+ Note, as an alternative, the previous steps can be combined using the
+ generative Builder classes.
+
+ ```dart
+ final myGame.WeaponBuilder sword = new myGame.WeaponObjectBuilder(
+ name: "Sword",
+ damage: 3,
+ );
+
+ final myGame.WeaponBuilder axe = new myGame.WeaponObjectBuilder(
+ name: "Axe",
+ damage: 5,
+ );
```
=== "Go"
```go
+ // Create the first `Weapon` ("Sword").
+ sample.WeaponStart(builder)
+ sample.WeaponAddName(builder, weaponOne)
+ sample.WeaponAddDamage(builder, 3)
+ sword := sample.WeaponEnd(builder)
+
+ // Create the second `Weapon` ("Axe").
+ sample.WeaponStart(builder)
+ sample.WeaponAddName(builder, weaponTwo)
+ sample.WeaponAddDamage(builder, 5)
+ axe := sample.WeaponEnd(builder)
```
=== "Java"
```java
+ short weaponOneDamage = 3;
+ short weaponTwoDamage = 5;
+
+ // Use the `createWeapon()` helper function to create the weapons, since we
+ // set every field.
+ int sword = Weapon.createWeapon(builder, weaponOneName, weaponOneDamage);
+ int axe = Weapon.createWeapon(builder, weaponTwoName, weaponTwoDamage);
```
=== "JavaScript"
```javascript
+ // Create the first `Weapon` ('Sword').
+ MyGame.Sample.Weapon.startWeapon(builder);
+ MyGame.Sample.Weapon.addName(builder, weaponOne);
+ MyGame.Sample.Weapon.addDamage(builder, 3);
+ var sword = MyGame.Sample.Weapon.endWeapon(builder);
+
+ // Create the second `Weapon` ('Axe').
+ MyGame.Sample.Weapon.startWeapon(builder);
+ MyGame.Sample.Weapon.addName(builder, weaponTwo);
+ MyGame.Sample.Weapon.addDamage(builder, 5);
+ var axe = MyGame.Sample.Weapon.endWeapon(builder);
```
=== "Kotlin"
```kotlin
+ val weaponOneDamage: Short = 3;
+ val weaponTwoDamage: Short = 5;
+
+ // Use the `createWeapon()` helper function to create the weapons, since we
+ // set every field.
+ val sword = Weapon.createWeapon(builder, weaponOneName, weaponOneDamage)
+ val axe = Weapon.createWeapon(builder, weaponTwoName, weaponTwoDamage)
```
=== "Lobster"
```lobster
+ let sword = MyGame_Sample_WeaponBuilder { b }
+ .start()
+ .add_name(weapon_one)
+ .add_damage(3)
+ .end()
+
+ let axe = MyGame_Sample_WeaponBuilder { b }
+ .start()
+ .add_name(weapon_two)
+ .add_damage(5)
+ .end()
```
=== "Lua"
```lua
+ -- Create the first 'Weapon'
+ weapon.Start(builder)
+ weapon.AddName(builder, weaponOne)
+ weapon.AddDamage(builder, 3)
+ local sword = weapon.End(builder)
+
+ -- Create the second 'Weapon'
+ weapon.Start(builder)
+ weapon.AddName(builder, weaponTwo)
+ weapon.AddDamage(builder, 5)
+ local axe = weapon.End(builder)
```
=== "PHP"
```php
+ $sword = \MyGame\Sample\Weapon::CreateWeapon($builder, $weapon_one_name, 3);
+ $axe = \MyGame\Sample\Weapon::CreateWeapon($builder, $weapon_two_name, 5);
```
=== "Python"
```py
+ # Create the first `Weapon` ('Sword').
+ MyGame.Sample.Weapon.Start(builder)
+ MyGame.Sample.Weapon.AddName(builder, weapon_one)
+ MyGame.Sample.Weapon.AddDamage(builder, 3)
+ sword = MyGame.Sample.Weapon.End(builder)
+
+ # Create the second `Weapon` ('Axe').
+ MyGame.Sample.Weapon.Start(builder)
+ MyGame.Sample.Weapon.AddName(builder, weapon_two)
+ MyGame.Sample.Weapon.AddDamage(builder, 5)
+ axe = MyGame.Sample.Weapon.End(builder)
```
=== "Rust"
```rust
+ // Use the `Weapon::create` shortcut to create Weapons with named field
+ // arguments.
+ let sword = Weapon::create(&mut builder, &WeaponArgs{
+ name: Some(weapon_one_name),
+ damage: 3,
+ });
+ let axe = Weapon::create(&mut builder, &WeaponArgs{
+ name: Some(weapon_two_name),
+ damage: 5,
+ });
```
=== "Swift"
```swift
+ // start creating the weapon by calling startWeapon
+ let weapon1Start = Weapon.startWeapon(&builder)
+ Weapon.add(name: weapon1Name, &builder)
+ Weapon.add(damage: 3, &builder)
+ // end the object by passing the start point for the weapon 1
+ let sword = Weapon.endWeapon(&builder, start: weapon1Start)
+
+ let weapon2Start = Weapon.startWeapon(&builder)
+ Weapon.add(name: weapon2Name, &builder)
+ Weapon.add(damage: 5, &builder)
+ let axe = Weapon.endWeapon(&builder, start: weapon2Start)
```
=== "TypeScript"
```ts
+ // Create the first `Weapon` ('Sword').
+ MyGame.Sample.Weapon.startWeapon(builder);
+ MyGame.Sample.Weapon.addName(builder, weaponOne);
+ MyGame.Sample.Weapon.addDamage(builder, 3);
+ let sword = MyGame.Sample.Weapon.endWeapon(builder);
+
+ // Create the second `Weapon` ('Axe').
+ MyGame.Sample.Weapon.startWeapon(builder);
+ MyGame.Sample.Weapon.addName(builder, weaponTwo);
+ MyGame.Sample.Weapon.addDamage(builder, 5);
+ let axe = MyGame.Sample.Weapon.endWeapon(builder);
```
@@ -825,6 +1029,11 @@ The Builder provides multiple ways to create `vectors`.
=== "C"
```c
+ // We use the internal builder stack to implement a dynamic vector.
+ ns(Weapon_vec_start(B));
+ ns(Weapon_vec_push(B, sword));
+ ns(Weapon_vec_push(B, axe));
+ ns(Weapon_vec_ref_t) weapons = ns(Weapon_vec_end(B));
```
=== "C#"
@@ -843,61 +1052,119 @@ The Builder provides multiple ways to create `vectors`.
=== "Dart"
```dart
+ // If using the Builder classes, serialize the `[sword,axe]`
+ final weapons = builder.writeList([sword, axe]);
+
+ // If using the ObjectBuilders, just create an array from the two `Weapon`s
+ final List weaps = [sword, axe];
```
=== "Go"
```go
+ // Create a FlatBuffer vector and prepend the weapons.
+ // Note: Since we prepend the data, prepend them in reverse order.
+ sample.MonsterStartWeaponsVector(builder, 2)
+ builder.PrependUOffsetT(axe)
+ builder.PrependUOffsetT(sword)
+ weapons := builder.EndVector(2)
```
=== "Java"
```java
+ // Place the two weapons into an array, and pass it to the
+ // `createWeaponsVector()` method to create a FlatBuffer vector.
+ int[] weaps = new int[2];
+ weaps[0] = sword;
+ weaps[1] = axe;
+
+ // Pass the `weaps` array into the `createWeaponsVector()` method to create
+ // a FlatBuffer vector.
+ int weapons = Monster.createWeaponsVector(builder, weaps);
```
=== "JavaScript"
```javascript
+ // Create an array from the two `Weapon`s and pass it to the
+ // `createWeaponsVector()` method to create a FlatBuffer vector.
+ var weaps = [sword, axe];
+ var weapons = MyGame.Sample.Monster.createWeaponsVector(builder, weaps);
```
=== "Kotlin"
```kotlin
+ // Place the two weapons into an array, and pass it to the
+ // `createWeaponsVector()` method to create a FlatBuffer vector.
+ val weaps = intArrayOf(sword, axe)
+
+ // Pass the `weaps` array into the `createWeaponsVector()` method to create
+ // a FlatBuffer vector.
+ val weapons = Monster.createWeaponsVector(builder, weaps)
```
=== "Lobster"
```lobster
+ let weapons = builder.MyGame_Sample_MonsterCreateWeaponsVector([sword, axe])
```
=== "Lua"
```lua
+ -- Create a FlatBuffer vector and prepend the weapons.
+ -- Note: Since we prepend the data, prepend them in reverse order.
+ monster.StartWeaponsVector(builder, 2)
+ builder:PrependUOffsetTRelative(axe)
+ builder:PrependUOffsetTRelative(sword)
+ local weapons = builder:EndVector(2)
```
=== "PHP"
```php
+ // Create an array from the two `Weapon`s and pass it to the
+ // `CreateWeaponsVector()` method to create a FlatBuffer vector.
+ $weaps = array($sword, $axe);
+ $weapons = \MyGame\Sample\Monster::CreateWeaponsVector($builder, $weaps);
```
=== "Python"
```py
+ # Create a FlatBuffer vector and prepend the weapons.
+ # Note: Since we prepend the data, prepend them in reverse order.
+ MyGame.Sample.Monster.StartWeaponsVector(builder, 2)
+ builder.PrependUOffsetTRelative(axe)
+ builder.PrependUOffsetTRelative(sword)
+ weapons = builder.EndVector()
```
=== "Rust"
```rust
+ // Create a FlatBuffer `vector` that contains offsets to the sword and axe
+ // we created above.
+ let weapons = builder.create_vector(&[sword, axe]);
```
=== "Swift"
```swift
+ // Create a FlatBuffer `vector` that contains offsets to the sword and axe
+ // we created above.
+ let weaponsOffset = builder.createVector(ofOffsets: [sword, axe])
```
=== "TypeScript"
```ts
+ // Create an array from the two `Weapon`s and pass it to the
+ // `createWeaponsVector()` method to create a FlatBuffer vector.
+ let weaps = [sword, axe];
+ let weapons = MyGame.Sample.Monster.createWeaponsVector(builder, weaps);
```
@@ -909,39 +1176,34 @@ bit more directly.
=== "C++"
```c++
- // Construct an array of two `Vec3` structs.
- Vec3 points[] = { Vec3(1.0f, 2.0f, 3.0f), Vec3(4.0f, 5.0f, 6.0f) };
-
- // Serialize it as a vector of structs.
- flatbuffers::Offset> path =
- builder.CreateVectorOfStructs(points, 2);
-
// Create a `vector` representing the inventory of the Orc. Each number
// could correspond to an item that can be claimed after he is slain.
unsigned char treasure[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
flatbuffers::Offset> inventory =
builder.CreateVector(treasure, 10);
+ // Construct an array of two `Vec3` structs.
+ Vec3 points[] = { Vec3(1.0f, 2.0f, 3.0f), Vec3(4.0f, 5.0f, 6.0f) };
+
+ // Serialize it as a vector of structs.
+ flatbuffers::Offset> path =
+ builder.CreateVectorOfStructs(points, 2);
```
=== "C"
```c
+ // Create a `vector` representing the inventory of the Orc. Each number
+ // could correspond to an item that can be claimed after he is slain.
+ uint8_t treasure[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ flatbuffers_uint8_vec_ref_t inventory;
+ // `c_vec_len` is the convenience macro we defined earlier.
+ inventory = flatbuffers_uint8_vec_create(B, treasure, c_vec_len(treasure));
```
=== "C#"
```c#
- // Start building a path vector of length 2.
- Monster.StartPathVector(fbb, 2);
-
- // Serialize the individual Vec3 structs
- Vec3.CreateVec3(builder, 1.0f, 2.0f, 3.0f);
- Vec3.CreateVec3(builder, 4.0f, 5.0f, 6.0f);
-
- // End the vector to get the offset
- Offset> path = fbb.EndVector();
-
// Create a `vector` representing the inventory of the Orc. Each number
// could correspond to an item that can be claimed after he is slain.
// Note: Since we prepend the bytes, this loop iterates in reverse order.
@@ -951,72 +1213,200 @@ bit more directly.
builder.AddByte((byte)i);
}
Offset> inventory = builder.EndVector();
+
+ // Start building a path vector of length 2.
+ Monster.StartPathVector(fbb, 2);
+
+ // Serialize the individual Vec3 structs
+ Vec3.CreateVec3(builder, 1.0f, 2.0f, 3.0f);
+ Vec3.CreateVec3(builder, 4.0f, 5.0f, 6.0f);
+
+ // End the vector to get the offset
+ Offset> path = fbb.EndVector();
```
=== "Dart"
```dart
+ // Create a list representing the inventory of the Orc. Each number
+ // could correspond to an item that can be claimed after he is slain.
+ final List treasure = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+ final inventory = builder.writeListUint8(treasure);
+
+ // Using the Builder classes, you can write a list of structs like so:
+ // Note that the intended order should be reversed if order is important.
+ final vec3Builder = new myGame.Vec3Builder(builder);
+ vec3Builder.finish(4.0, 5.0, 6.0);
+ vec3Builder.finish(1.0, 2.0, 3.0);
+ final int path = builder.endStructVector(2); // the length of the vector
```
=== "Go"
```go
+ // Create a `vector` representing the inventory of the Orc. Each number
+ // could correspond to an item that can be claimed after he is slain.
+ // Note: Since we prepend the bytes, this loop iterates in reverse.
+ sample.MonsterStartInventoryVector(builder, 10)
+ for i := 9; i >= 0; i-- {
+ builder.PrependByte(byte(i))
+ }
+ inv := builder.EndVector(10)
+
+ sample.MonsterStartPathVector(builder, 2)
+ sample.CreateVec3(builder, 1.0, 2.0, 3.0)
+ sample.CreateVec3(builder, 4.0, 5.0, 6.0)
+ path := builder.EndVector(2)
```
=== "Java"
```java
+ // Create a `vector` representing the inventory of the Orc. Each number
+ // could correspond to an item that can be claimed after he is slain.
+ byte[] treasure = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ int inv = Monster.createInventoryVector(builder, treasure);
+
+ Monster.startPathVector(fbb, 2);
+ Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f);
+ Vec3.createVec3(builder, 4.0f, 5.0f, 6.0f);
+ int path = fbb.endVector();
```
=== "JavaScript"
```javascript
+ // Create a `vector` representing the inventory of the Orc. Each number
+ // could correspond to an item that can be claimed after he is slain.
+ var treasure = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+ var inv = MyGame.Sample.Monster.createInventoryVector(builder, treasure);
+
+ MyGame.Sample.Monster.startPathVector(builder, 2);
+ MyGame.Sample.Vec3.createVec3(builder, 1.0, 2.0, 3.0);
+ MyGame.Sample.Vec3.createVec3(builder, 4.0, 5.0, 6.0);
+ var path = builder.endVector();
```
=== "Kotlin"
```kotlin
+ // Create a `vector` representing the inventory of the Orc. Each number
+ // could correspond to an item that can be claimed after he is slain.
+ val treasure = byteArrayOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
+ val inv = Monster.createInventoryVector(builder, treasure)
+
+ Monster.startPathVector(fbb, 2)
+ Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f)
+ Vec3.createVec3(builder, 4.0f, 5.0f, 6.0f)
+ val path = fbb.endVector()
```
=== "Lobster"
```lobster
+ // Inventory.
+ let inv = builder.MyGame_Sample_MonsterCreateInventoryVector(map(10): _)
+
+ builder.MyGame_Sample_MonsterStartPathVector(2)
+ builder.MyGame_Sample_CreateVec3(1.0, 2.0, 3.0)
+ builder.MyGame_Sample_CreateVec3(4.0, 5.0, 6.0)
+ let path = builder.EndVector(2)
```
=== "Lua"
```lua
+ -- Create a `vector` representing the inventory of the Orc. Each number
+ -- could correspond to an item that can be claimed after he is slain.
+ -- Note: Since we prepend the bytes, this loop iterates in reverse.
+ monster.StartInventoryVector(builder, 10)
+ for i=10,1,-1 do
+ builder:PrependByte(i)
+ end
+ local inv = builder:EndVector(10)
+
+ -- Create a FlatBuffer vector and prepend the path locations.
+ -- Note: Since we prepend the data, prepend them in reverse order.
+ monster.StartPathVector(builder, 2)
+ vec3.CreateVec3(builder, 1.0, 2.0, 3.0)
+ vec3.CreateVec3(builder, 4.0, 5.0, 6.0)
+ local path = builder:EndVector(2)
```
=== "PHP"
```php
+ // Create a `vector` representing the inventory of the Orc. Each number
+ // could correspond to an item that can be claimed after he is slain.
+ $treasure = array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+ $inv = \MyGame\Sample\Monster::CreateInventoryVector($builder, $treasure);
+
+ \MyGame\Example\Monster::StartPathVector($builder, 2);
+ \MyGame\Sample\Vec3::CreateVec3($builder, 1.0, 2.0, 3.0);
+ \MyGame\Sample\Vec3::CreateVec3($builder, 1.0, 2.0, 3.0);
+ $path = $builder->endVector();
```
=== "Python"
```py
+ # Create a `vector` representing the inventory of the Orc. Each number
+ # could correspond to an item that can be claimed after he is slain.
+ # Note: Since we prepend the bytes, this loop iterates in reverse.
+ MyGame.Sample.Monster.StartInventoryVector(builder, 10)
+ for i in reversed(range(0, 10)):
+ builder.PrependByte(i)
+ inv = builder.EndVector()
+
+ MyGame.Sample.Monster.StartPathVector(builder, 2)
+ MyGame.Sample.Vec3.CreateVec3(builder, 1.0, 2.0, 3.0)
+ MyGame.Sample.Vec3.CreateVec3(builder, 4.0, 5.0, 6.0)
+ path = builder.EndVector()
```
=== "Rust"
```rust
+ // Inventory.
+ let inventory = builder.create_vector(&[0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
+
+ // Create the path vector of Vec3 objects.
+ let x = Vec3::new(1.0, 2.0, 3.0);
+ let y = Vec3::new(4.0, 5.0, 6.0);
+ let path = builder.create_vector(&[x, y]);
```
=== "Swift"
```swift
+ // create inventory
+ let inventory: [Byte] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+ let inventoryOffset = builder.createVector(inventory)
+
+ let path = fbb.createVector(ofStructs: [
+ Vec3(x: 1, y: 2, z: 3),
+ Vec3(x: 4, y: 5, z: 6)
+ ])
```
=== "TypeScript"
```ts
+ // Create a `vector` representing the inventory of the Orc. Each number
+ // could correspond to an item that can be claimed after he is slain.
+ let treasure = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+ let inv = MyGame.Sample.Monster.createInventoryVector(builder, treasure);
+
+ MyGame.Sample.Monster.startPathVector(builder, 2);
+ MyGame.Sample.Vec3.createVec3(builder, 1.0, 2.0, 3.0);
+ MyGame.Sample.Vec3.createVec3(builder, 4.0, 5.0, 6.0);
+ let path = builder.endVector();
```
#### Unions
-The last non-scalar data for the `Monster` table is the `equipped` `union`
+The last non-scalar data field for the `Monster` table is the `equipped` `union`
field. For this case, we will reuse an already serialized `Weapon` (the only
type in the union), without needing to reserialize it. Union fields implicitly
add a hidden `_type` field that stores the type of value stored in the union.
@@ -1056,6 +1446,20 @@ the necessary values and Offsets to make a `Monster`.
=== "C"
```c
+ // Serialize a name for our monster, called "Orc".
+ // The _str suffix indicates the source is an ascii-z string.
+ flatbuffers_string_ref_t name = flatbuffers_string_create_str(B, "Orc");
+
+ // Set his hit points to 300 and his mana to 150.
+ uint16_t hp = 300;
+ uint16_t mana = 150;
+
+ // Define an equipment union. `create` calls in C has a single
+ // argument for unions where C++ has both a type and a data argument.
+ ns(Equipment_union_ref_t) equipped = ns(Equipment_as_Weapon(axe));
+ ns(Vec3_t) pos = { 1.0f, 2.0f, 3.0f };
+ ns(Monster_create_as_root(B, &pos, mana, hp, name, inventory, ns(Color_Red),
+ weapons, equipped, path));
```
=== "C#"
@@ -1084,61 +1488,260 @@ the necessary values and Offsets to make a `Monster`.
=== "Dart"
```dart
+ // Serialize a name for our monster, called "Orc".
+ final int name = builder.writeString('Orc');
+
+ // Using the Builder API:
+ // Set his hit points to 300 and his mana to 150.
+ final int hp = 300;
+ final int mana = 150;
+
+ final monster = new myGame.MonsterBuilder(builder)
+ ..begin()
+ ..addNameOffset(name)
+ ..addInventoryOffset(inventory)
+ ..addWeaponsOffset(weapons)
+ ..addEquippedType(myGame.EquipmentTypeId.Weapon)
+ ..addEquippedOffset(axe)
+ ..addHp(hp)
+ ..addMana(mana)
+ ..addPos(vec3Builder.finish(1.0, 2.0, 3.0))
+ ..addPathOffset(path)
+ ..addColor(myGame.Color.Red);
+
+ final int orc = monster.finish();
```
=== "Go"
```go
+ // Serialize a name for our monster, called "Orc".
+ name := builder.CreateString("Orc")
+
+ // Create our monster using `MonsterStart()` and `MonsterEnd()`.
+ sample.MonsterStart(builder)
+ sample.MonsterAddPos(builder, sample.CreateVec3(builder, 1.0, 2.0, 3.0))
+ sample.MonsterAddHp(builder, 300)
+ sample.MonsterAddName(builder, name)
+ sample.MonsterAddInventory(builder, inv)
+ sample.MonsterAddColor(builder, sample.ColorRed)
+ sample.MonsterAddWeapons(builder, weapons)
+ sample.MonsterAddEquippedType(builder, sample.EquipmentWeapon)
+ sample.MonsterAddEquipped(builder, axe)
+ sample.MonsterAddPath(builder, path)
+ orc := sample.MonsterEnd(builder)
```
=== "Java"
```java
+ // Serialize a name for our monster, called "Orc".
+ int name = builder.createString("Orc");
+
+ // Create our monster using `startMonster()` and `endMonster()`.
+ Monster.startMonster(builder);
+ Monster.addPos(builder, Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f));
+ Monster.addName(builder, name);
+ Monster.addColor(builder, Color.Red);
+ Monster.addHp(builder, (short)300);
+ Monster.addInventory(builder, inv);
+ Monster.addWeapons(builder, weapons);
+ Monster.addEquippedType(builder, Equipment.Weapon);
+ Monster.addEquipped(builder, axe);
+ Monster.addPath(builder, path);
+ int orc = Monster.endMonster(builder);
```
=== "JavaScript"
```javascript
+ // Serialize a name for our monster, called 'Orc'.
+ var name = builder.createString('Orc');
+
+ // Create our monster by using `startMonster()` and `endMonster()`.
+ MyGame.Sample.Monster.startMonster(builder);
+ MyGame.Sample.Monster.addPos(builder,
+ MyGame.Sample.Vec3.createVec3(builder, 1.0, 2.0, 3.0));
+ MyGame.Sample.Monster.addHp(builder, 300);
+ MyGame.Sample.Monster.addColor(builder, MyGame.Sample.Color.Red)
+ MyGame.Sample.Monster.addName(builder, name);
+ MyGame.Sample.Monster.addInventory(builder, inv);
+ MyGame.Sample.Monster.addWeapons(builder, weapons);
+ MyGame.Sample.Monster.addEquippedType(builder,
+ MyGame.Sample.Equipment.Weapon);
+ MyGame.Sample.Monster.addEquipped(builder, axe);
+ MyGame.Sample.Monster.addPath(builder, path);
+ var orc = MyGame.Sample.Monster.endMonster(builder);
```
=== "Kotlin"
```kotlin
+ // Serialize a name for our monster, called "Orc".
+ val name = builder.createString("Orc")
+
+ // Create our monster using `startMonster()` and `endMonster()`.
+ Monster.startMonster(builder)
+ Monster.addPos(builder, Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f))
+ Monster.addName(builder, name)
+ Monster.addColor(builder, Color.Red)
+ Monster.addHp(builder, 300.toShort())
+ Monster.addInventory(builder, inv)
+ Monster.addWeapons(builder, weapons)
+ Monster.addEquippedType(builder, Equipment.Weapon)
+ Monster.addEquipped(builder, axe)
+ Monster.addPath(builder, path)
+ val orc = Monster.endMonster(builder)
```
=== "Lobster"
```lobster
+ // Name of the monster.
+ let name = builder.CreateString("Orc")
+
+ let orc = MyGame_Sample_MonsterBuilder { b }
+ .start()
+ .add_pos(b.MyGame_Sample_CreateVec3(1.0, 2.0, 3.0))
+ .add_hp(300)
+ .add_name(name)
+ .add_inventory(inv)
+ .add_color(MyGame_Sample_Color_Red)
+ .add_weapons(weapons)
+ .add_equipped_type(MyGame_Sample_Equipment_Weapon)
+ .add_equipped(weapon_offsets[1])
+ .add_path(path)
+ .end()
```
=== "Lua"
```lua
+ -- Serialize a name for our monster, called 'orc'
+ local name = builder:CreateString("Orc")
+
+ -- Create our monster by using Start() andEnd()
+ monster.Start(builder)
+ monster.AddPos(builder, vec3.CreateVec3(builder, 1.0, 2.0, 3.0))
+ monster.AddHp(builder, 300)
+ monster.AddName(builder, name)
+ monster.AddInventory(builder, inv)
+ monster.AddColor(builder, color.Red)
+ monster.AddWeapons(builder, weapons)
+ monster.AddEquippedType(builder, equipment.Weapon)
+ monster.AddEquipped(builder, axe)
+ monster.AddPath(builder, path)
+ local orc = monster.End(builder)
```
=== "PHP"
```php
+ // Serialize a name for our monster, called "Orc".
+ $name = $builder->createString("Orc");
+
+ // Create our monster by using `StartMonster()` and `EndMonster()`.
+ \MyGame\Sample\Monster::StartMonster($builder);
+ \MyGame\Sample\Monster::AddPos($builder,
+ \MyGame\Sample\Vec3::CreateVec3($builder, 1.0, 2.0, 3.0));
+ \MyGame\Sample\Monster::AddHp($builder, 300);
+ \MyGame\Sample\Monster::AddName($builder, $name);
+ \MyGame\Sample\Monster::AddInventory($builder, $inv);
+ \MyGame\Sample\Monster::AddColor($builder, \MyGame\Sample\Color::Red);
+ \MyGame\Sample\Monster::AddWeapons($builder, $weapons);
+ \MyGame\Sample\Monster::AddEquippedType($builder,
+ \MyGame\Sample\Equipment::Weapon);
+ \MyGame\Sample\Monster::AddEquipped($builder, $axe);
+ \MyGame\Sample\Monster::AddPath($builder, $path);
+ $orc = \MyGame\Sample\Monster::EndMonster($builder);
```
=== "Python"
```py
+ # Serialize a name for our monster, called "Orc".
+ name = builder.CreateString("Orc")
+
+ # Create our monster by using `Monster.Start()` and `Monster.End()`.
+ MyGame.Sample.Monster.Start(builder)
+ MyGame.Sample.Monster.AddPos(builder,
+ MyGame.Sample.Vec3.CreateVec3(builder, 1.0, 2.0, 3.0))
+ MyGame.Sample.Monster.AddHp(builder, 300)
+ MyGame.Sample.Monster.AddName(builder, name)
+ MyGame.Sample.Monster.AddInventory(builder, inv)
+ MyGame.Sample.Monster.AddColor(builder,
+ MyGame.Sample.Color.Color().Red)
+ MyGame.Sample.Monster.AddWeapons(builder, weapons)
+ MyGame.Sample.Monster.AddEquippedType(
+ builder, MyGame.Sample.Equipment.Equipment().Weapon)
+ MyGame.Sample.Monster.AddEquipped(builder, axe)
+ MyGame.Sample.Monster.AddPath(builder, path)
+ orc = MyGame.Sample.Monster.End(builder)
```
=== "Rust"
```rust
+ // Name of the Monster.
+ let name = builder.create_string("Orc");
+
+ // Create the monster using the `Monster::create` helper function. This
+ // function accepts a `MonsterArgs` struct, which supplies all of the data
+ // needed to build a `Monster`. To supply empty/default fields, just use the
+ // Rust built-in `Default::default()` function, as demonstrated below.
+ let orc = Monster::create(&mut builder, &MonsterArgs{
+ pos: Some(&Vec3::new(1.0f32, 2.0f32, 3.0f32)),
+ mana: 150,
+ hp: 80,
+ name: Some(name),
+ inventory: Some(inventory),
+ color: Color::Red,
+ weapons: Some(weapons),
+ equipped_type: Equipment::Weapon,
+ equipped: Some(axe.as_union_value()),
+ path: Some(path),
+ ..Default::default()
+ });
```
=== "Swift"
```swift
+ // Name of the Monster.
+ let name = builder.create(string: "Orc")
+
+ let orc = Monster.createMonster(
+ &builder,
+ pos: MyGame_Sample_Vec3(x: 1, y: 2, z: 3),
+ hp: 300,
+ nameOffset: name,
+ inventoryVectorOffset: inventoryOffset,
+ color: .red,
+ weaponsVectorOffset: weaponsOffset,
+ equippedType: .weapon,
+ equippedOffset: axe)
```
=== "TypeScript"
```ts
+ // Serialize a name for our monster, called 'Orc'.
+ let name = builder.createString('Orc');
+
+ // Create our monster by using `startMonster()` and `endMonster()`.
+ MyGame.Sample.Monster.startMonster(builder);
+ MyGame.Sample.Monster.addPos(builder,
+ MyGame.Sample.Vec3.createVec3(builder, 1.0, 2.0, 3.0));
+ MyGame.Sample.Monster.addHp(builder, 300);
+ MyGame.Sample.Monster.addColor(builder, MyGame.Sample.Color.Red)
+ MyGame.Sample.Monster.addName(builder, name);
+ MyGame.Sample.Monster.addInventory(builder, inv);
+ MyGame.Sample.Monster.addWeapons(builder, weapons);
+ MyGame.Sample.Monster.addEquippedType(builder,
+ MyGame.Sample.Equipment.Weapon);
+ MyGame.Sample.Monster.addEquipped(builder, axe);
+ MyGame.Sample.Monster.addPath(builder, path);
+ let orc = MyGame.Sample.Monster.endMonster(builder);
```
@@ -1163,6 +1766,8 @@ deserializing the buffer later.
=== "C"
```c
+ // Because we used `Monster_create_as_root`, we do not need a `finish` call
+ // in C.
```
=== "C#"
@@ -1176,61 +1781,86 @@ deserializing the buffer later.
=== "Dart"
```dart
+ // Call `finish()` to instruct the builder that this monster is complete.
+ // See the next code section, as in Dart `finish` will also return the byte
+ // array.
```
=== "Go"
```go
+ // Call `Finish()` to instruct the builder that this monster is complete.
+ builder.Finish(orc)
```
=== "Java"
```java
+ // Call `finish()` to instruct the builder that this monster is complete.
+ builder.finish(orc);
```
=== "JavaScript"
```javascript
+ // Call `finish()` to instruct the builder that this monster is complete.
+ builder.finish(orc);
```
=== "Kotlin"
```kotlin
+ // Call `finish()` to instruct the builder that this monster is complete.
+ builder.finish(orc) ;
```
=== "Lobster"
```lobster
+ // Call `Finish()` to instruct the builder that this monster is complete.
+ builder.Finish(orc)
```
=== "Lua"
```lua
+ -- Call 'Finish()' to instruct the builder that this monster is complete.
+ builder:Finish(orc)
```
=== "PHP"
```php
+ // Call `finish()` to instruct the builder that this monster is complete.
+ $builder->finish($orc);
```
=== "Python"
```py
+ # Call `Finish()` to instruct the builder that this monster is complete.
+ builder.Finish(orc)
```
=== "Rust"
```rust
+ // Call `finish()` to instruct the builder that this monster is complete.
+ builder.finish(orc, None);
```
=== "Swift"
```swift
+ // Call `finish()` to instruct the builder that this monster is complete.
+ builder.finish(offset: orc)
```
=== "TypeScript"
```ts
+ // Call `finish()` to instruct the builder that this monster is complete.
+ builder.finish(orc);
```
@@ -1255,6 +1885,25 @@ like so:
=== "C"
```c
+ uint8_t *buf;
+ size_t size;
+
+ // Allocate and extract a readable buffer from internal builder heap.
+ // The returned buffer must be deallocated using `free`.
+ // NOTE: Finalizing the buffer does NOT change the builder, it
+ // just creates a snapshot of the builder content.
+ buf = flatcc_builder_finalize_buffer(B, &size);
+ // use buf
+ free(buf);
+
+ // Optionally reset builder to reuse builder without deallocating
+ // internal stack and heap.
+ flatcc_builder_reset(B);
+ // build next buffer.
+ // ...
+
+ // Cleanup.
+ flatcc_builder_clear(B);
```
=== "C#"
@@ -1274,61 +1923,101 @@ like so:
=== "Dart"
```dart
+ final Uint8List buf = builder.finish(orc);
```
=== "Go"
```go
+ // This must be called after `Finish()`.
+ buf := builder.FinishedBytes() // Of type `byte[]`.
```
=== "Java"
```java
+ // This must be called after `finish()`.
+ java.nio.ByteBuffer buf = builder.dataBuffer();
+ // The data in this ByteBuffer does NOT start at 0, but at buf.position().
+ // The number of bytes is buf.remaining().
+
+ // Alternatively this copies the above data out of the ByteBuffer for you:
+ byte[] buf = builder.sizedByteArray();
```
=== "JavaScript"
```javascript
+ // This must be called after `finish()`.
+ var buf = builder.asUint8Array(); // Of type `Uint8Array`.
```
=== "Kotlin"
```kotlin
+ // This must be called after `finish()`.
+ val buf = builder.dataBuffer()
+ // The data in this ByteBuffer does NOT start at 0, but at buf.position().
+ // The number of bytes is buf.remaining().
+
+ // Alternatively this copies the above data out of the ByteBuffer for you:
+ val buf = builder.sizedByteArray()
```
=== "Lobster"
```lobster
+ // This must be called after `Finish()`.
+ let buf = builder.SizedCopy() // Of type `string`.
```
=== "Lua"
```lua
+ local bufAsString = builder:Output()
```
=== "PHP"
```php
+ // This must be called after `finish()`.
+ $buf = $builder->dataBuffer(); // Of type `Google\FlatBuffers\ByteBuffer`
+ // The data in this ByteBuffer does NOT start at 0, but at
+ // buf->getPosition().
+ // The end of the data is marked by buf->capacity(), so the size is
+ // buf->capacity() - buf->getPosition().
```
=== "Python"
```py
+ # This must be called after `Finish()`.
+ buf = builder.Output() // Of type `bytearray`.
```
=== "Rust"
```rust
+ // This must be called after `finish()`.
+ // `finished_data` returns a byte slice.
+ let buf = builder.finished_data(); // Of type `&[u8]`
```
=== "Swift"
```swift
+ // This must be called after `finish()`.
+ // `sizedByteArray` returns the finished buf of type [UInt8].
+ let buf = builder.sizedByteArray
+ // or you can use to get an object of type Data
+ let bufData = ByteBuffer(data: builder.data)
```
=== "TypeScript"
```ts
+ // This must be called after `finish()`.
+ let buf = builder.asUint8Array(); // Of type `Uint8Array`.
```
@@ -1372,6 +2061,12 @@ functions to get the root object given the buffer.
=== "C"
```c
+ // Note that we use the `table_t` suffix when reading a table object
+ // as opposed to the `ref_t` suffix used during the construction of
+ // the buffer.
+ ns(Monster_table_t) monster = ns(Monster_as_root(buffer));
+
+ // Note: root object pointers are NOT the same as the `buffer` pointer.
```
=== "C#"
@@ -1386,61 +2081,135 @@ functions to get the root object given the buffer.
=== "Dart"
```dart
+ List data = ... // the data, e.g. from file or network
+ // A generated factory constructor that will read the data.
+ myGame.Monster monster = new myGame.Monster(data);
```
=== "Go"
```go
+ var buf []byte = /* the data you just read */
+
+ // Get an accessor to the root object inside the buffer.
+ monster := sample.GetRootAsMonster(buf, 0)
+
+ // Note: We use `0` for the offset here, which is typical for most buffers
+ // you would read. If you wanted to read from `builder.Bytes` directly, you
+ // would need to pass in the offset of `builder.Head()`, as the builder
+ // constructs the buffer backwards, so may not start at offset 0.
```
=== "Java"
```java
+ byte[] bytes = /* the data you just read */
+ java.nio.ByteBuffer buf = java.nio.ByteBuffer.wrap(bytes);
+
+ // Get an accessor to the root object inside the buffer.
+ Monster monster = Monster.getRootAsMonster(buf);
```
=== "JavaScript"
```javascript
+ // the data you just read, as a `Uint8Array`
+ // Note that the example here uses `readFileSync` from the built-in `fs`
+ // module, but other methods for accessing the file contents will also work.
+ var bytes = new Uint8Array(readFileSync('./monsterdata.bin'));
+
+ var buf = new flatbuffers.ByteBuffer(bytes);
+
+ // Get an accessor to the root object inside the buffer.
+ var monster = MyGame.Sample.Monster.getRootAsMonster(buf);
```
=== "Kotlin"
```kotlin
+ val bytes = /* the data you just read */
+ val buf = java.nio.ByteBuffer.wrap(bytes)
+
+ // Get an accessor to the root object inside the buffer.
+ Monster monster = Monster.getRootAsMonster(buf)
```
=== "Lobster"
```lobster
+ buf = /* the data you just read, in a string */
+
+ // Get an accessor to the root object inside the buffer.
+ let monster = MyGame_Sample_GetRootAsMonster(buf)
```
=== "Lua"
```lua
+ local bufAsString = -- The data you just read in
+
+ -- Convert the string representation into binary array Lua structure
+ local buf = flatbuffers.binaryArray.New(bufAsString)
+
+ -- Get an accessor to the root object insert the buffer
+ local mon = monster.GetRootAsMonster(buf, 0)
```
=== "PHP"
```php
+ $bytes = /* the data you just read, in a string */
+ $buf = Google\FlatBuffers\ByteBuffer::wrap($bytes);
+
+ // Get an accessor to the root object inside the buffer.
+ $monster = \MyGame\Sample\Monster::GetRootAsMonster($buf);
```
=== "Python"
```py
+ buf = /* the data you just read, in an object of type "bytearray" */
+
+ # Get an accessor to the root object inside the buffer.
+ monster = MyGame.Sample.Monster.Monster.GetRootAs(buf, 0)
+
+ # Note: We use `0` for the offset here, which is typical for most buffers
+ # you would read. If you wanted to read from the `builder.Bytes` directly,
+ # you would need to pass in the offset of `builder.Head()`, as the builder
+ # constructs the buffer backwards, so may not start at offset 0.
```
=== "Rust"
```rust
+ let buf = /* the data you just read, in a &[u8] */
+
+ // Get an accessor to the root object inside the buffer.
+ let monster = root_as_monster(buf).unwrap();
```
=== "Swift"
```swift
+ // create a ByteBuffer(:) from an [UInt8] or Data()
+ var buf = // Get your data
+ // Get an accessor to the root object inside the buffer.
+ let monster: Monster = try! getCheckedRoot(byteBuffer: &byteBuffer)
+ // let monster: Monster = getRoot(byteBuffer: &byteBuffer)
```
=== "TypeScript"
```ts
+ // the data you just read, as a `Uint8Array`.
+ // Note that the example here uses `readFileSync` from the built-in `fs`
+ // module, but other methods for accessing the file contents will also work.
+ let bytes = new Uint8Array(readFileSync('./monsterdata.bin'));
+
+ let buf = new flatbuffers.ByteBuffer(bytes);
+
+ // Get an accessor to the root object inside the buffer.
+ let monster = MyGame.Sample.Monster.getRootAsMonster(buf);
```
@@ -1468,6 +2237,9 @@ some of the accessors of the `Monster` root table would look like:
=== "C"
```c
+ uint16_t hp = ns(Monster_hp(monster));
+ uint16_t mana = ns(Monster_mana(monster));
+ flatbuffers_string_t name = ns(Monster_name(monster));
```
=== "C#"
@@ -1484,61 +2256,100 @@ some of the accessors of the `Monster` root table would look like:
=== "Dart"
```dart
+ // For Dart, unlike other languages support by FlatBuffers, most values
+ // are available as properties instead of accessor methods.
+ var hp = monster.hp;
+ var mana = monster.mana;
+ var name = monster.name;
```
=== "Go"
```go
+ hp := monster.Hp()
+ mana := monster.Mana()
+ name := string(monster.Name()) // Note: `monster.Name()` returns a byte[].
```
=== "Java"
```java
+ short hp = monster.hp();
+ short mana = monster.mana();
+ String name = monster.name();
```
=== "JavaScript"
```javascript
+ var hp = monster.hp();
+ var mana = monster.mana();
+ var name = monster.name();
```
=== "Kotlin"
```kotlin
+ val hp = monster.hp
+ val mana = monster.mana
+ val name = monster.name
```
=== "Lobster"
```lobster
+ let hp = monster.hp
+ let mana = monster.mana
+ let name = monster.name
```
=== "Lua"
```lua
+ local hp = mon:Hp()
+ local mana = mon:Mana()
+ local name = mon:Name()
```
=== "PHP"
```php
+ $hp = $monster->getHp();
+ $mana = $monster->getMana();
+ $name = monster->getName();
```
=== "Python"
```py
+ hp = monster.Hp()
+ mana = monster.Mana()
+ name = monster.Name()
```
=== "Rust"
```rust
+ // Get and test some scalar types from the FlatBuffer.
+ let hp = monster.hp();
+ let mana = monster.mana();
+ let name = monster.name();
```
=== "Swift"
```swift
+ let hp = monster.hp
+ let mana = monster.mana
+ let name = monster.name // returns an optional string
```
=== "TypeScript"
```ts
+ let hp = monster.hp();
+ let mana = monster.mana();
+ let name = monster.name();
```
@@ -1567,6 +2378,10 @@ For example, accessing the `pos` `struct`, which is type `Vec3` you would do:
=== "C"
```c
+ ns(Vec3_struct_t) pos = ns(Monster_pos(monster));
+ float x = ns(Vec3_x(pos));
+ float y = ns(Vec3_y(pos));
+ float z = ns(Vec3_z(pos));
```
=== "C#"
@@ -1581,61 +2396,115 @@ For example, accessing the `pos` `struct`, which is type `Vec3` you would do:
=== "Dart"
```dart
+ myGame.Vec3 pos = monster.pos;
+ double x = pos.x;
+ double y = pos.y;
+ double z = pos.z;
```
=== "Go"
```go
+ pos := monster.Pos(nil)
+ x := pos.X()
+ y := pos.Y()
+ z := pos.Z()
+
+ // Note: Whenever you access a new object, like in `Pos()`, a new temporary
+ // accessor object gets created. If your code is very performance sensitive,
+ // you can pass in a pointer to an existing `Vec3` instead of `nil`. This
+ // allows you to reuse it across many calls to reduce the amount of object
+ // allocation/garbage collection.
```
=== "Java"
```java
+ Vec3 pos = monster.pos();
+ float x = pos.x();
+ float y = pos.y();
+ float z = pos.z();
```
=== "JavaScript"
```javascript
+ var pos = monster.pos();
+ var x = pos.x();
+ var y = pos.y();
+ var z = pos.z();
```
=== "Kotlin"
```kotlin
+ val pos = monster.pos!!
+ val x = pos.x
+ val y = pos.y
+ val z = pos.z
```
=== "Lobster"
```lobster
+ let pos = monster.pos
+ let x = pos.x
+ let y = pos.y
+ let z = pos.z
```
=== "Lua"
```lua
+ local pos = mon:Pos()
+ local x = pos:X()
+ local y = pos:Y()
+ local z = pos:Z()
```
=== "PHP"
```php
+ $pos = $monster->getPos();
+ $x = $pos->getX();
+ $y = $pos->getY();
+ $z = $pos->getZ();
```
=== "Python"
```py
+ pos = monster.Pos()
+ x = pos.X()
+ y = pos.Y()
+ z = pos.Z()
```
=== "Rust"
```rust
+ let pos = monster.pos().unwrap();
+ let x = pos.x();
+ let y = pos.y();
+ let z = pos.z();
```
=== "Swift"
```swift
+ let pos = monster.pos
+ let x = pos.x
+ let y = pos.y
+ let z = pos.z
```
=== "TypeScript"
```ts
+ let pos = monster.pos();
+ let x = pos.x();
+ let y = pos.y();
+ let z = pos.z();
```
@@ -1657,6 +2526,10 @@ You can also iterate over the length of the vector.
=== "C"
```c
+ // If `inv` hasn't been set, it will be null. It is valid get
+ // the length of null which will be 0, useful for iteration.
+ flatbuffers_uint8_vec_t inv = ns(Monster_inventory(monster));
+ size_t inv_len = flatbuffers_uint8_vec_len(inv);
```
=== "C#"
@@ -1669,61 +2542,96 @@ You can also iterate over the length of the vector.
=== "Dart"
```dart
+ int invLength = monster.inventory.length;
+ var thirdItem = monster.inventory[2];
```
=== "Go"
```go
+ invLength := monster.InventoryLength()
+ thirdItem := monster.Inventory(2)
```
=== "Java"
```java
+ int invLength = monster.inventoryLength();
+ byte thirdItem = monster.inventory(2);
```
=== "JavaScript"
```javascript
+ var invLength = monster.inventoryLength();
+ var thirdItem = monster.inventory(2);
```
=== "Kotlin"
```kotlin
+ val invLength = monster.inventoryLength
+ val thirdItem = monster.inventory(2)!!
```
=== "Lobster"
```lobster
+ let inv_len = monster.inventory_length
+ let third_item = monster.inventory(2)
```
=== "Lua"
```lua
+ local invLength = mon:InventoryLength()
+ local thirdItem = mon:Inventory(3) -- Lua is 1-based
```
=== "PHP"
```php
+ $inv_len = $monster->getInventoryLength();
+ $third_item = $monster->getInventory(2);
```
=== "Python"
```py
+ inv_len = monster.InventoryLength()
+ third_item = monster.Inventory(2)
```
=== "Rust"
```rust
+ // Get and test an element from the `inventory` FlatBuffer's `vector`.
+ let inv = monster.inventory().unwrap();
+
+ // Note that this vector is returned as a slice, because direct access for
+ // this type, a `u8` vector, is safe on all platforms:
+ let third_item = inv[2];
```
=== "Swift"
```swift
+ // Get a the count of objects in the vector
+ let count = monster.inventoryCount
+
+ // get item at index 4
+ let object = monster.inventory(at: 4)
+
+ // or you can fetch the entire array
+ let inv = monster.inventory
+ // inv[4] should equal object
```
=== "TypeScript"
```ts
+ let invLength = monster.inventoryLength();
+ let thirdItem = monster.inventory(2);
```
@@ -1743,6 +2651,13 @@ you need to handle the result as a FlatBuffer table. Here we iterate over the
=== "C"
```c
+ ns(Weapon_vec_t) weapons = ns(Monster_weapons(monster));
+ size_t weapons_len = ns(Weapon_vec_len(weapons));
+ // We can use `const char *` instead of `flatbuffers_string_t`.
+ const char *second_weapon_name =
+ ns(Weapon_name(ns(Weapon_vec_at(weapons, 1))));
+ uint16_t second_weapon_damage =
+ ns(Weapon_damage(ns(Weapon_vec_at(weapons, 1))));
```
=== "C#"
@@ -1756,61 +2671,109 @@ you need to handle the result as a FlatBuffer table. Here we iterate over the
=== "Dart"
```dart
+ int weaponsLength = monster.weapons.length;
+ var secondWeaponName = monster.weapons[1].name;
+ var secondWeaponDamage = monster.Weapons[1].damage;
```
=== "Go"
```go
+ weaponLength := monster.WeaponsLength()
+ // We need a `sample.Weapon` to pass into `monster.Weapons()`
+ // to capture the output of the function.k
+ weapon := new(sample.Weapon)
+ if monster.Weapons(weapon, 1) {
+ secondWeaponName := weapon.Name()
+ secondWeaponDamage := weapon.Damage()
+ }
```
=== "Java"
```java
+ int weaponsLength = monster.weaponsLength();
+ String secondWeaponName = monster.weapons(1).name();
+ short secondWeaponDamage = monster.weapons(1).damage();
```
=== "JavaScript"
```javascript
+ var weaponsLength = monster.weaponsLength();
+ var secondWeaponName = monster.weapons(1).name();
+ var secondWeaponDamage = monster.weapons(1).damage();
```
=== "Kotlin"
```kotlin
+ val weaponsLength = monster.weaponsLength
+ val secondWeaponName = monster.weapons(1)!!.name
+ val secondWeaponDamage = monster.weapons(1)!!.damage
```
=== "Lobster"
```lobster
+ let weapons_length = monster.weapons_length
+ let second_weapon_name = monster.weapons(1).name
+ let second_weapon_damage = monster.weapons(1).damage
```
=== "Lua"
```lua
+ local weaponsLength = mon:WeaponsLength()
+ local secondWeaponName = mon:Weapon(2):Name()
+ local secondWeaponDamage = mon:Weapon(2):Damage()
```
=== "PHP"
```php
+ $weapons_len = $monster->getWeaponsLength();
+ $second_weapon_name = $monster->getWeapons(1)->getName();
+ $second_weapon_damage = $monster->getWeapons(1)->getDamage();
```
=== "Python"
```py
+ weapons_length = monster.WeaponsLength()
+ second_weapon_name = monster.Weapons(1).Name()
+ second_weapon_damage = monster.Weapons(1).Damage()
```
=== "Rust"
```rust
+ // Get and test the `weapons` FlatBuffers's `vector`.
+ let weps = monster.weapons().unwrap();
+ let weps_len = weps.len();
+
+ let wep2 = weps.get(1);
+ let second_weapon_name = wep2.name();
+ let second_weapon_damage = wep2.damage();
```
=== "Swift"
```swift
+ // Get the count of weapon objects
+ let wepsCount = monster.weaponsCount
+
+ let weapon2 = monster.weapons(at: 1)
+ let weaponName = weapon2.name
+ let weaponDmg = weapon2.damage
```
=== "TypeScript"
```ts
+ let weaponsLength = monster.weaponsLength();
+ let secondWeaponName = monster.weapons(1).name();
+ let secondWeaponDamage = monster.weapons(1).damage();
```
@@ -1839,6 +2802,15 @@ only stores a FlatBuffer `table`).
=== "C"
```c
+ // Access union type field.
+ if (ns(Monster_equipped_type(monster)) == ns(Equipment_Weapon)) {
+ // Cast to appropriate type:
+ // C allows for silent void pointer assignment, so we need no
+ // explicit cast.
+ ns(Weapon_table_t) weapon = ns(Monster_equipped(monster));
+ const char *weapon_name = ns(Weapon_name(weapon)); // "Axe"
+ uint16_t weapon_damage = ns(Weapon_damage(weapon)); // 5
+ }
```
=== "C#"
@@ -1857,59 +2829,173 @@ only stores a FlatBuffer `table`).
=== "Dart"
```dart
+ var unionType = monster.equippedType.value;
+
+ if (unionType == myGame.EquipmentTypeId.Weapon.value) {
+ myGame.Weapon weapon = mon.equipped as myGame.Weapon;
+
+ var weaponName = weapon.name; // "Axe"
+ var weaponDamage = weapon.damage; // 5
+ }
```
=== "Go"
```go
+ // We need a `flatbuffers.Table` to capture the output of the
+ // `monster.Equipped()` function.
+ unionTable := new(flatbuffers.Table)
+
+ if monster.Equipped(unionTable) {
+ unionType := monster.EquippedType()
+
+ if unionType == sample.EquipmentWeapon {
+ // Create a `sample.Weapon` object that can be initialized with the
+ // contents of the `flatbuffers.Table` (`unionTable`), which was
+ // populated by `monster.Equipped()`.
+ unionWeapon = new(sample.Weapon)
+ unionWeapon.Init(unionTable.Bytes, unionTable.Pos)
+
+ weaponName = unionWeapon.Name()
+ weaponDamage = unionWeapon.Damage()
+ }
+ }
```
=== "Java"
```java
+ int unionType = monster.EquippedType();
+
+ if (unionType == Equipment.Weapon) {
+ // Requires an explicit cast to `Weapon`.
+ Weapon weapon = (Weapon)monster.equipped(new Weapon());
+
+ String weaponName = weapon.name(); // "Axe"
+ short weaponDamage = weapon.damage(); // 5
+ }
```
=== "JavaScript"
```javascript
+ var unionType = monster.equippedType();
+
+ if (unionType == MyGame.Sample.Equipment.Weapon) {
+ // 'Axe'
+ var weaponName = monster.equipped(new MyGame.Sample.Weapon()).name();
+ // 5
+ var weaponDamage =
+ monster.equipped(new MyGame.Sample.Weapon()).damage();
+ }
```
=== "Kotlin"
```kotlin
+ val unionType = monster.EquippedType
+
+ if (unionType == Equipment.Weapon) {
+ // Requires an explicit cast to `Weapon`.
+ val weapon = monster.equipped(Weapon()) as Weapon
+
+ val weaponName = weapon.name // "Axe"
+ val weaponDamage = weapon.damage // 5
+ }
```
=== "Lobster"
```lobster
+ union_type = monster.equipped_type
+
+ if union_type == MyGame_Sample_Equipment_Weapon:
+ // `monster.equipped_as_Weapon` returns a FlatBuffer handle much like
+ // normal table fields, but this is only valid to call if we already
+ // know it is the correct type.
+ let union_weapon = monster.equipped_as_Weapon
+
+ let weapon_name = union_weapon.name // "Axe"
+ let weapon_damage = union_weapon.damage // 5
```
=== "Lua"
```lua
+ local unionType = mon:EquippedType()
+
+ if unionType == equipment.Weapon then
+ local unionWeapon = weapon.New()
+ unionWeapon:Init(mon:Equipped().bytes, mon:Equipped().pos)
+
+ local weaponName = unionWeapon:Name() -- 'Axe'
+ local weaponDamage = unionWeapon:Damage() -- 5
+ end
```
=== "PHP"
```php
+ $union_type = $monster->getEquippedType();
+
+ if ($union_type == \MyGame\Sample\Equipment::Weapon) {
+ // "Axe"
+ $weapon_name =
+ $monster->getEquipped(new \MyGame\Sample\Weapon())->getName();
+ // 5
+ $weapon_damage =
+ $monster->getEquipped(new \MyGame\Sample\Weapon())->getDamage();
+ }
```
=== "Python"
```py
+ union_type = monster.EquippedType()
+
+ if union_type == MyGame.Sample.Equipment.Equipment().Weapon:
+ # `monster.Equipped()` returns a `flatbuffers.Table`, which can be used
+ # to initialize a `MyGame.Sample.Weapon.Weapon()`.
+ union_weapon = MyGame.Sample.Weapon.Weapon()
+ union_weapon.Init(monster.Equipped().Bytes, monster.Equipped().Pos)
+
+ weapon_name = union_weapon.Name() // 'Axe'
+ weapon_damage = union_weapon.Damage() // 5
```
=== "Rust"
```rust
+ // Get and test the `Equipment` union (`equipped` field).
+ // `equipped_as_weapon` returns a FlatBuffer handle much like normal table
+ // fields, but this will return `None` if the union is not actually of that
+ // type.
+ if monster.equipped_type() == Equipment::Weapon {
+ let equipped = monster.equipped_as_weapon().unwrap();
+ let weapon_name = equipped.name();
+ let weapon_damage = equipped.damage();
```
=== "Swift"
```swift
+ // Get and check if the monster has an equipped item
+ if monster.equippedType == .weapon {
+ let _weapon = monster.equipped(type: Weapon.self)
+ let name = _weapon.name // should return "Axe"
+ let dmg = _weapon.damage // should return 5
+ }
```
=== "TypeScript"
```ts
+ let unionType = monster.equippedType();
+
+ if (unionType == MyGame.Sample.Equipment.Weapon) {
+ // 'Axe'
+ let weaponName = monster.equipped(new MyGame.Sample.Weapon()).name();
+ // 5
+ let weaponDamage = monster.equipped(new MyGame.Sample.Weapon()).damage();
+ }
```