1Tutorial {#flatbuffers_guide_tutorial} 2======== 3 4## Overview 5 6This tutorial provides a basic example of how to work with 7[FlatBuffers](@ref flatbuffers_overview). We will step through a simple example 8application, which shows you how to: 9 10 - Write a FlatBuffer `schema` file. 11 - Use the `flatc` FlatBuffer compiler. 12 - Parse [JSON](http://json.org) files that conform to a schema into 13 FlatBuffer binary files. 14 - Use the generated files in many of the supported languages (such as C++, 15 Java, and more.) 16 17During this example, imagine that you are creating a game where the main 18character, the hero of the story, needs to slay some `orc`s. We will walk 19through each step necessary to create this monster type using FlatBuffers. 20 21Please select your desired language for our quest: 22\htmlonly 23<form> 24 <input type="radio" name="language" value="cpp" checked="checked">C++</input> 25 <input type="radio" name="language" value="java">Java</input> 26 <input type="radio" name="language" value="kotlin">Kotlin</input> 27 <input type="radio" name="language" value="csharp">C#</input> 28 <input type="radio" name="language" value="go">Go</input> 29 <input type="radio" name="language" value="python">Python</input> 30 <input type="radio" name="language" value="javascript">JavaScript</input> 31 <input type="radio" name="language" value="typescript">TypeScript</input> 32 <input type="radio" name="language" value="php">PHP</input> 33 <input type="radio" name="language" value="c">C</input> 34 <input type="radio" name="language" value="dart">Dart</input> 35 <input type="radio" name="language" value="lua">Lua</input> 36 <input type="radio" name="language" value="lobster">Lobster</input> 37 <input type="radio" name="language" value="rust">Rust</input> 38 <input type="radio" name="language" value="swift">Swift</input> 39</form> 40\endhtmlonly 41 42\htmlonly 43<script> 44 /** 45 * Check if an HTML `class` attribute is in the language-specific format. 46 * @param {string} languageClass An HTML `class` attribute in the format 47 * 'language-{lang}', where {lang} is a programming language (e.g. 'cpp', 48 * 'java', 'go', etc.). 49 * @return {boolean} Returns `true` if `languageClass` was in the valid 50 * format, prefixed with 'language-'. Otherwise, it returns false. 51 */ 52 function isProgrammingLanguageClassName(languageClass) { 53 if (languageClass && languageClass.substring(0, 9) == 'language-' && 54 languageClass.length > 8) { 55 return true; 56 } else { 57 return false; 58 } 59 } 60 61 /** 62 * Given a language-specific HTML `class` attribute, extract the language. 63 * @param {string} languageClass The string name of an HTML `class` attribute, 64 * in the format `language-{lang}`, where {lang} is a programming language 65 * (e.g. 'cpp', 'java', 'go', etc.). 66 * @return {string} Returns a string containing only the {lang} portion of 67 * the class name. If the input was invalid, then it returns `null`. 68 */ 69 function extractProgrammingLanguageFromLanguageClass(languageClass) { 70 if (isProgrammingLanguageClassName(languageClass)) { 71 return languageClass.substring(9); 72 } else { 73 return null; 74 } 75 } 76 77 /** 78 * Hide every code snippet, except for the language that is selected. 79 */ 80 function displayChosenLanguage() { 81 var selection = $('input:checked').val(); 82 83 var htmlElements = document.getElementsByTagName('*'); 84 for (var i = 0; i < htmlElements.length; i++) { 85 if (isProgrammingLanguageClassName(htmlElements[i].className)) { 86 if (extractProgrammingLanguageFromLanguageClass( 87 htmlElements[i].className).toLowerCase() != selection) { 88 htmlElements[i].style.display = 'none'; 89 } else { 90 htmlElements[i].style.display = 'initial'; 91 } 92 } 93 } 94 } 95 96 $( document ).ready(displayChosenLanguage); 97 98 $('input[type=radio]').on("click", displayChosenLanguage); 99</script> 100\endhtmlonly 101 102## Where to Find the Example Code 103 104Samples demonstating the concepts in this example are located in the source code 105package, under the `samples` directory. You can browse the samples on GitHub 106[here](https://github.com/google/flatbuffers/tree/master/samples). 107 108<div class="language-c"> 109*Note: The above does not apply to C, instead [look here](https://github.com/dvidelabs/flatcc/tree/master/samples).* 110</div> 111 112For your chosen language, please cross-reference with: 113 114<div class="language-cpp"> 115[sample_binary.cpp](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.cpp) 116</div> 117<div class="language-java"> 118[SampleBinary.java](https://github.com/google/flatbuffers/blob/master/samples/SampleBinary.java) 119</div> 120<div class="language-kotlin"> 121[SampleBinary.kt](https://github.com/google/flatbuffers/blob/master/samples/SampleBinary.kt) 122</div> 123<div class="language-csharp"> 124[SampleBinary.cs](https://github.com/google/flatbuffers/blob/master/samples/SampleBinary.cs) 125</div> 126<div class="language-go"> 127[sample_binary.go](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.go) 128</div> 129<div class="language-python"> 130[sample_binary.py](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.py) 131</div> 132<div class="language-javascript"> 133No sample binary is provided, since JS needs to be transpiled from TypeScript. Please see TypeScript support. 134</div> 135<div class="language-typescript"> 136<em>none yet</em> 137</div> 138<div class="language-php"> 139[SampleBinary.php](https://github.com/google/flatbuffers/blob/master/samples/SampleBinary.php) 140</div> 141<div class="language-c"> 142[monster.c](https://github.com/dvidelabs/flatcc/blob/master/samples/monster/monster.c) 143</div> 144<div class="language-dart"> 145[example.dart](https://github.com/google/flatbuffers/blob/master/dart/example/example.dart) 146</div> 147<div class="language-lua"> 148[sample_binary.lua](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.lua) 149</div> 150<div class="language-lobster"> 151[sample_binary.lobster](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.lobster) 152</div> 153<div class="language-rust"> 154[sample_binary.rs](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.rs) 155</div> 156<div class="language-swift"> 157[sample_binary.swift](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.swift) 158</div> 159 160 161## Writing the Monsters' FlatBuffer Schema 162 163To start working with FlatBuffers, you first need to create a `schema` file, 164which defines the format for each data structure you wish to serialize. Here is 165the `schema` that defines the template for our monsters: 166 167~~~ 168 // Example IDL file for our monster's schema. 169 170 namespace MyGame.Sample; 171 172 enum Color:byte { Red = 0, Green, Blue = 2 } 173 174 union Equipment { Weapon } // Optionally add more tables. 175 176 struct Vec3 { 177 x:float; 178 y:float; 179 z:float; 180 } 181 182 table Monster { 183 pos:Vec3; // Struct. 184 mana:short = 150; 185 hp:short = 100; 186 name:string; 187 friendly:bool = false (deprecated); 188 inventory:[ubyte]; // Vector of scalars. 189 color:Color = Blue; // Enum. 190 weapons:[Weapon]; // Vector of tables. 191 equipped:Equipment; // Union. 192 path:[Vec3]; // Vector of structs. 193 } 194 195 table Weapon { 196 name:string; 197 damage:short; 198 } 199 200 root_type Monster; 201~~~ 202 203As you can see, the syntax for the `schema` 204[Interface Definition Language (IDL)](https://en.wikipedia.org/wiki/Interface_description_language) 205is similar to those of the C family of languages, and other IDL languages. Let's 206examine each part of this `schema` to determine what it does. 207 208The `schema` starts with a `namespace` declaration. This determines the 209corresponding package/namespace for the generated code. In our example, we have 210the `Sample` namespace inside of the `MyGame` namespace. 211 212Next, we have an `enum` definition. In this example, we have an `enum` of type 213`byte`, named `Color`. We have three values in this `enum`: `Red`, `Green`, and 214`Blue`. We specify `Red = 0` and `Blue = 2`, but we do not specify an explicit 215value for `Green`. Since the behavior of an `enum` is to increment if 216unspecified, `Green` will receive the implicit value of `1`. 217 218Following the `enum` is a `union`. The `union` in this example is not very 219useful, as it only contains the one `table` (named `Weapon`). If we had created 220multiple tables that we would want the `union` to be able to reference, we 221could add more elements to the `union Equipment`. 222 223After the `union` comes a `struct Vec3`, which represents a floating point 224vector with `3` dimensions. We use a `struct` here, over a `table`, because 225`struct`s are ideal for data structures that will not change, since they use 226less memory and have faster lookup. 227 228The `Monster` table is the main object in our FlatBuffer. This will be used as 229the template to store our `orc` monster. We specify some default values for 230fields, such as `mana:short = 150`. If unspecified, scalar fields (like `int`, 231`uint`, or `float`) will be given a default of `0` while strings and tables will 232be given a default of `null`. Another thing to note is the line `friendly:bool = 233false (deprecated);`. Since you cannot delete fields from a `table` (to support 234backwards compatibility), you can set fields as `deprecated`, which will prevent 235the generation of accessors for this field in the generated code. Be careful 236when using `deprecated`, however, as it may break legacy code that used this 237accessor. 238 239The `Weapon` table is a sub-table used within our FlatBuffer. It is 240used twice: once within the `Monster` table and once within the `Equipment` 241union. For our `Monster`, it is used to populate a `vector of tables` via the 242`weapons` field within our `Monster`. It is also the only table referenced by 243the `Equipment` union. 244 245The last part of the `schema` is the `root_type`. The root type declares what 246will be the root table for the serialized data. In our case, the root type is 247our `Monster` table. 248 249The scalar types can also use alias type names such as `int16` instead 250of `short` and `float32` instead of `float`. Thus we could also write 251the `Weapon` table as: 252 253~~~ 254 table Weapon { 255 name:string; 256 damage:int16; 257 } 258~~~ 259 260#### More Information About Schemas 261 262You can find a complete guide to writing `schema` files in the 263[Writing a schema](@ref flatbuffers_guide_writing_schema) section of the 264Programmer's Guide. You can also view the formal 265[Grammar of the schema language](@ref flatbuffers_grammar). 266 267## Compiling the Monsters' Schema 268 269After you have written the FlatBuffers schema, the next step is to compile it. 270 271If you have not already done so, please follow 272[these instructions](@ref flatbuffers_guide_building) to build `flatc`, the 273FlatBuffer compiler. 274 275Once `flatc` is built successfully, compile the schema for your language: 276 277<div class="language-c"> 278*Note: If you're working in C, you need to use the separate project [FlatCC](https://github.com/dvidelabs/flatcc) which contains a schema compiler and runtime library in C for C.* 279<br> 280See [flatcc build instructions](https://github.com/dvidelabs/flatcc#building). 281<br> 282Please be aware of the difference between `flatc` and `flatcc` tools. 283<br> 284</div> 285<div class="language-cpp"> 286~~~{.sh} 287 cd flatbuffers/samples 288 ./../flatc --cpp monster.fbs 289~~~ 290</div> 291<div class="language-java"> 292~~~{.sh} 293 cd flatbuffers/samples 294 ./../flatc --java monster.fbs 295~~~ 296</div> 297<div class="language-kotlin"> 298~~~{.sh} 299 cd flatbuffers/samples 300 ./../flatc --kotlin monster.fbs 301~~~ 302</div> 303<div class="language-csharp"> 304~~~{.sh} 305 cd flatbuffers/samples 306 ./../flatc --csharp monster.fbs 307~~~ 308</div> 309<div class="language-go"> 310~~~{.sh} 311 cd flatbuffers/samples 312 ./../flatc --go monster.fbs 313~~~ 314</div> 315<div class="language-python"> 316~~~{.sh} 317 cd flatbuffers/samples 318 ./../flatc --python monster.fbs 319~~~ 320</div> 321<div class="language-javascript"> 322~~~{.sh} 323 cd flatbuffers/samples 324 ./../flatc --ts-flat-files --ts monster.fbs 325 # produces ts/js modules and js bundle monster_generated.js 326~~~ 327</div> 328<div class="language-typescript"> 329~~~{.sh} 330 cd flatbuffers/samples 331 ./../flatc --ts monster.fbs 332~~~ 333</div> 334<div class="language-php"> 335~~~{.sh} 336 cd flatbuffers/sample 337 ./../flatc --php monster.fbs 338~~~ 339</div> 340<div class="language-c"> 341~~~{.sh} 342 cd flatcc 343 mkdir -p build/tmp/samples/monster 344 bin/flatcc -a -o build/tmp/samples/monster samples/monster/monster.fbs 345 # or just 346 flatcc/samples/monster/build.sh 347~~~ 348</div> 349<div class="language-dart"> 350~~~{.sh} 351 cd flatbuffers/samples 352 ./../flatc --dart monster.fbs 353~~~ 354</div> 355<div class="language-lua"> 356~~~{.sh} 357 cd flatbuffers/samples 358 ./../flatc --lua monster.fbs 359~~~ 360</div> 361<div class="language-lobster"> 362~~~{.sh} 363 cd flatbuffers/samples 364 ./../flatc --lobster monster.fbs 365~~~ 366</div> 367<div class="language-rust"> 368~~~{.sh} 369 cd flatbuffers/samples 370 ./../flatc --rust monster.fbs 371~~~ 372</div> 373<div class="language-swift"> 374~~~{.sh} 375 cd flatbuffers/samples 376 ./../flatc --swift monster.fbs 377~~~ 378</div> 379 380For a more complete guide to using the `flatc` compiler, please read the 381[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler) 382section of the Programmer's Guide. 383 384## Reading and Writing Monster FlatBuffers 385 386Now that we have compiled the schema for our programming language, we can 387start creating some monsters and serializing/deserializing them from 388FlatBuffers. 389 390#### Creating and Writing Orc FlatBuffers 391 392The first step is to import/include the library, generated files, etc. 393 394<div class="language-cpp"> 395~~~{.cpp} 396 #include "monster_generated.h" // This was generated by `flatc`. 397 398 using namespace MyGame::Sample; // Specified in the schema. 399~~~ 400</div> 401<div class="language-java"> 402~~~{.java} 403 import MyGame.Sample.*; //The `flatc` generated files. (Monster, Vec3, etc.) 404 405 import com.google.flatbuffers.FlatBufferBuilder; 406~~~ 407</div> 408<div class="language-kotlin"> 409~~~{.kotlin} 410 import MyGame.Sample.* //The `flatc` generated files. (Monster, Vec3, etc.) 411 412 import com.google.flatbuffers.FlatBufferBuilder 413~~~ 414</div> 415<div class="language-csharp"> 416~~~{.cs} 417 using Google.FlatBuffers; 418 using MyGame.Sample; // The `flatc` generated files. (Monster, Vec3, etc.) 419~~~ 420</div> 421<div class="language-go"> 422~~~{.go} 423 import ( 424 flatbuffers "github.com/google/flatbuffers/go" 425 sample "MyGame/Sample" 426 ) 427~~~ 428</div> 429<div class="language-python"> 430~~~{.py} 431 import flatbuffers 432 433 # Generated by `flatc`. 434 import MyGame.Sample.Color 435 import MyGame.Sample.Equipment 436 import MyGame.Sample.Monster 437 import MyGame.Sample.Vec3 438 import MyGame.Sample.Weapon 439~~~ 440</div> 441<div class="language-javascript"> 442~~~{.js} 443 // The following code is an example - use your desired module flavor by transpiling from TS. 444 var flatbuffers = require('/js/flatbuffers').flatbuffers; 445 var MyGame = require('./monster_generated').MyGame; // Generated by `flatc`. 446 447 //--------------------------------------------------------------------------// 448 449 // The following code is for browser-based HTML/JavaScript. Use the above code 450 // for JavaScript module loaders (e.g. Node.js). 451 <script src="../js/flatbuffers.js"></script> 452 <script src="monster_generated.js"></script> // Generated by `flatc`. 453~~~ 454</div> 455<div class="language-typescript"> 456~~~{.ts} 457 // note: import flatbuffers with your desired import method 458 459 import { MyGame } from './monster_generated'; 460~~~ 461</div> 462<div class="language-php"> 463~~~{.php} 464 // It is recommended that your use PSR autoload when using FlatBuffers in PHP. 465 // Here is an example from `SampleBinary.php`: 466 function __autoload($class_name) { 467 // The last segment of the class name matches the file name. 468 $class = substr($class_name, strrpos($class_name, "\\") + 1); 469 $root_dir = join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)))); // `flatbuffers` root. 470 471 // Contains the `*.php` files for the FlatBuffers library and the `flatc` generated files. 472 $paths = array(join(DIRECTORY_SEPARATOR, array($root_dir, "php")), 473 join(DIRECTORY_SEPARATOR, array($root_dir, "samples", "MyGame", "Sample"))); 474 foreach ($paths as $path) { 475 $file = join(DIRECTORY_SEPARATOR, array($path, $class . ".php")); 476 if (file_exists($file)) { 477 require($file); 478 break; 479 } 480 } 481 } 482~~~ 483</div> 484<div class="language-c"> 485~~~{.c} 486 #include "monster_builder.h" // Generated by `flatcc`. 487 488 // Convenient namespace macro to manage long namespace prefix. 489 #undef ns 490 #define ns(x) FLATBUFFERS_WRAP_NAMESPACE(MyGame_Sample, x) // Specified in the schema. 491 492 // A helper to simplify creating vectors from C-arrays. 493 #define c_vec_len(V) (sizeof(V)/sizeof((V)[0])) 494~~~ 495</div> 496<div class="language-dart"> 497~~~{.dart} 498 import 'package:flat_buffers/flat_buffers.dart' as fb; 499 500 // Generated by `flatc`. 501 import 'monster_my_game.sample_generated.dart' as myGame; 502~~~ 503</div> 504<div class="language-lua"> 505~~~{.lua} 506 -- require the flatbuffers module 507 local flatbuffers = require("flatbuffers") 508 509 -- require the generated files from `flatc`. 510 local color = require("MyGame.Sample.Color") 511 local equipment = require("MyGame.Sample.Equipment") 512 local monster = require("MyGame.Sample.Monster") 513 local vec3 = require("MyGame.Sample.Vec3") 514 local weapon = require("MyGame.Sample.Weapon") 515~~~ 516</div> 517<div class="language-lobster"> 518~~~{.lobster} 519 import from "../lobster/" // Where to find flatbuffers.lobster 520 import monster_generated 521~~~ 522</div> 523<div class="language-rust"> 524~~~{.rs} 525 // import the flatbuffers runtime library 526 extern crate flatbuffers; 527 528 // import the generated code 529 #[allow(dead_code, unused_imports)] 530 #[path = "./monster_generated.rs"] 531 mod monster_generated; 532 pub use monster_generated::my_game::sample::{root_as_monster, 533 Color, Equipment, 534 Monster, MonsterArgs, 535 Vec3, 536 Weapon, WeaponArgs}; 537~~~ 538</div> 539<div class="language-swift"> 540~~~{.swift} 541 /** 542 // make sure that monster_generated.swift is included in your project 543 */ 544 import Flatbuffers 545 546 // typealiases for convenience 547 typealias Monster = MyGame1_Sample_Monster 548 typealias Weapon = MyGame1_Sample_Weapon 549 typealias Color = MyGame1_Sample_Color 550 typealias Vec3 = MyGame1_Sample_Vec3 551~~~ 552</div> 553 554Now we are ready to start building some buffers. In order to start, we need 555to create an instance of the `FlatBufferBuilder`, which will contain the buffer 556as it grows. You can pass an initial size of the buffer (here 1024 bytes), 557which will grow automatically if needed: 558 559<div class="language-cpp"> 560~~~{.cpp} 561 // Create a `FlatBufferBuilder`, which will be used to create our 562 // monsters' FlatBuffers. 563 flatbuffers::FlatBufferBuilder builder(1024); 564~~~ 565</div> 566<div class="language-java"> 567~~~{.java} 568 // Create a `FlatBufferBuilder`, which will be used to create our 569 // monsters' FlatBuffers. 570 FlatBufferBuilder builder = new FlatBufferBuilder(1024); 571~~~ 572</div> 573<div class="language-kotlin"> 574~~~{.kt} 575 // Create a `FlatBufferBuilder`, which will be used to create our 576 // monsters' FlatBuffers. 577 val builder = FlatBufferBuilder(1024) 578~~~ 579</div> 580<div class="language-csharp"> 581~~~{.cs} 582 // Create a `FlatBufferBuilder`, which will be used to create our 583 // monsters' FlatBuffers. 584 var builder = new FlatBufferBuilder(1024); 585~~~ 586</div> 587<div class="language-go"> 588~~~{.go} 589 // Create a `FlatBufferBuilder`, which will be used to create our 590 // monsters' FlatBuffers. 591 builder := flatbuffers.NewBuilder(1024) 592~~~ 593</div> 594<div class="language-python"> 595~~~{.py} 596 # Create a `FlatBufferBuilder`, which will be used to create our 597 # monsters' FlatBuffers. 598 builder = flatbuffers.Builder(1024) 599~~~ 600</div> 601<div class="language-javascript"> 602~~~{.js} 603 // Create a `flatbuffer.Builder`, which will be used to create our 604 // monsters' FlatBuffers. 605 var builder = new flatbuffers.Builder(1024); 606~~~ 607</div> 608<div class="language-typescript"> 609~~~{.ts} 610 // Create a `flatbuffer.Builder`, which will be used to create our 611 // monsters' FlatBuffers. 612 let builder = new flatbuffers.Builder(1024); 613~~~ 614</div> 615<div class="language-php"> 616~~~{.php} 617 // Create a `FlatBufferBuilder`, which will be used to create our 618 // monsters' FlatBuffers. 619 $builder = new Google\FlatBuffers\FlatbufferBuilder(1024); 620~~~ 621</div> 622<div class="language-c"> 623~~~{.c} 624 flatcc_builder_t builder, *B; 625 B = &builder; 626 // Initialize the builder object. 627 flatcc_builder_init(B); 628~~~ 629</div> 630<div class="language-dart"> 631~~~{.dart} 632 // Create the fb.Builder object that will be used by our generated builders 633 // Note that if you are only planning to immediately get the byte array this builder would create, 634 // you can use the convenience method `toBytes()` on the generated builders. 635 // For example, you could do something like `new myGame.MonsterBuilder(...).toBytes()` 636 var builder = new fb.Builder(initialSize: 1024); 637~~~ 638</div> 639<div class="language-lua"> 640~~~{.lua} 641 -- get access to the builder, providing an array of size 1024 642 local builder = flatbuffers.Builder(1024) 643~~~ 644</div> 645<div class="language-lobster"> 646~~~{.lobster} 647 // get access to the builder 648 let builder = flatbuffers_builder {} 649~~~ 650</div> 651<div class="language-rust"> 652~~~{.rs} 653 // Build up a serialized buffer algorithmically. 654 // Initialize it with a capacity of 1024 bytes. 655 let mut builder = flatbuffers::FlatBufferBuilder::with_capacity(1024); 656~~~ 657</div> 658<div class="language-swift"> 659~~~{.swift} 660 // create a `FlatBufferBuilder`, which will be used to serialize objects 661 let builder = FlatBufferBuilder(initialSize: 1024) 662~~~ 663</div> 664 665After creating the `builder`, we can start serializing our data. Before we make 666our `orc` Monster, let's create some `Weapon`s: a `Sword` and an `Axe`. 667 668<div class="language-cpp"> 669~~~{.cpp} 670 auto weapon_one_name = builder.CreateString("Sword"); 671 short weapon_one_damage = 3; 672 673 auto weapon_two_name = builder.CreateString("Axe"); 674 short weapon_two_damage = 5; 675 676 // Use the `CreateWeapon` shortcut to create Weapons with all the fields set. 677 auto sword = CreateWeapon(builder, weapon_one_name, weapon_one_damage); 678 auto axe = CreateWeapon(builder, weapon_two_name, weapon_two_damage); 679~~~ 680</div> 681<div class="language-java"> 682~~~{.java} 683 int weaponOneName = builder.createString("Sword") 684 short weaponOneDamage = 3; 685 686 int weaponTwoName = builder.createString("Axe"); 687 short weaponTwoDamage = 5; 688 689 // Use the `createWeapon()` helper function to create the weapons, since we set every field. 690 int sword = Weapon.createWeapon(builder, weaponOneName, weaponOneDamage); 691 int axe = Weapon.createWeapon(builder, weaponTwoName, weaponTwoDamage); 692~~~ 693</div> 694<div class="language-kotlin"> 695~~~{.kt} 696 val weaponOneName = builder.createString("Sword") 697 val weaponOneDamage: Short = 3; 698 699 val weaponTwoName = builder.createString("Axe") 700 val weaponTwoDamage: Short = 5; 701 702 // Use the `createWeapon()` helper function to create the weapons, since we set every field. 703 val sword = Weapon.createWeapon(builder, weaponOneName, weaponOneDamage) 704 val axe = Weapon.createWeapon(builder, weaponTwoName, weaponTwoDamage) 705~~~ 706</div> 707<div class="language-csharp"> 708~~~{.cs} 709 var weaponOneName = builder.CreateString("Sword"); 710 var weaponOneDamage = 3; 711 712 var weaponTwoName = builder.CreateString("Axe"); 713 var weaponTwoDamage = 5; 714 715 // Use the `CreateWeapon()` helper function to create the weapons, since we set every field. 716 var sword = Weapon.CreateWeapon(builder, weaponOneName, (short)weaponOneDamage); 717 var axe = Weapon.CreateWeapon(builder, weaponTwoName, (short)weaponTwoDamage); 718~~~ 719</div> 720<div class="language-go"> 721~~~{.go} 722 weaponOne := builder.CreateString("Sword") 723 weaponTwo := builder.CreateString("Axe") 724 725 // Create the first `Weapon` ("Sword"). 726 sample.WeaponStart(builder) 727 sample.WeaponAddName(builder, weaponOne) 728 sample.WeaponAddDamage(builder, 3) 729 sword := sample.WeaponEnd(builder) 730 731 // Create the second `Weapon` ("Axe"). 732 sample.WeaponStart(builder) 733 sample.WeaponAddName(builder, weaponTwo) 734 sample.WeaponAddDamage(builder, 5) 735 axe := sample.WeaponEnd(builder) 736~~~ 737</div> 738<div class="language-python"> 739~~~{.py} 740 weapon_one = builder.CreateString('Sword') 741 weapon_two = builder.CreateString('Axe') 742 743 # Create the first `Weapon` ('Sword'). 744 MyGame.Sample.Weapon.Start(builder) 745 MyGame.Sample.Weapon.AddName(builder, weapon_one) 746 MyGame.Sample.Weapon.AddDamage(builder, 3) 747 sword = MyGame.Sample.Weapon.End(builder) 748 749 # Create the second `Weapon` ('Axe'). 750 MyGame.Sample.Weapon.Start(builder) 751 MyGame.Sample.Weapon.AddName(builder, weapon_two) 752 MyGame.Sample.Weapon.AddDamage(builder, 5) 753 axe = MyGame.Sample.Weapon.End(builder) 754~~~ 755</div> 756<div class="language-javascript"> 757~~~{.js} 758 var weaponOne = builder.createString('Sword'); 759 var weaponTwo = builder.createString('Axe'); 760 761 // Create the first `Weapon` ('Sword'). 762 MyGame.Sample.Weapon.startWeapon(builder); 763 MyGame.Sample.Weapon.addName(builder, weaponOne); 764 MyGame.Sample.Weapon.addDamage(builder, 3); 765 var sword = MyGame.Sample.Weapon.endWeapon(builder); 766 767 // Create the second `Weapon` ('Axe'). 768 MyGame.Sample.Weapon.startWeapon(builder); 769 MyGame.Sample.Weapon.addName(builder, weaponTwo); 770 MyGame.Sample.Weapon.addDamage(builder, 5); 771 var axe = MyGame.Sample.Weapon.endWeapon(builder); 772~~~ 773</div> 774<div class="language-typescript"> 775~~~{.ts} 776 let weaponOne = builder.createString('Sword'); 777 let weaponTwo = builder.createString('Axe'); 778 779 // Create the first `Weapon` ('Sword'). 780 MyGame.Sample.Weapon.startWeapon(builder); 781 MyGame.Sample.Weapon.addName(builder, weaponOne); 782 MyGame.Sample.Weapon.addDamage(builder, 3); 783 let sword = MyGame.Sample.Weapon.endWeapon(builder); 784 785 // Create the second `Weapon` ('Axe'). 786 MyGame.Sample.Weapon.startWeapon(builder); 787 MyGame.Sample.Weapon.addName(builder, weaponTwo); 788 MyGame.Sample.Weapon.addDamage(builder, 5); 789 let axe = MyGame.Sample.Weapon.endWeapon(builder); 790~~~ 791</div> 792<div class="language-php"> 793~~~{.php} 794 // Create the `Weapon`s using the `createWeapon()` helper function. 795 $weapon_one_name = $builder->createString("Sword"); 796 $sword = \MyGame\Sample\Weapon::CreateWeapon($builder, $weapon_one_name, 3); 797 798 $weapon_two_name = $builder->createString("Axe"); 799 $axe = \MyGame\Sample\Weapon::CreateWeapon($builder, $weapon_two_name, 5); 800 801 // Create an array from the two `Weapon`s and pass it to the 802 // `CreateWeaponsVector()` method to create a FlatBuffer vector. 803 $weaps = array($sword, $axe); 804 $weapons = \MyGame\Sample\Monster::CreateWeaponsVector($builder, $weaps); 805~~~ 806</div> 807<div class="language-c"> 808~~~{.c} 809 flatbuffers_string_ref_t weapon_one_name = flatbuffers_string_create_str(B, "Sword"); 810 uint16_t weapon_one_damage = 3; 811 812 flatbuffers_string_ref_t weapon_two_name = flatbuffers_string_create_str(B, "Axe"); 813 uint16_t weapon_two_damage = 5; 814 815 ns(Weapon_ref_t) sword = ns(Weapon_create(B, weapon_one_name, weapon_one_damage)); 816 ns(Weapon_ref_t) axe = ns(Weapon_create(B, weapon_two_name, weapon_two_damage)); 817~~~ 818</div> 819<div class="language-dart"> 820~~~{.dart} 821 // The generated Builder classes work much like in other languages, 822 final int weaponOneName = builder.writeString("Sword"); 823 final int weaponOneDamage = 3; 824 825 final int weaponTwoName = builder.writeString("Axe"); 826 final int weaponTwoDamage = 5; 827 828 final swordBuilder = new myGame.WeaponBuilder(builder) 829 ..begin() 830 ..addNameOffset(weaponOneName) 831 ..addDamage(weaponOneDamage); 832 final int sword = swordBuilder.finish(); 833 834 final axeBuilder = new myGame.WeaponBuilder(builder) 835 ..begin() 836 ..addNameOffset(weaponTwoName) 837 ..addDamage(weaponTwoDamage); 838 final int axe = axeBuilder.finish(); 839 840 841 842 // The generated ObjectBuilder classes offer an easier to use alternative 843 // at the cost of requiring some additional reference allocations. If memory 844 // usage is critical, or if you'll be working with especially large messages 845 // or tables, you should prefer using the generated Builder classes. 846 // The following code would produce an identical buffer as above. 847 final String weaponOneName = "Sword"; 848 final int weaponOneDamage = 3; 849 850 final String weaponTwoName = "Axe"; 851 final int weaponTwoDamage = 5; 852 853 final myGame.WeaponBuilder sword = new myGame.WeaponObjectBuilder( 854 name: weaponOneName, 855 damage: weaponOneDamage, 856 ); 857 858 final myGame.WeaponBuilder axe = new myGame.WeaponObjectBuilder( 859 name: weaponTwoName, 860 damage: weaponTwoDamage, 861 ); 862~~~ 863</div> 864<div class="language-lua"> 865~~~{.lua} 866 local weaponOne = builder:CreateString("Sword") 867 local weaponTwo = builder:CreateString("Axe") 868 869 -- Create the first 'Weapon' 870 weapon.Start(builder) 871 weapon.AddName(builder, weaponOne) 872 weapon.AddDamage(builder, 3) 873 local sword = weapon.End(builder) 874 875 -- Create the second 'Weapon' 876 weapon.Start(builder) 877 weapon.AddName(builder, weaponTwo) 878 weapon.AddDamage(builder, 5) 879 local axe = weapon.End(builder) 880~~~ 881</div> 882<div class="language-lobster"> 883~~~{.lobster} 884 let weapon_names = [ "Sword", "Axe" ] 885 let weapon_damages = [ 3, 5 ] 886 887 let weapon_offsets = map(weapon_names) name, i: 888 let ns = builder.CreateString(name) 889 MyGame_Sample_WeaponBuilder { b } 890 .start() 891 .add_name(ns) 892 .add_damage(weapon_damages[i]) 893 .end() 894~~~ 895</div> 896<div class="language-rust"> 897~~~{.rs} 898 // Serialize some weapons for the Monster: A 'sword' and an 'axe'. 899 let weapon_one_name = builder.create_string("Sword"); 900 let weapon_two_name = builder.create_string("Axe"); 901 902 // Use the `Weapon::create` shortcut to create Weapons with named field 903 // arguments. 904 let sword = Weapon::create(&mut builder, &WeaponArgs{ 905 name: Some(weapon_one_name), 906 damage: 3, 907 }); 908 let axe = Weapon::create(&mut builder, &WeaponArgs{ 909 name: Some(weapon_two_name), 910 damage: 5, 911 }); 912~~~ 913</div> 914<div class="language-swift"> 915~~~{.swift} 916 let weapon1Name = builder.create(string: "Sword") 917 let weapon2Name = builder.create(string: "Axe") 918 919 // start creating the weapon by calling startWeapon 920 let weapon1Start = Weapon.startWeapon(&builder) 921 Weapon.add(name: weapon1Name, &builder) 922 Weapon.add(damage: 3, &builder) 923 // end the object by passing the start point for the weapon 1 924 let sword = Weapon.endWeapon(&builder, start: weapon1Start) 925 926 let weapon2Start = Weapon.startWeapon(&builder) 927 Weapon.add(name: weapon2Name, &builder) 928 Weapon.add(damage: 5, &builder) 929 let axe = Weapon.endWeapon(&builder, start: weapon2Start) 930~~~ 931</div> 932 933Now let's create our monster, the `orc`. For this `orc`, lets make him 934`red` with rage, positioned at `(1.0, 2.0, 3.0)`, and give him 935a large pool of hit points with `300`. We can give him a vector of weapons 936to choose from (our `Sword` and `Axe` from earlier). In this case, we will 937equip him with the `Axe`, since it is the most powerful of the two. Lastly, 938let's fill his inventory with some potential treasures that can be taken once he 939is defeated. 940 941Before we serialize a monster, we need to first serialize any objects that are 942contained therein, i.e. we serialize the data tree using depth-first, pre-order 943traversal. This is generally easy to do on any tree structures. 944 945<div class="language-cpp"> 946~~~{.cpp} 947 // Serialize a name for our monster, called "Orc". 948 auto name = builder.CreateString("Orc"); 949 950 // Create a `vector` representing the inventory of the Orc. Each number 951 // could correspond to an item that can be claimed after he is slain. 952 unsigned char treasure[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 953 auto inventory = builder.CreateVector(treasure, 10); 954~~~ 955</div> 956<div class="language-java"> 957~~~{.java} 958 // Serialize a name for our monster, called "Orc". 959 int name = builder.createString("Orc"); 960 961 // Create a `vector` representing the inventory of the Orc. Each number 962 // could correspond to an item that can be claimed after he is slain. 963 byte[] treasure = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 964 int inv = Monster.createInventoryVector(builder, treasure); 965~~~ 966</div> 967<div class="language-kotlin"> 968~~~{.kt} 969 // Serialize a name for our monster, called "Orc". 970 val name = builder.createString("Orc") 971 972 // Create a `vector` representing the inventory of the Orc. Each number 973 // could correspond to an item that can be claimed after he is slain. 974 val treasure = byteArrayOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) 975 val inv = Monster.createInventoryVector(builder, treasure) 976~~~ 977</div> 978<div class="language-csharp"> 979~~~{.cs} 980 // Serialize a name for our monster, called "Orc". 981 var name = builder.CreateString("Orc"); 982 983 // Create a `vector` representing the inventory of the Orc. Each number 984 // could correspond to an item that can be claimed after he is slain. 985 // Note: Since we prepend the bytes, this loop iterates in reverse order. 986 Monster.StartInventoryVector(builder, 10); 987 for (int i = 9; i >= 0; i--) 988 { 989 builder.AddByte((byte)i); 990 } 991 var inv = builder.EndVector(); 992~~~ 993</div> 994<div class="language-go"> 995~~~{.go} 996 // Serialize a name for our monster, called "Orc". 997 name := builder.CreateString("Orc") 998 999 // Create a `vector` representing the inventory of the Orc. Each number 1000 // could correspond to an item that can be claimed after he is slain. 1001 // Note: Since we prepend the bytes, this loop iterates in reverse. 1002 sample.MonsterStartInventoryVector(builder, 10) 1003 for i := 9; i >= 0; i-- { 1004 builder.PrependByte(byte(i)) 1005 } 1006 inv := builder.EndVector(10) 1007~~~ 1008</div> 1009<div class="language-python"> 1010~~~{.py} 1011 # Serialize a name for our monster, called "Orc". 1012 name = builder.CreateString("Orc") 1013 1014 # Create a `vector` representing the inventory of the Orc. Each number 1015 # could correspond to an item that can be claimed after he is slain. 1016 # Note: Since we prepend the bytes, this loop iterates in reverse. 1017 MyGame.Sample.Monster.StartInventoryVector(builder, 10) 1018 for i in reversed(range(0, 10)): 1019 builder.PrependByte(i) 1020 inv = builder.EndVector() 1021~~~ 1022</div> 1023<div class="language-javascript"> 1024~~~{.js} 1025 // Serialize a name for our monster, called 'Orc'. 1026 var name = builder.createString('Orc'); 1027 1028 // Create a `vector` representing the inventory of the Orc. Each number 1029 // could correspond to an item that can be claimed after he is slain. 1030 var treasure = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; 1031 var inv = MyGame.Sample.Monster.createInventoryVector(builder, treasure); 1032~~~ 1033</div> 1034<div class="language-typescript"> 1035~~~{.ts} 1036 // Serialize a name for our monster, called 'Orc'. 1037 let name = builder.createString('Orc'); 1038 1039 // Create a `vector` representing the inventory of the Orc. Each number 1040 // could correspond to an item that can be claimed after he is slain. 1041 let treasure = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; 1042 let inv = MyGame.Sample.Monster.createInventoryVector(builder, treasure); 1043~~~ 1044</div> 1045<div class="language-php"> 1046~~~{.php} 1047 // Serialize a name for our monster, called "Orc". 1048 $name = $builder->createString("Orc"); 1049 1050 // Create a `vector` representing the inventory of the Orc. Each number 1051 // could correspond to an item that can be claimed after he is slain. 1052 $treasure = array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); 1053 $inv = \MyGame\Sample\Monster::CreateInventoryVector($builder, $treasure); 1054~~~ 1055</div> 1056<div class="language-c"> 1057~~~{.c} 1058 // Serialize a name for our monster, called "Orc". 1059 // The _str suffix indicates the source is an ascii-z string. 1060 flatbuffers_string_ref_t name = flatbuffers_string_create_str(B, "Orc"); 1061 1062 // Create a `vector` representing the inventory of the Orc. Each number 1063 // could correspond to an item that can be claimed after he is slain. 1064 uint8_t treasure[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 1065 flatbuffers_uint8_vec_ref_t inventory; 1066 // `c_vec_len` is the convenience macro we defined earlier. 1067 inventory = flatbuffers_uint8_vec_create(B, treasure, c_vec_len(treasure)); 1068~~~ 1069</div> 1070<div class="language-dart"> 1071~~~{.dart} 1072 // Serialize a name for our monster, called "Orc". 1073 final int name = builder.writeString('Orc'); 1074 1075 // Create a list representing the inventory of the Orc. Each number 1076 // could correspond to an item that can be claimed after he is slain. 1077 final List<int> treasure = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; 1078 final inventory = builder.writeListUint8(treasure); 1079 1080 // The following code should be used instead if you intend to use the 1081 // ObjectBuilder classes: 1082 // Serialize a name for our monster, called "Orc". 1083 final String name = 'Orc'; 1084 1085 // Create a list representing the inventory of the Orc. Each number 1086 // could correspond to an item that can be claimed after he is slain. 1087 final List<int> treasure = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; 1088~~~ 1089</div> 1090<div class="language-lua"> 1091~~~{.py} 1092 -- Serialize a name for our monster, called 'orc' 1093 local name = builder:CreateString("Orc") 1094 1095 -- Create a `vector` representing the inventory of the Orc. Each number 1096 -- could correspond to an item that can be claimed after he is slain. 1097 -- Note: Since we prepend the bytes, this loop iterates in reverse. 1098 monster.StartInventoryVector(builder, 10) 1099 for i=10,1,-1 do 1100 builder:PrependByte(i) 1101 end 1102 local inv = builder:EndVector(10) 1103~~~ 1104</div> 1105<div class="language-lobster"> 1106~~~{.lobster} 1107 // Name of the monster. 1108 let name = builder.CreateString("Orc") 1109 1110 // Inventory. 1111 let inv = builder.MyGame_Sample_MonsterCreateInventoryVector(map(10): _) 1112~~~ 1113</div> 1114<div class="language-rust"> 1115~~~{.rs} 1116 // Name of the Monster. 1117 let name = builder.create_string("Orc"); 1118 1119 // Inventory. 1120 let inventory = builder.create_vector(&[0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9]); 1121~~~ 1122</div> 1123<div class="language-swift"> 1124~~~{.swift} 1125 // Name of the Monster. 1126 let name = builder.create(string: "Orc") 1127 1128 // create inventory 1129 let inventory: [Byte] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 1130 let inventoryOffset = builder.createVector(inventory) 1131~~~ 1132</div> 1133 1134We serialized two built-in data types (`string` and `vector`) and captured 1135their return values. These values are offsets into the serialized data, 1136indicating where they are stored, such that we can refer to them below when 1137adding fields to our monster. 1138 1139*Note: To create a `vector` of nested objects (e.g. `table`s, `string`s, or 1140other `vector`s), collect their offsets into a temporary data structure, and 1141then create an additional `vector` containing their offsets.* 1142 1143If instead of creating a vector from an existing array you serialize elements 1144individually one by one, take care to note that this happens in reverse order, 1145as buffers are built back to front. 1146 1147For example, take a look at the two `Weapon`s that we created earlier (`Sword` 1148and `Axe`). These are both FlatBuffer `table`s, whose offsets we now store in 1149memory. Therefore we can create a FlatBuffer `vector` to contain these 1150offsets. 1151 1152<div class="language-cpp"> 1153~~~{.cpp} 1154 // Place the weapons into a `std::vector`, then convert that into a FlatBuffer `vector`. 1155 std::vector<flatbuffers::Offset<Weapon>> weapons_vector; 1156 weapons_vector.push_back(sword); 1157 weapons_vector.push_back(axe); 1158 auto weapons = builder.CreateVector(weapons_vector); 1159~~~ 1160</div> 1161<div class="language-java"> 1162~~~{.java} 1163 // Place the two weapons into an array, and pass it to the `createWeaponsVector()` method to 1164 // create a FlatBuffer vector. 1165 int[] weaps = new int[2]; 1166 weaps[0] = sword; 1167 weaps[1] = axe; 1168 1169 // Pass the `weaps` array into the `createWeaponsVector()` method to create a FlatBuffer vector. 1170 int weapons = Monster.createWeaponsVector(builder, weaps); 1171~~~ 1172</div> 1173<div class="language-kotlin"> 1174~~~{.kt} 1175 // Place the two weapons into an array, and pass it to the `createWeaponsVector()` method to 1176 // create a FlatBuffer vector. 1177 val weaps = intArrayOf(sword, axe) 1178 1179 // Pass the `weaps` array into the `createWeaponsVector()` method to create a FlatBuffer vector. 1180 val weapons = Monster.createWeaponsVector(builder, weaps) 1181~~~ 1182</div> 1183<div class="language-csharp"> 1184~~~{.cs} 1185 var weaps = new Offset<Weapon>[2]; 1186 weaps[0] = sword; 1187 weaps[1] = axe; 1188 1189 // Pass the `weaps` array into the `CreateWeaponsVector()` method to create a FlatBuffer vector. 1190 var weapons = Monster.CreateWeaponsVector(builder, weaps); 1191~~~ 1192</div> 1193<div class="language-go"> 1194~~~{.go} 1195 // Create a FlatBuffer vector and prepend the weapons. 1196 // Note: Since we prepend the data, prepend them in reverse order. 1197 sample.MonsterStartWeaponsVector(builder, 2) 1198 builder.PrependUOffsetT(axe) 1199 builder.PrependUOffsetT(sword) 1200 weapons := builder.EndVector(2) 1201~~~ 1202</div> 1203<div class="language-python"> 1204~~~{.py} 1205 # Create a FlatBuffer vector and prepend the weapons. 1206 # Note: Since we prepend the data, prepend them in reverse order. 1207 MyGame.Sample.Monster.StartWeaponsVector(builder, 2) 1208 builder.PrependUOffsetTRelative(axe) 1209 builder.PrependUOffsetTRelative(sword) 1210 weapons = builder.EndVector() 1211~~~ 1212</div> 1213<div class="language-javascript"> 1214~~~{.js} 1215 // Create an array from the two `Weapon`s and pass it to the 1216 // `createWeaponsVector()` method to create a FlatBuffer vector. 1217 var weaps = [sword, axe]; 1218 var weapons = MyGame.Sample.Monster.createWeaponsVector(builder, weaps); 1219~~~ 1220</div> 1221<div class="language-typescript"> 1222~~~{.ts} 1223 // Create an array from the two `Weapon`s and pass it to the 1224 // `createWeaponsVector()` method to create a FlatBuffer vector. 1225 let weaps = [sword, axe]; 1226 let weapons = MyGame.Sample.Monster.createWeaponsVector(builder, weaps); 1227~~~ 1228</div> 1229<div class="language-php"> 1230~~~{.php} 1231 // Create an array from the two `Weapon`s and pass it to the 1232 // `CreateWeaponsVector()` method to create a FlatBuffer vector. 1233 $weaps = array($sword, $axe); 1234 $weapons = \MyGame\Sample\Monster::CreateWeaponsVector($builder, $weaps); 1235~~~ 1236</div> 1237<div class="language-c"> 1238~~~{.c} 1239 // We use the internal builder stack to implement a dynamic vector. 1240 ns(Weapon_vec_start(B)); 1241 ns(Weapon_vec_push(B, sword)); 1242 ns(Weapon_vec_push(B, axe)); 1243 ns(Weapon_vec_ref_t) weapons = ns(Weapon_vec_end(B)); 1244~~~ 1245</div> 1246<div class="language-dart"> 1247~~~{.dart} 1248 // If using the Builder classes, serialize the `[sword,axe]` 1249 final weapons = builder.writeList([sword, axe]); 1250 1251 // If using the ObjectBuilders, just create an array from the two `Weapon`s 1252 final List<myGame.WeaponBuilder> weaps = [sword, axe]; 1253~~~ 1254</div> 1255<div class="language-lua"> 1256~~~{.lua} 1257 -- Create a FlatBuffer vector and prepend the weapons. 1258 -- Note: Since we prepend the data, prepend them in reverse order. 1259 monster.StartWeaponsVector(builder, 2) 1260 builder:PrependUOffsetTRelative(axe) 1261 builder:PrependUOffsetTRelative(sword) 1262 local weapons = builder:EndVector(2) 1263~~~ 1264</div> 1265<div class="language-lobster"> 1266~~~{.lobster} 1267 let weapons = builder.MyGame_Sample_MonsterCreateWeaponsVector(weapon_offsets) 1268~~~ 1269</div> 1270<div class="language-rust"> 1271~~~{.rs} 1272 // Create a FlatBuffer `vector` that contains offsets to the sword and axe 1273 // we created above. 1274 let weapons = builder.create_vector(&[sword, axe]); 1275~~~ 1276</div> 1277<div class="language-swift"> 1278~~~{.swift} 1279 // Create a FlatBuffer `vector` that contains offsets to the sword and axe 1280 // we created above. 1281 let weaponsOffset = builder.createVector(ofOffsets: [sword, axe]) 1282~~~ 1283</div> 1284 1285<br> 1286Note there are additional convenience overloads of `CreateVector`, allowing you 1287to work with data that's not in a `std::vector` or allowing you to generate 1288elements by calling a lambda. For the common case of `std::vector<std::string>` 1289there's also `CreateVectorOfStrings`. 1290</div> 1291 1292Note that vectors of structs are serialized differently from tables, since 1293structs are stored in-line in the vector. For example, to create a vector 1294for the `path` field above: 1295 1296<div class="language-cpp"> 1297~~~{.cpp} 1298 Vec3 points[] = { Vec3(1.0f, 2.0f, 3.0f), Vec3(4.0f, 5.0f, 6.0f) }; 1299 auto path = builder.CreateVectorOfStructs(points, 2); 1300~~~ 1301</div> 1302<div class="language-java"> 1303~~~{.java} 1304 Monster.startPathVector(fbb, 2); 1305 Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f); 1306 Vec3.createVec3(builder, 4.0f, 5.0f, 6.0f); 1307 int path = fbb.endVector(); 1308~~~ 1309</div> 1310<div class="language-kotlin"> 1311~~~{.kt} 1312 Monster.startPathVector(fbb, 2) 1313 Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f) 1314 Vec3.createVec3(builder, 4.0f, 5.0f, 6.0f) 1315 val path = fbb.endVector() 1316~~~ 1317</div> 1318<div class="language-csharp"> 1319~~~{.cs} 1320 Monster.StartPathVector(fbb, 2); 1321 Vec3.CreateVec3(builder, 1.0f, 2.0f, 3.0f); 1322 Vec3.CreateVec3(builder, 4.0f, 5.0f, 6.0f); 1323 var path = fbb.EndVector(); 1324~~~ 1325</div> 1326<div class="language-go"> 1327~~~{.go} 1328 sample.MonsterStartPathVector(builder, 2) 1329 sample.CreateVec3(builder, 1.0, 2.0, 3.0) 1330 sample.CreateVec3(builder, 4.0, 5.0, 6.0) 1331 path := builder.EndVector(2) 1332~~~ 1333</div> 1334<div class="language-python"> 1335~~~{.py} 1336 MyGame.Sample.Monster.StartPathVector(builder, 2) 1337 MyGame.Sample.Vec3.CreateVec3(builder, 1.0, 2.0, 3.0) 1338 MyGame.Sample.Vec3.CreateVec3(builder, 4.0, 5.0, 6.0) 1339 path = builder.EndVector() 1340~~~ 1341</div> 1342<div class="language-javascript"> 1343~~~{.js} 1344 MyGame.Sample.Monster.startPathVector(builder, 2); 1345 MyGame.Sample.Vec3.createVec3(builder, 1.0, 2.0, 3.0); 1346 MyGame.Sample.Vec3.createVec3(builder, 4.0, 5.0, 6.0); 1347 var path = builder.endVector(); 1348~~~ 1349</div> 1350<div class="language-typescript"> 1351~~~{.ts} 1352 MyGame.Sample.Monster.startPathVector(builder, 2); 1353 MyGame.Sample.Vec3.createVec3(builder, 1.0, 2.0, 3.0); 1354 MyGame.Sample.Vec3.createVec3(builder, 4.0, 5.0, 6.0); 1355 let path = builder.endVector(); 1356~~~ 1357</div> 1358<div class="language-php"> 1359~~~{.php} 1360 \MyGame\Example\Monster::StartPathVector($builder, 2); 1361 \MyGame\Sample\Vec3::CreateVec3($builder, 1.0, 2.0, 3.0); 1362 \MyGame\Sample\Vec3::CreateVec3($builder, 1.0, 2.0, 3.0); 1363 $path = $builder->endVector(); 1364~~~ 1365</div> 1366<div class="language-c"> 1367~~~{.c} 1368 // TBD 1369~~~ 1370</div> 1371<div class="language-dart"> 1372~~~{.dart} 1373 // Using the Builder classes, you can write a list of structs like so: 1374 // Note that the intended order should be reversed if order is important. 1375 final vec3Builder = new myGame.Vec3Builder(builder); 1376 vec3Builder.finish(4.0, 5.0, 6.0); 1377 vec3Builder.finish(1.0, 2.0, 3.0); 1378 final int path = builder.endStructVector(2); // the length of the vector 1379 1380 // Otherwise, using the ObjectBuilder classes: 1381 // The dart implementation provides a simple interface for writing vectors 1382 // of structs, in `writeListOfStructs`. This method takes 1383 // `List<ObjectBuilder>` and is used by the generated builder classes. 1384 final List<myGame.Vec3ObjectBuilder> path = [ 1385 new myGame.Vec3ObjectBuilder(x: 1.0, y: 2.0, z: 3.0), 1386 new myGame.Vec3ObjectBuilder(x: 4.0, y: 5.0, z: 6.0) 1387 ]; 1388~~~ 1389</div> 1390<div class="language-lua"> 1391~~~{.lua} 1392 -- Create a FlatBuffer vector and prepend the path locations. 1393 -- Note: Since we prepend the data, prepend them in reverse order. 1394 monster.StartPathVector(builder, 2) 1395 vec3.CreateVec3(builder, 1.0, 2.0, 3.0) 1396 vec3.CreateVec3(builder, 4.0, 5.0, 6.0) 1397 local path = builder:EndVector(2) 1398~~~ 1399</div> 1400<div class="language-lobster"> 1401~~~{.lobster} 1402 builder.MyGame_Sample_MonsterStartPathVector(2) 1403 builder.MyGame_Sample_CreateVec3(1.0, 2.0, 3.0) 1404 builder.MyGame_Sample_CreateVec3(4.0, 5.0, 6.0) 1405 let path = builder.EndVector(2) 1406~~~ 1407</div> 1408<div class="language-rust"> 1409~~~{.rs} 1410 // Create the path vector of Vec3 objects. 1411 let x = Vec3::new(1.0, 2.0, 3.0); 1412 let y = Vec3::new(4.0, 5.0, 6.0); 1413 let path = builder.create_vector(&[x, y]); 1414 1415 // Note that, for convenience, it is also valid to create a vector of 1416 // references to structs, like this: 1417 // let path = builder.create_vector(&[&x, &y]); 1418~~~ 1419</div> 1420<div class="language-swift"> 1421~~~{.swift} 1422 // 1423 let points = fbb.createVector(ofStructs: [ 1424 Vec3(x: 1, y: 2, z: 3), 1425 Vec3(x: 4, y: 5, z: 6) 1426 ]) 1427 1428 // OR 1429 var vec3 = [ 1430 Vec3(x: 1, y: 2, z: 3), 1431 Vec3(x: 4, y: 5, z: 6) 1432 ] 1433 Monster.startVectorOfVec3(2, in: &fbb) 1434 for i in obj { 1435 _ = create(struct: i) 1436 } 1437 let points = fbb.endVector(len: size) 1438~~~ 1439</div> 1440 1441 1442We have now serialized the non-scalar components of the orc, so we 1443can serialize the monster itself: 1444 1445<div class="language-cpp"> 1446~~~{.cpp} 1447 // Create the position struct 1448 auto position = Vec3(1.0f, 2.0f, 3.0f); 1449 1450 // Set his hit points to 300 and his mana to 150. 1451 int hp = 300; 1452 int mana = 150; 1453 1454 // Finally, create the monster using the `CreateMonster` helper function 1455 // to set all fields. 1456 auto orc = CreateMonster(builder, &position, mana, hp, name, inventory, 1457 Color_Red, weapons, Equipment_Weapon, axe.Union(), 1458 path); 1459~~~ 1460</div> 1461<div class="language-java"> 1462~~~{.java} 1463 // Create our monster using `startMonster()` and `endMonster()`. 1464 Monster.startMonster(builder); 1465 Monster.addPos(builder, Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f)); 1466 Monster.addName(builder, name); 1467 Monster.addColor(builder, Color.Red); 1468 Monster.addHp(builder, (short)300); 1469 Monster.addInventory(builder, inv); 1470 Monster.addWeapons(builder, weapons); 1471 Monster.addEquippedType(builder, Equipment.Weapon); 1472 Monster.addEquipped(builder, axe); 1473 Monster.addPath(builder, path); 1474 int orc = Monster.endMonster(builder); 1475~~~ 1476</div> 1477<div class="language-kotlin"> 1478~~~{.kt} 1479 // Create our monster using `startMonster()` and `endMonster()`. 1480 Monster.startMonster(builder) 1481 Monster.addPos(builder, Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f)) 1482 Monster.addName(builder, name) 1483 Monster.addColor(builder, Color.Red) 1484 Monster.addHp(builder, 300.toShort()) 1485 Monster.addInventory(builder, inv) 1486 Monster.addWeapons(builder, weapons) 1487 Monster.addEquippedType(builder, Equipment.Weapon) 1488 Monster.addEquipped(builder, axe) 1489 Monster.addPath(builder, path) 1490 val orc = Monster.endMonster(builder) 1491~~~ 1492</div> 1493<div class="language-csharp"> 1494~~~{.cs} 1495 // Create our monster using `StartMonster()` and `EndMonster()`. 1496 Monster.StartMonster(builder); 1497 Monster.AddPos(builder, Vec3.CreateVec3(builder, 1.0f, 2.0f, 3.0f)); 1498 Monster.AddHp(builder, (short)300); 1499 Monster.AddName(builder, name); 1500 Monster.AddInventory(builder, inv); 1501 Monster.AddColor(builder, Color.Red); 1502 Monster.AddWeapons(builder, weapons); 1503 Monster.AddEquippedType(builder, Equipment.Weapon); 1504 Monster.AddEquipped(builder, axe.Value); // Axe 1505 Monster.AddPath(builder, path); 1506 var orc = Monster.EndMonster(builder); 1507~~~ 1508</div> 1509<div class="language-go"> 1510~~~{.go} 1511 // Create our monster using `MonsterStart()` and `MonsterEnd()`. 1512 sample.MonsterStart(builder) 1513 sample.MonsterAddPos(builder, sample.CreateVec3(builder, 1.0, 2.0, 3.0)) 1514 sample.MonsterAddHp(builder, 300) 1515 sample.MonsterAddName(builder, name) 1516 sample.MonsterAddInventory(builder, inv) 1517 sample.MonsterAddColor(builder, sample.ColorRed) 1518 sample.MonsterAddWeapons(builder, weapons) 1519 sample.MonsterAddEquippedType(builder, sample.EquipmentWeapon) 1520 sample.MonsterAddEquipped(builder, axe) 1521 sample.MonsterAddPath(builder, path) 1522 orc := sample.MonsterEnd(builder) 1523~~~ 1524</div> 1525<div class="language-python"> 1526~~~{.py} 1527 # Create our monster by using `Monster.Start()` and `Monster.End()`. 1528 MyGame.Sample.Monster.Start(builder) 1529 MyGame.Sample.Monster.AddPos(builder, 1530 MyGame.Sample.Vec3.CreateVec3(builder, 1.0, 2.0, 3.0)) 1531 MyGame.Sample.Monster.AddHp(builder, 300) 1532 MyGame.Sample.Monster.AddName(builder, name) 1533 MyGame.Sample.Monster.AddInventory(builder, inv) 1534 MyGame.Sample.Monster.AddColor(builder, 1535 MyGame.Sample.Color.Color().Red) 1536 MyGame.Sample.Monster.AddWeapons(builder, weapons) 1537 MyGame.Sample.Monster.AddEquippedType( 1538 builder, MyGame.Sample.Equipment.Equipment().Weapon) 1539 MyGame.Sample.Monster.AddEquipped(builder, axe) 1540 MyGame.Sample.Monster.AddPath(builder, path) 1541 orc = MyGame.Sample.Monster.End(builder) 1542~~~ 1543</div> 1544<div class="language-javascript"> 1545~~~{.js} 1546 // Create our monster by using `startMonster()` and `endMonster()`. 1547 MyGame.Sample.Monster.startMonster(builder); 1548 MyGame.Sample.Monster.addPos(builder, 1549 MyGame.Sample.Vec3.createVec3(builder, 1.0, 2.0, 3.0)); 1550 MyGame.Sample.Monster.addHp(builder, 300); 1551 MyGame.Sample.Monster.addColor(builder, MyGame.Sample.Color.Red) 1552 MyGame.Sample.Monster.addName(builder, name); 1553 MyGame.Sample.Monster.addInventory(builder, inv); 1554 MyGame.Sample.Monster.addWeapons(builder, weapons); 1555 MyGame.Sample.Monster.addEquippedType(builder, MyGame.Sample.Equipment.Weapon); 1556 MyGame.Sample.Monster.addEquipped(builder, axe); 1557 MyGame.Sample.Monster.addPath(builder, path); 1558 var orc = MyGame.Sample.Monster.endMonster(builder); 1559~~~ 1560</div> 1561<div class="language-typescript"> 1562~~~{.ts} 1563 // Create our monster by using `startMonster()` and `endMonster()`. 1564 MyGame.Sample.Monster.startMonster(builder); 1565 MyGame.Sample.Monster.addPos(builder, 1566 MyGame.Sample.Vec3.createVec3(builder, 1.0, 2.0, 3.0)); 1567 MyGame.Sample.Monster.addHp(builder, 300); 1568 MyGame.Sample.Monster.addColor(builder, MyGame.Sample.Color.Red) 1569 MyGame.Sample.Monster.addName(builder, name); 1570 MyGame.Sample.Monster.addInventory(builder, inv); 1571 MyGame.Sample.Monster.addWeapons(builder, weapons); 1572 MyGame.Sample.Monster.addEquippedType(builder, MyGame.Sample.Equipment.Weapon); 1573 MyGame.Sample.Monster.addEquipped(builder, axe); 1574 MyGame.Sample.Monster.addPath(builder, path); 1575 let orc = MyGame.Sample.Monster.endMonster(builder); 1576~~~ 1577</div> 1578<div class="language-php"> 1579~~~{.php} 1580 // Create our monster by using `StartMonster()` and `EndMonster()`. 1581 \MyGame\Sample\Monster::StartMonster($builder); 1582 \MyGame\Sample\Monster::AddPos($builder, 1583 \MyGame\Sample\Vec3::CreateVec3($builder, 1.0, 2.0, 3.0)); 1584 \MyGame\Sample\Monster::AddHp($builder, 300); 1585 \MyGame\Sample\Monster::AddName($builder, $name); 1586 \MyGame\Sample\Monster::AddInventory($builder, $inv); 1587 \MyGame\Sample\Monster::AddColor($builder, \MyGame\Sample\Color::Red); 1588 \MyGame\Sample\Monster::AddWeapons($builder, $weapons); 1589 \MyGame\Sample\Monster::AddEquippedType($builder, \MyGame\Sample\Equipment::Weapon); 1590 \MyGame\Sample\Monster::AddEquipped($builder, $axe); 1591 \MyGame\Sample\Monster::AddPath($builder, $path); 1592 $orc = \MyGame\Sample\Monster::EndMonster($builder); 1593~~~ 1594</div> 1595<div class="language-c"> 1596~~~{.c} 1597 // Set his hit points to 300 and his mana to 150. 1598 uint16_t hp = 300; 1599 uint16_t mana = 150; 1600 1601 // Define an equipment union. `create` calls in C has a single 1602 // argument for unions where C++ has both a type and a data argument. 1603 ns(Equipment_union_ref_t) equipped = ns(Equipment_as_Weapon(axe)); 1604 ns(Vec3_t) pos = { 1.0f, 2.0f, 3.0f }; 1605 ns(Monster_create_as_root(B, &pos, mana, hp, name, inventory, ns(Color_Red), 1606 weapons, equipped, path)); 1607~~~ 1608</div> 1609<div class="language-dart"> 1610~~~{.dart} 1611 // Using the Builder API: 1612 // Set his hit points to 300 and his mana to 150. 1613 final int hp = 300; 1614 final int mana = 150; 1615 1616 final monster = new myGame.MonsterBuilder(builder) 1617 ..begin() 1618 ..addNameOffset(name) 1619 ..addInventoryOffset(inventory) 1620 ..addWeaponsOffset(weapons) 1621 ..addEquippedType(myGame.EquipmentTypeId.Weapon) 1622 ..addEquippedOffset(axe) 1623 ..addHp(hp) 1624 ..addMana(mana) 1625 ..addPos(vec3Builder.finish(1.0, 2.0, 3.0)) 1626 ..addPathOffset(path) 1627 ..addColor(myGame.Color.Red); 1628 1629 final int orc = monster.finish(); 1630 1631 // -Or- using the ObjectBuilder API: 1632 // Set his hit points to 300 and his mana to 150. 1633 final int hp = 300; 1634 final int mana = 150; 1635 1636 // Note that these parameters are optional - it is not necessary to set 1637 // all of them. 1638 // Also note that it is not necessary to `finish` the builder helpers above 1639 // - the generated code will automatically reuse offsets if the same object 1640 // is used in more than one place (e.g. the axe appearing in `weapons` and 1641 // `equipped`). 1642 final myGame.MonsterBuilder orcBuilder = new myGame.MonsterBuilder( 1643 name: name, 1644 inventory: treasure, 1645 weapons: weaps, 1646 equippedType: myGame.EquipmentTypeId.Weapon, 1647 equipped: axe, 1648 path: path, 1649 hp: hp, 1650 mana: mana, 1651 pos: new myGame.Vec3Builder(x: 1.0, y: 2.0, z: 3.0), 1652 color: myGame.Color.Red, 1653 path: [ 1654 new myGame.Vec3ObjectBuilder(x: 1.0, y: 2.0, z: 3.0), 1655 new myGame.Vec3ObjectBuilder(x: 4.0, y: 5.0, z: 6.0) 1656 ]); 1657 1658 final int orc = orcBuilder.finish(builder); 1659~~~ 1660</div> 1661<div class="language-lua"> 1662~~~{.lua} 1663 -- Create our monster by using Start() andEnd() 1664 monster.Start(builder) 1665 monster.AddPos(builder, vec3.CreateVec3(builder, 1.0, 2.0, 3.0)) 1666 monster.AddHp(builder, 300) 1667 monster.AddName(builder, name) 1668 monster.AddInventory(builder, inv) 1669 monster.AddColor(builder, color.Red) 1670 monster.AddWeapons(builder, weapons) 1671 monster.AddEquippedType(builder, equipment.Weapon) 1672 monster.AddEquipped(builder, axe) 1673 monster.AddPath(builder, path) 1674 local orc = monster.End(builder) 1675~~~ 1676</div> 1677<div class="language-lobster"> 1678~~~{.lobster} 1679 let orc = MyGame_Sample_MonsterBuilder { b } 1680 .start() 1681 .add_pos(b.MyGame_Sample_CreateVec3(1.0, 2.0, 3.0)) 1682 .add_hp(300) 1683 .add_name(name) 1684 .add_inventory(inv) 1685 .add_color(MyGame_Sample_Color_Red) 1686 .add_weapons(weapons) 1687 .add_equipped_type(MyGame_Sample_Equipment_Weapon) 1688 .add_equipped(weapon_offsets[1]) 1689 .add_path(path) 1690 .end() 1691~~~ 1692</div> 1693<div class="language-rust"> 1694~~~{.rs} 1695 // Create the monster using the `Monster::create` helper function. This 1696 // function accepts a `MonsterArgs` struct, which supplies all of the data 1697 // needed to build a `Monster`. To supply empty/default fields, just use the 1698 // Rust built-in `Default::default()` function, as demonstrated below. 1699 let orc = Monster::create(&mut builder, &MonsterArgs{ 1700 pos: Some(&Vec3::new(1.0f32, 2.0f32, 3.0f32)), 1701 mana: 150, 1702 hp: 80, 1703 name: Some(name), 1704 inventory: Some(inventory), 1705 color: Color::Red, 1706 weapons: Some(weapons), 1707 equipped_type: Equipment::Weapon, 1708 equipped: Some(axe.as_union_value()), 1709 path: Some(path), 1710 ..Default::default() 1711 }); 1712~~~ 1713</div> 1714<div class="language-swift"> 1715~~~{.swift} 1716 let orc = Monster.createMonster( 1717 &builder, 1718 pos: MyGame_Sample_Vec3(x: 1, y: 2, z: 3), 1719 hp: 300, 1720 nameOffset: name, 1721 inventoryVectorOffset: inventoryOffset, 1722 color: .red, 1723 weaponsVectorOffset: weaponsOffset, 1724 equippedType: .weapon, 1725 equippedOffset: axe) 1726~~~ 1727</div> 1728 1729Note how we create `Vec3` struct in-line in the table. Unlike tables, structs 1730are simple combinations of scalars that are always stored inline, just like 1731scalars themselves. 1732 1733**Important**: Unlike structs, you should not nest tables or other objects, 1734which is why we created all the strings/vectors/tables that this monster refers 1735to before `start`. If you try to create any of them between `start` and `end`, 1736you will get an assert/exception/panic depending on your language. 1737 1738*Note: Since we are passing `150` as the `mana` field, which happens to be the 1739default value, the field will not actually be written to the buffer, since the 1740default value will be returned on query anyway. This is a nice space savings, 1741especially if default values are common in your data. It also means that you do 1742not need to be worried about adding a lot of fields that are only used in a small 1743number of instances, as it will not bloat the buffer if unused.* 1744 1745<div class="language-cpp"> 1746<br> 1747If you do not wish to set every field in a `table`, it may be more convenient to 1748manually set each field of your monster, instead of calling `CreateMonster()`. 1749The following snippet is functionally equivalent to the above code, but provides 1750a bit more flexibility. 1751<br> 1752~~~{.cpp} 1753 // You can use this code instead of `CreateMonster()`, to create our orc 1754 // manually. 1755 MonsterBuilder monster_builder(builder); 1756 monster_builder.add_pos(&position); 1757 monster_builder.add_hp(hp); 1758 monster_builder.add_name(name); 1759 monster_builder.add_inventory(inventory); 1760 monster_builder.add_color(Color_Red); 1761 monster_builder.add_weapons(weapons); 1762 monster_builder.add_equipped_type(Equipment_Weapon); 1763 monster_builder.add_equipped(axe.Union()); 1764 auto orc = monster_builder.Finish(); 1765~~~ 1766</div> 1767<div class="language-c"> 1768If you do not wish to set every field in a `table`, it may be more convenient to 1769manually set each field of your monster, instead of calling `create_monster_as_root()`. 1770The following snippet is functionally equivalent to the above code, but provides 1771a bit more flexibility. 1772<br> 1773~~~{.c} 1774 // It is important to pair `start_as_root` with `end_as_root`. 1775 ns(Monster_start_as_root(B)); 1776 ns(Monster_pos_create(B, 1.0f, 2.0f, 3.0f)); 1777 // or alternatively 1778 //ns(Monster_pos_add(&pos); 1779 1780 ns(Monster_hp_add(B, hp)); 1781 // Notice that `Monser_name_add` adds a string reference unlike the 1782 // add_str and add_strn variants. 1783 ns(Monster_name_add(B, name)); 1784 ns(Monster_inventory_add(B, inventory)); 1785 ns(Monster_color_add(B, ns(Color_Red))); 1786 ns(Monster_weapons_add(B, weapons)); 1787 ns(Monster_equipped_add(B, equipped)); 1788 // Complete the monster object and make it the buffer root object. 1789 ns(Monster_end_as_root(B)); 1790~~~ 1791</div> 1792 1793<div class="language-swift"> 1794~~~{.swift} 1795 let start = Monster.startMonster(&builder) 1796 Monster.add(pos: Vec3(x: 1, y: 2, z: 3), &builder) 1797 Monster.add(hp: 300, &builder) 1798 Monster.add(name: name, &builder) 1799 Monster.addVectorOf(inventory: inventoryOffset, &builder) 1800 Monster.add(color: .red, &builder) 1801 Monster.addVectorOf(weapons: weaponsOffset, &builder) 1802 Monster.add(equippedType: .weapon, &builder) 1803 Monster.add(equipped: axe, &builder) 1804 var orc = Monster.endMonster(&builder, start: start) 1805~~~ 1806</div> 1807 1808Before finishing the serialization, let's take a quick look at FlatBuffer 1809`union Equipped`. There are two parts to each FlatBuffer `union`. The first is 1810a hidden field `_type` that is generated to hold the type of `table` referred 1811to by the `union`. This allows you to know which type to cast to at runtime. 1812Second is the `union`'s data. 1813 1814In our example, the last two things we added to our `Monster` were the 1815`Equipped Type` and the `Equipped` union itself. 1816 1817Here is a repetition of these lines, to help highlight them more clearly: 1818 1819<div class="language-cpp"> 1820 ~~~{.cpp} 1821 monster_builder.add_equipped_type(Equipment_Weapon); // Union type 1822 monster_builder.add_equipped(axe.Union()); // Union data 1823 ~~~ 1824</div> 1825<div class="language-java"> 1826 ~~~{.java} 1827 Monster.addEquippedType(builder, Equipment.Weapon); // Union type 1828 Monster.addEquipped(axe); // Union data 1829 ~~~ 1830</div> 1831<div class="language-kotlin"> 1832 ~~~{.kt} 1833 Monster.addEquippedType(builder, Equipment.Weapon) // Union type 1834 Monster.addEquipped(axe) // Union data 1835 ~~~ 1836</div> 1837<div class="language-csharp"> 1838 ~~~{.cs} 1839 Monster.AddEquippedType(builder, Equipment.Weapon); // Union type 1840 Monster.AddEquipped(builder, axe.Value); // Union data 1841 ~~~ 1842</div> 1843<div class="language-go"> 1844 ~~~{.go} 1845 sample.MonsterAddEquippedType(builder, sample.EquipmentWeapon) // Union type 1846 sample.MonsterAddEquipped(builder, axe) // Union data 1847 ~~~ 1848</div> 1849<div class="language-python"> 1850 ~~~{.py} 1851 MyGame.Sample.Monster.AddEquippedType( # Union type 1852 builder, MyGame.Sample.Equipment.Equipment().Weapon) 1853 MyGame.Sample.Monster.AddEquipped(builder, axe) # Union data 1854 ~~~ 1855</div> 1856<div class="language-javascript"> 1857 ~~~{.js} 1858 MyGame.Sample.Monster.addEquippedType(builder, MyGame.Sample.Equipment.Weapon); // Union type 1859 MyGame.Sample.Monster.addEquipped(builder, axe); // Union data 1860 ~~~ 1861</div> 1862<div class="language-typescript"> 1863 ~~~{.ts} 1864 MyGame.Sample.Monster.addEquippedType(builder, MyGame.Sample.Equipment.Weapon); // Union type 1865 MyGame.Sample.Monster.addEquipped(builder, axe); // Union data 1866 ~~~ 1867</div> 1868<div class="language-php"> 1869 ~~~{.php} 1870 \MyGame\Sample\Monster::AddEquippedType($builder, \MyGame\Sample\Equipment::Weapon); // Union type 1871 \MyGame\Sample\Monster::AddEquipped($builder, $axe); // Union data 1872 ~~~ 1873</div> 1874<div class="language-c"> 1875~~~{.c} 1876 // Add union type and data simultaneously. 1877 ns(Monster_equipped_Weapon_add(B, axe)); 1878~~~ 1879</div> 1880<div class="language-dart"> 1881~~~{.dart} 1882 // using the builder API: 1883 ..addEquippedType(myGame.EquipmentTypeId.Weapon) 1884 ..addEquippedOffset(axe) 1885 1886 // in the ObjectBuilder API: 1887 equippedTypeId: myGame.EquipmentTypeId.Weapon, // Union type 1888 equipped: axe, // Union data 1889~~~ 1890</div> 1891<div class="language-lua"> 1892~~~{.lua} 1893 monster.AddEquippedType(builder, equipment.Weapon) -- Union type 1894 monster.AddEquipped(builder, axe) -- Union data 1895~~~ 1896</div> 1897<div class="language-lobster"> 1898~~~{.lobster} 1899 .add_equipped_type(MyGame_Sample_Equipment_Weapon) 1900 .add_equipped(axe) 1901~~~ 1902</div> 1903<div class="language-rust"> 1904 ~~~{.rs} 1905 // You need to call `as_union_value` to turn an object into a type that 1906 // can be used as a union value. 1907 monster_builder.add_equipped_type(Equipment::Weapon); // Union type 1908 monster_builder.add_equipped(axe.as_union_value()); // Union data 1909 ~~~ 1910</div> 1911<div class="language-swift"> 1912 ~~~{.swift} 1913 Monster.add(equippedType: .weapon, builder) // Type of union 1914 Monster.add(equipped: axe, builder) // Union data 1915 ~~~ 1916</div> 1917 1918 1919After you have created your buffer, you will have the offset to the root of the 1920data in the `orc` variable, so you can finish the buffer by calling the 1921appropriate `finish` method. 1922 1923 1924<div class="language-cpp"> 1925~~~{.cpp} 1926 // Call `Finish()` to instruct the builder that this monster is complete. 1927 // Note: Regardless of how you created the `orc`, you still need to call 1928 // `Finish()` on the `FlatBufferBuilder`. 1929 builder.Finish(orc); // You could also call `FinishMonsterBuffer(builder, orc);`. 1930~~~ 1931</div> 1932<div class="language-java"> 1933~~~{.java} 1934 // Call `finish()` to instruct the builder that this monster is complete. 1935 builder.finish(orc); // You could also call `Monster.finishMonsterBuffer(builder, orc);`. 1936~~~ 1937</div> 1938<div class="language-kotlin"> 1939~~~{.kt} 1940 // Call `finish()` to instruct the builder that this monster is complete. 1941 builder.finish(orc) // You could also call `Monster.finishMonsterBuffer(builder, orc);`. 1942~~~ 1943</div> 1944<div class="language-csharp"> 1945~~~{.cs} 1946 // Call `Finish()` to instruct the builder that this monster is complete. 1947 builder.Finish(orc.Value); // You could also call `Monster.FinishMonsterBuffer(builder, orc);`. 1948~~~ 1949</div> 1950<div class="language-go"> 1951~~~{.go} 1952 // Call `Finish()` to instruct the builder that this monster is complete. 1953 builder.Finish(orc) 1954~~~ 1955</div> 1956<div class="language-python"> 1957~~~{.py} 1958 # Call `Finish()` to instruct the builder that this monster is complete. 1959 builder.Finish(orc) 1960~~~ 1961</div> 1962<div class="language-javascript"> 1963~~~{.js} 1964 // Call `finish()` to instruct the builder that this monster is complete. 1965 builder.finish(orc); // You could also call `MyGame.Sample.Monster.finishMonsterBuffer(builder, orc);`. 1966~~~ 1967</div> 1968<div class="language-typescript"> 1969~~~{.ts} 1970 // Call `finish()` to instruct the builder that this monster is complete. 1971 builder.finish(orc); // You could also call `MyGame.Sample.Monster.finishMonsterBuffer(builder, orc);`. 1972~~~ 1973</div> 1974<div class="language-php"> 1975~~~{.php} 1976 // Call `finish()` to instruct the builder that this monster is complete. 1977 $builder->finish($orc); // You may also call `\MyGame\Sample\Monster::FinishMonsterBuffer($builder, $orc);`. 1978~~~ 1979</div> 1980<div class="language-c"> 1981~~~{.c} 1982 // Because we used `Monster_create_as_root`, we do not need a `finish` call in C`. 1983~~~ 1984</div> 1985<div class="language-dart"> 1986~~~{.dart} 1987 // Call `finish()` to instruct the builder that this monster is complete. 1988 // See the next code section, as in Dart `finish` will also return the byte array. 1989~~~ 1990</div> 1991<div class="language-lua"> 1992~~~{.lua} 1993 -- Call 'Finish()' to instruct the builder that this monster is complete. 1994 builder:Finish(orc) 1995~~~ 1996</div> 1997<div class="language-lobster"> 1998~~~{.lobster} 1999 // Call `Finish()` to instruct the builder that this monster is complete. 2000 builder.Finish(orc) 2001~~~ 2002</div> 2003<div class="language-rust"> 2004~~~{.rs} 2005 // Call `finish()` to instruct the builder that this monster is complete. 2006 builder.finish(orc, None); 2007~~~ 2008</div> 2009<div class="language-swift"> 2010~~~{.swift} 2011 // Call `finish(offset:)` to instruct the builder that this monster is complete. 2012 builder.finish(offset: orc) 2013~~~ 2014</div> 2015 2016The buffer is now ready to be stored somewhere, sent over the network, be 2017compressed, or whatever you'd like to do with it. You can access the buffer 2018like so: 2019 2020<div class="language-cpp"> 2021~~~{.cpp} 2022 // This must be called after `Finish()`. 2023 uint8_t *buf = builder.GetBufferPointer(); 2024 int size = builder.GetSize(); // Returns the size of the buffer that 2025 // `GetBufferPointer()` points to. 2026~~~ 2027</div> 2028<div class="language-java"> 2029~~~{.java} 2030 // This must be called after `finish()`. 2031 java.nio.ByteBuffer buf = builder.dataBuffer(); 2032 // The data in this ByteBuffer does NOT start at 0, but at buf.position(). 2033 // The number of bytes is buf.remaining(). 2034 2035 // Alternatively this copies the above data out of the ByteBuffer for you: 2036 byte[] buf = builder.sizedByteArray(); 2037~~~ 2038</div> 2039<div class="language-kotlin"> 2040~~~{.kt} 2041 // This must be called after `finish()`. 2042 val buf = builder.dataBuffer() 2043 // The data in this ByteBuffer does NOT start at 0, but at buf.position(). 2044 // The number of bytes is buf.remaining(). 2045 2046 // Alternatively this copies the above data out of the ByteBuffer for you: 2047 val buf = builder.sizedByteArray() 2048~~~ 2049</div> 2050<div class="language-csharp"> 2051~~~{.cs} 2052 // This must be called after `Finish()`. 2053 var buf = builder.DataBuffer; // Of type `FlatBuffers.ByteBuffer`. 2054 // The data in this ByteBuffer does NOT start at 0, but at buf.Position. 2055 // The end of the data is marked by buf.Length, so the size is 2056 // buf.Length - buf.Position. 2057 2058 // Alternatively this copies the above data out of the ByteBuffer for you: 2059 byte[] buf = builder.SizedByteArray(); 2060~~~ 2061</div> 2062<div class="language-go"> 2063~~~{.go} 2064 // This must be called after `Finish()`. 2065 buf := builder.FinishedBytes() // Of type `byte[]`. 2066~~~ 2067</div> 2068<div class="language-python"> 2069~~~{.py} 2070 # This must be called after `Finish()`. 2071 buf = builder.Output() // Of type `bytearray`. 2072~~~ 2073</div> 2074<div class="language-javascript"> 2075~~~{.js} 2076 // This must be called after `finish()`. 2077 var buf = builder.asUint8Array(); // Of type `Uint8Array`. 2078~~~ 2079</div> 2080<div class="language-typescript"> 2081~~~{.ts} 2082 // This must be called after `finish()`. 2083 let buf = builder.asUint8Array(); // Of type `Uint8Array`. 2084~~~ 2085</div> 2086<div class="language-php"> 2087~~~{.php} 2088 // This must be called after `finish()`. 2089 $buf = $builder->dataBuffer(); // Of type `Google\FlatBuffers\ByteBuffer` 2090 // The data in this ByteBuffer does NOT start at 0, but at buf->getPosition(). 2091 // The end of the data is marked by buf->capacity(), so the size is 2092 // buf->capacity() - buf->getPosition(). 2093~~~ 2094</div> 2095<div class="language-c"> 2096~~~{.c} 2097 uint8_t *buf; 2098 size_t size; 2099 2100 // Allocate and extract a readable buffer from internal builder heap. 2101 // The returned buffer must be deallocated using `free`. 2102 // NOTE: Finalizing the buffer does NOT change the builder, it 2103 // just creates a snapshot of the builder content. 2104 buf = flatcc_builder_finalize_buffer(B, &size); 2105 // use buf 2106 free(buf); 2107 2108 // Optionally reset builder to reuse builder without deallocating 2109 // internal stack and heap. 2110 flatcc_builder_reset(B); 2111 // build next buffer. 2112 // ... 2113 2114 // Cleanup. 2115 flatcc_builder_clear(B); 2116~~~ 2117</div> 2118<div class="language-dart"> 2119~~~{.dart} 2120 final Uint8List buf = builder.finish(orc); 2121~~~ 2122</div> 2123<div class="language-lua"> 2124~~~{.lua} 2125 -- Get the flatbuffer as a string containing the binary data 2126 local bufAsString = builder:Output() 2127~~~ 2128</div> 2129<div class="language-lobster"> 2130~~~{.lobster} 2131 // This must be called after `Finish()`. 2132 let buf = builder.SizedCopy() // Of type `string`. 2133~~~ 2134</div> 2135<div class="language-rust"> 2136~~~{.rs} 2137 // This must be called after `finish()`. 2138 // `finished_data` returns a byte slice. 2139 let buf = builder.finished_data(); // Of type `&[u8]` 2140~~~ 2141</div> 2142<div class="language-swift"> 2143~~~{.swift} 2144 // This must be called after `finish()`. 2145 // `sizedByteArray` returns the finished buf of type [UInt8]. 2146 let buf = builder.sizedByteArray 2147 // or you can use to get an object of type Data 2148 let bufData = ByteBuffer(data: builder.data) 2149~~~ 2150</div> 2151 2152Now you can write the bytes to a file or send them over the network. 2153**Make sure your file mode (or transfer protocol) is set to BINARY, not text.** 2154If you transfer a FlatBuffer in text mode, the buffer will be corrupted, 2155which will lead to hard to find problems when you read the buffer. 2156 2157<div class="language-javascript"> 2158For example, in Node you can simply do: 2159~~~{.js} 2160 writeFileSync('monster.bin', buf, 'binary'); 2161~~~ 2162</div> 2163<div class="language-typescript"> 2164For example, in Node you can simply do: 2165~~~{.ts} 2166 writeFileSync('monster.bin', buf, 'binary'); 2167~~~ 2168</div> 2169 2170#### Reading Orc FlatBuffers 2171 2172Now that we have successfully created an `Orc` FlatBuffer, the monster data can 2173be saved, sent over a network, etc. Let's now adventure into the inverse, and 2174access a FlatBuffer. 2175 2176This section requires the same import/include, namespace, etc. requirements as 2177before: 2178 2179<div class="language-cpp"> 2180~~~{.cpp} 2181 #include "monster_generated.h" // This was generated by `flatc`. 2182 2183 using namespace MyGame::Sample; // Specified in the schema. 2184~~~ 2185</div> 2186<div class="language-java"> 2187~~~{.java} 2188 import MyGame.Sample.*; //The `flatc` generated files. (Monster, Vec3, etc.) 2189 2190 import com.google.flatbuffers.FlatBufferBuilder; 2191~~~ 2192</div> 2193<div class="language-kotlin"> 2194~~~{.kt} 2195 import MyGame.Sample.* //The `flatc` generated files. (Monster, Vec3, etc.) 2196 2197 import com.google.flatbuffers.FlatBufferBuilder 2198~~~ 2199</div> 2200<div class="language-csharp"> 2201~~~{.cs} 2202 using Google.FlatBuffers; 2203 using MyGame.Sample; // The `flatc` generated files. (Monster, Vec3, etc.) 2204~~~ 2205</div> 2206<div class="language-go"> 2207~~~{.go} 2208 import ( 2209 flatbuffers "github.com/google/flatbuffers/go" 2210 sample "MyGame/Sample" 2211 ) 2212~~~ 2213</div> 2214<div class="language-python"> 2215~~~{.py} 2216 import flatbuffers 2217 2218 # Generated by `flatc`. 2219 import MyGame.Sample.Any 2220 import MyGame.Sample.Color 2221 import MyGame.Sample.Monster 2222 import MyGame.Sample.Vec3 2223~~~ 2224</div> 2225<div class="language-javascript"> 2226~~~{.js} 2227 // The following code is an example - use your desired module flavor by transpiling from TS. 2228 var flatbuffers = require('/js/flatbuffers').flatbuffers; 2229 var MyGame = require('./monster_generated').MyGame; // Generated by `flatc`. 2230 2231 //--------------------------------------------------------------------------// 2232 2233 // The following code an example for browser-based HTML/JavaScript. Use the above code 2234 // for JavaScript module loaders (e.g. Node.js). 2235 <script src="../js/flatbuffers.js"></script> 2236 <script src="monster_generated.js"></script> // Generated by `flatc`. 2237~~~ 2238</div> 2239<div class="language-typescript"> 2240~~~{.ts} 2241 // note: import flatbuffers with your desired import method 2242 2243 // note: the `./monster_generated.js` file was previously generated by `flatc` above using the `monster.fbs` schema 2244 import { MyGame } from './monster_generated'; 2245~~~ 2246</div> 2247<div class="language-php"> 2248~~~{.php} 2249 // It is recommended that your use PSR autoload when using FlatBuffers in PHP. 2250 // Here is an example from `SampleBinary.php`: 2251 function __autoload($class_name) { 2252 // The last segment of the class name matches the file name. 2253 $class = substr($class_name, strrpos($class_name, "\\") + 1); 2254 $root_dir = join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)))); // `flatbuffers` root. 2255 2256 // Contains the `*.php` files for the FlatBuffers library and the `flatc` generated files. 2257 $paths = array(join(DIRECTORY_SEPARATOR, array($root_dir, "php")), 2258 join(DIRECTORY_SEPARATOR, array($root_dir, "samples", "MyGame", "Sample"))); 2259 foreach ($paths as $path) { 2260 $file = join(DIRECTORY_SEPARATOR, array($path, $class . ".php")); 2261 if (file_exists($file)) { 2262 require($file); 2263 break; 2264 } 2265 } 2266 } 2267~~~ 2268</div> 2269<div class="language-c"> 2270~~~{.c} 2271 // Only needed if we don't have `#include "monster_builder.h"`. 2272 #include "monster_reader.h" 2273 2274 #undef ns 2275 #define ns(x) FLATBUFFERS_WRAP_NAMESPACE(MyGame_Sample, x) // Specified in the schema. 2276~~~ 2277</div> 2278<div class="language-dart"> 2279~~~{.dart} 2280import 'package:flat_buffers/flat_buffers.dart' as fb; 2281import './monster_my_game.sample_generated.dart' as myGame; 2282~~~ 2283</div> 2284<div class="language-lua"> 2285~~~{.lua} 2286 -- require the flatbuffers module 2287 local flatbuffers = require("flatbuffers") 2288 2289 -- require the generated files from `flatc`. 2290 local color = require("MyGame.Sample.Color") 2291 local equipment = require("MyGame.Sample.Equipment") 2292 local monster = require("MyGame.Sample.Monster") 2293 local vec3 = require("MyGame.Sample.Vec3") 2294 local weapon = require("MyGame.Sample.Weapon") 2295~~~ 2296</div> 2297<div class="language-lobster"> 2298~~~{.lobster} 2299 import from "../lobster/" // Where to find flatbuffers.lobster 2300 import monster_generated 2301~~~ 2302</div> 2303<div class="language-rust"> 2304~~~{.rs} 2305 // import the flatbuffers runtime library 2306 extern crate flatbuffers; 2307 2308 // import the generated code 2309 #[allow(dead_code, unused_imports)] 2310 #[path = "./monster_generated.rs"] 2311 mod monster_generated; 2312 pub use monster_generated::my_game::sample::{root_as_monster, 2313 Color, Equipment, 2314 Monster, MonsterArgs, 2315 Vec3, 2316 Weapon, WeaponArgs}; 2317~~~ 2318</div> 2319 2320Then, assuming you have a buffer of bytes received from disk, 2321network, etc., you can start accessing the buffer like so: 2322 2323**Again, make sure you read the bytes in BINARY mode, otherwise the code below 2324won't work.** 2325 2326<div class="language-cpp"> 2327~~~{.cpp} 2328 uint8_t *buffer_pointer = /* the data you just read */; 2329 2330 // Get a pointer to the root object inside the buffer. 2331 auto monster = GetMonster(buffer_pointer); 2332 2333 // `monster` is of type `Monster *`. 2334 // Note: root object pointers are NOT the same as `buffer_pointer`. 2335 // `GetMonster` is a convenience function that calls `GetRoot<Monster>`, 2336 // the latter is also available for non-root types. 2337~~~ 2338</div> 2339<div class="language-java"> 2340~~~{.java} 2341 byte[] bytes = /* the data you just read */ 2342 java.nio.ByteBuffer buf = java.nio.ByteBuffer.wrap(bytes); 2343 2344 // Get an accessor to the root object inside the buffer. 2345 Monster monster = Monster.getRootAsMonster(buf); 2346~~~ 2347</div> 2348<div class="language-kotlin"> 2349~~~{.kt} 2350 val bytes = /* the data you just read */ 2351 val buf = java.nio.ByteBuffer.wrap(bytes) 2352 2353 // Get an accessor to the root object inside the buffer. 2354 Monster monster = Monster.getRootAsMonster(buf) 2355~~~ 2356</div> 2357<div class="language-csharp"> 2358~~~{.cs} 2359 byte[] bytes = /* the data you just read */ 2360 var buf = new ByteBuffer(bytes); 2361 2362 // Get an accessor to the root object inside the buffer. 2363 var monster = Monster.GetRootAsMonster(buf); 2364~~~ 2365</div> 2366<div class="language-go"> 2367~~~{.go} 2368 var buf []byte = /* the data you just read */ 2369 2370 // Get an accessor to the root object inside the buffer. 2371 monster := sample.GetRootAsMonster(buf, 0) 2372 2373 // Note: We use `0` for the offset here, which is typical for most buffers 2374 // you would read. If you wanted to read from `builder.Bytes` directly, you 2375 // would need to pass in the offset of `builder.Head()`, as the builder 2376 // constructs the buffer backwards, so may not start at offset 0. 2377~~~ 2378</div> 2379<div class="language-python"> 2380~~~{.py} 2381 buf = /* the data you just read, in an object of type "bytearray" */ 2382 2383 // Get an accessor to the root object inside the buffer. 2384 monster = MyGame.Sample.Monster.Monster.GetRootAs(buf, 0) 2385 2386 # Note: We use `0` for the offset here, which is typical for most buffers 2387 # you would read. If you wanted to read from the `builder.Bytes` directly, 2388 # you would need to pass in the offset of `builder.Head()`, as the builder 2389 # constructs the buffer backwards, so may not start at offset 0. 2390~~~ 2391</div> 2392<div class="language-javascript"> 2393~~~{.js} 2394 // the data you just read, as a `Uint8Array` 2395 // Note that the example here uses `readFileSync` from the built-in `fs` module, 2396 // but other methods for accessing the file contents will also work. 2397 var bytes = new Uint8Array(readFileSync('./monsterdata.bin')); 2398 2399 var buf = new flatbuffers.ByteBuffer(bytes); 2400 2401 // Get an accessor to the root object inside the buffer. 2402 var monster = MyGame.Sample.Monster.getRootAsMonster(buf); 2403~~~ 2404</div> 2405<div class="language-typescript"> 2406~~~{.ts} 2407 // the data you just read, as a `Uint8Array`. 2408 // Note that the example here uses `readFileSync` from the built-in `fs` module, 2409 // but other methods for accessing the file contents will also work. 2410 let bytes = new Uint8Array(readFileSync('./monsterdata.bin')); 2411 2412 let buf = new flatbuffers.ByteBuffer(bytes); 2413 2414 // Get an accessor to the root object inside the buffer. 2415 let monster = MyGame.Sample.Monster.getRootAsMonster(buf); 2416~~~ 2417</div> 2418<div class="language-php"> 2419~~~{.php} 2420 $bytes = /* the data you just read, in a string */ 2421 $buf = Google\FlatBuffers\ByteBuffer::wrap($bytes); 2422 2423 // Get an accessor to the root object inside the buffer. 2424 $monster = \MyGame\Sample\Monster::GetRootAsMonster($buf); 2425~~~ 2426</div> 2427<div class="language-c"> 2428~~~{.c} 2429 // Note that we use the `table_t` suffix when reading a table object 2430 // as opposed to the `ref_t` suffix used during the construction of 2431 // the buffer. 2432 ns(Monster_table_t) monster = ns(Monster_as_root(buffer)); 2433 2434 // Note: root object pointers are NOT the same as the `buffer` pointer. 2435~~~ 2436</div> 2437<div class="language-dart"> 2438~~~{.dart} 2439List<int> data = ... // the data, e.g. from file or network 2440// A generated factory constructor that will read the data. 2441myGame.Monster monster = new myGame.Monster(data); 2442~~~ 2443</div> 2444<div class="language-lua"> 2445~~~{.lua} 2446 local bufAsString = -- The data you just read in 2447 2448 -- Convert the string representation into binary array Lua structure 2449 local buf = flatbuffers.binaryArray.New(bufAsString) 2450 2451 -- Get an accessor to the root object insert the buffer 2452 local mon = monster.GetRootAsMonster(buf, 0) 2453~~~ 2454</div> 2455<div class="language-lobster"> 2456~~~{.lobster} 2457 buf = /* the data you just read, in a string */ 2458 2459 // Get an accessor to the root object inside the buffer. 2460 let monster = MyGame_Sample_GetRootAsMonster(buf) 2461~~~ 2462</div> 2463<div class="language-rust"> 2464~~~{.rs} 2465 let buf = /* the data you just read, in a &[u8] */ 2466 2467 // Get an accessor to the root object inside the buffer. 2468 let monster = root_as_monster(buf).unwrap(); 2469~~~ 2470</div> 2471<div class="language-swift"> 2472~~~{.swift} 2473 // create a ByteBuffer(:) from an [UInt8] or Data() 2474 var buf = // Get your data 2475 // Get an accessor to the root object inside the buffer. 2476 let monster: Monster = try! getCheckedRoot(byteBuffer: &byteBuffer) 2477 // let monster: Monster = getRoot(byteBuffer: &byteBuffer) 2478~~~ 2479</div> 2480 2481If you look in the generated files from the schema compiler, you will see it generated 2482accessors for all non-`deprecated` fields. For example: 2483 2484<div class="language-cpp"> 2485~~~{.cpp} 2486 auto hp = monster->hp(); 2487 auto mana = monster->mana(); 2488 auto name = monster->name()->c_str(); 2489~~~ 2490</div> 2491<div class="language-java"> 2492~~~{.java} 2493 short hp = monster.hp(); 2494 short mana = monster.mana(); 2495 String name = monster.name(); 2496~~~ 2497</div> 2498<div class="language-kotlin"> 2499~~~{.kt} 2500 val hp = monster.hp 2501 val mana = monster.mana 2502 val name = monster.name 2503~~~ 2504</div> 2505<div class="language-csharp"> 2506~~~{.cs} 2507 // For C#, unlike most other languages support by FlatBuffers, most values (except for 2508 // vectors and unions) are available as properties instead of accessor methods. 2509 var hp = monster.Hp 2510 var mana = monster.Mana 2511 var name = monster.Name 2512~~~ 2513</div> 2514<div class="language-go"> 2515~~~{.go} 2516 hp := monster.Hp() 2517 mana := monster.Mana() 2518 name := string(monster.Name()) // Note: `monster.Name()` returns a byte[]. 2519~~~ 2520</div> 2521<div class="language-python"> 2522~~~{.py} 2523 hp = monster.Hp() 2524 mana = monster.Mana() 2525 name = monster.Name() 2526~~~ 2527</div> 2528<div class="language-javascript"> 2529~~~{.js} 2530 var hp = monster.hp(); 2531 var mana = monster.mana(); 2532 var name = monster.name(); 2533~~~ 2534</div> 2535<div class="language-typescript"> 2536~~~{.ts} 2537 let hp = monster.hp(); 2538 let mana = monster.mana(); 2539 let name = monster.name(); 2540~~~ 2541</div> 2542<div class="language-php"> 2543~~~{.php} 2544 $hp = $monster->getHp(); 2545 $mana = $monster->getMana(); 2546 $name = monster->getName(); 2547~~~ 2548</div> 2549<div class="language-c"> 2550~~~{.c} 2551 uint16_t hp = ns(Monster_hp(monster)); 2552 uint16_t mana = ns(Monster_mana(monster)); 2553 flatbuffers_string_t name = ns(Monster_name(monster)); 2554~~~ 2555</div> 2556<div class="language-dart"> 2557~~~{.dart} 2558 // For Dart, unlike other languages support by FlatBuffers, most values 2559 // are available as properties instead of accessor methods. 2560 var hp = monster.hp; 2561 var mana = monster.mana; 2562 var name = monster.name; 2563~~~ 2564</div> 2565<div class="language-lua"> 2566~~~{.lua} 2567 local hp = mon:Hp() 2568 local mana = mon:Mana() 2569 local name = mon:Name() 2570~~~ 2571</div> 2572<div class="language-lobster"> 2573~~~{.lobster} 2574 let hp = monster.hp 2575 let mana = monster.mana 2576 let name = monster.name 2577~~~ 2578</div> 2579<div class="language-rust"> 2580~~~{.rs} 2581 // Get and test some scalar types from the FlatBuffer. 2582 let hp = monster.hp(); 2583 let mana = monster.mana(); 2584 let name = monster.name(); 2585~~~ 2586</div> 2587<div class="language-swift"> 2588~~~{.swift} 2589 let hp = monster.hp 2590 let mana = monster.mana 2591 let name = monster.name // returns an optional string 2592~~~ 2593</div> 2594 2595These should hold `300`, `150`, and `"Orc"` respectively. 2596 2597*Note: The default value `150` wasn't stored in `mana`, but we are still able to retrieve it.* 2598 2599To access sub-objects, in the case of our `pos`, which is a `Vec3`: 2600 2601<div class="language-cpp"> 2602~~~{.cpp} 2603 auto pos = monster->pos(); 2604 auto x = pos->x(); 2605 auto y = pos->y(); 2606 auto z = pos->z(); 2607~~~ 2608</div> 2609<div class="language-java"> 2610~~~{.java} 2611 Vec3 pos = monster.pos(); 2612 float x = pos.x(); 2613 float y = pos.y(); 2614 float z = pos.z(); 2615~~~ 2616</div> 2617<div class="language-kotlin"> 2618~~~{.kt} 2619 val pos = monster.pos!! 2620 val x = pos.x 2621 val y = pos.y 2622 val z = pos.z 2623~~~ 2624</div> 2625<div class="language-csharp"> 2626~~~{.cs} 2627 var pos = monster.Pos.Value; 2628 var x = pos.X; 2629 var y = pos.Y; 2630 var z = pos.Z; 2631~~~ 2632</div> 2633<div class="language-go"> 2634~~~{.go} 2635 pos := monster.Pos(nil) 2636 x := pos.X() 2637 y := pos.Y() 2638 z := pos.Z() 2639 2640 // Note: Whenever you access a new object, like in `Pos()`, a new temporary 2641 // accessor object gets created. If your code is very performance sensitive, 2642 // you can pass in a pointer to an existing `Vec3` instead of `nil`. This 2643 // allows you to reuse it across many calls to reduce the amount of object 2644 // allocation/garbage collection. 2645~~~ 2646</div> 2647<div class="language-python"> 2648~~~{.py} 2649 pos = monster.Pos() 2650 x = pos.X() 2651 y = pos.Y() 2652 z = pos.Z() 2653~~~ 2654</div> 2655<div class="language-javascript"> 2656~~~{.js} 2657 var pos = monster.pos(); 2658 var x = pos.x(); 2659 var y = pos.y(); 2660 var z = pos.z(); 2661~~~ 2662</div> 2663<div class="language-typescript"> 2664~~~{.ts} 2665 let pos = monster.pos(); 2666 let x = pos.x(); 2667 let y = pos.y(); 2668 let z = pos.z(); 2669~~~ 2670</div> 2671<div class="language-php"> 2672~~~{.php} 2673 $pos = $monster->getPos(); 2674 $x = $pos->getX(); 2675 $y = $pos->getY(); 2676 $z = $pos->getZ(); 2677~~~ 2678</div> 2679<div class="language-c"> 2680~~~{.c} 2681 ns(Vec3_struct_t) pos = ns(Monster_pos(monster)); 2682 float x = ns(Vec3_x(pos)); 2683 float y = ns(Vec3_y(pos)); 2684 float z = ns(Vec3_z(pos)); 2685~~~ 2686</div> 2687<div class="language-dart"> 2688~~~{.dart} 2689 myGame.Vec3 pos = monster.pos; 2690 double x = pos.x; 2691 double y = pos.y; 2692 double z = pos.z; 2693~~~ 2694</div> 2695<div class="language-lua"> 2696~~~{.lua} 2697 local pos = mon:Pos() 2698 local x = pos:X() 2699 local y = pos:Y() 2700 local z = pos:Z() 2701~~~ 2702</div> 2703<div class="language-lobster"> 2704~~~{.lobster} 2705 let pos = monster.pos 2706 let x = pos.x 2707 let y = pos.y 2708 let z = pos.z 2709~~~ 2710</div> 2711<div class="language-rust"> 2712~~~{.rs} 2713 let pos = monster.pos().unwrap(); 2714 let x = pos.x(); 2715 let y = pos.y(); 2716 let z = pos.z(); 2717~~~ 2718</div> 2719<div class="language-swift"> 2720~~~{.swift} 2721 let pos = monster.pos 2722 let x = pos.x 2723 let y = pos.y 2724 let z = pos.z 2725~~~ 2726</div> 2727 2728`x`, `y`, and `z` will contain `1.0`, `2.0`, and `3.0`, respectively. 2729 2730*Note: Had we not set `pos` during serialization, it would be a `null`-value.* 2731 2732Similarly, we can access elements of the inventory `vector` by indexing it. You 2733can also iterate over the length of the array/vector representing the 2734FlatBuffers `vector`. 2735 2736<div class="language-cpp"> 2737~~~{.cpp} 2738 auto inv = monster->inventory(); // A pointer to a `flatbuffers::Vector<>`. 2739 auto inv_len = inv->size(); 2740 auto third_item = inv->Get(2); 2741~~~ 2742</div> 2743<div class="language-java"> 2744~~~{.java} 2745 int invLength = monster.inventoryLength(); 2746 byte thirdItem = monster.inventory(2); 2747~~~ 2748</div> 2749<div class="language-kotlin"> 2750~~~{.kotlin} 2751 val invLength = monster.inventoryLength 2752 val thirdItem = monster.inventory(2)!! 2753~~~ 2754</div> 2755<div class="language-csharp"> 2756~~~{.cs} 2757 int invLength = monster.InventoryLength; 2758 var thirdItem = monster.Inventory(2); 2759~~~ 2760</div> 2761<div class="language-go"> 2762~~~{.go} 2763 invLength := monster.InventoryLength() 2764 thirdItem := monster.Inventory(2) 2765~~~ 2766</div> 2767<div class="language-python"> 2768~~~{.py} 2769 inv_len = monster.InventoryLength() 2770 third_item = monster.Inventory(2) 2771~~~ 2772</div> 2773<div class="language-javascript"> 2774~~~{.js} 2775 var invLength = monster.inventoryLength(); 2776 var thirdItem = monster.inventory(2); 2777~~~ 2778</div> 2779<div class="language-typescript"> 2780~~~{.ts} 2781 let invLength = monster.inventoryLength(); 2782 let thirdItem = monster.inventory(2); 2783~~~ 2784</div> 2785<div class="language-php"> 2786~~~{.php} 2787 $inv_len = $monster->getInventoryLength(); 2788 $third_item = $monster->getInventory(2); 2789~~~ 2790</div> 2791<div class="language-c"> 2792~~~{.c} 2793 // If `inv` hasn't been set, it will be null. It is valid get 2794 // the length of null which will be 0, useful for iteration. 2795 flatbuffers_uint8_vec_t inv = ns(Monster_inventory(monster)); 2796 size_t inv_len = flatbuffers_uint8_vec_len(inv); 2797~~~ 2798</div> 2799<div class="language-dart"> 2800~~~{.dart} 2801 int invLength = monster.inventory.length; 2802 var thirdItem = monster.inventory[2]; 2803~~~ 2804</div> 2805<div class="language-lua"> 2806~~~{.lua} 2807 local invLength = mon:InventoryLength() 2808 local thirdItem = mon:Inventory(3) -- Lua is 1-based 2809~~~ 2810</div> 2811<div class="language-lobster"> 2812~~~{.lobster} 2813 let inv_len = monster.inventory_length 2814 let third_item = monster.inventory(2) 2815~~~ 2816</div> 2817<div class="language-rust"> 2818~~~{.rs} 2819 // Get and test an element from the `inventory` FlatBuffer's `vector`. 2820 let inv = monster.inventory().unwrap(); 2821 2822 // Note that this vector is returned as a slice, because direct access for 2823 // this type, a `u8` vector, is safe on all platforms: 2824 let third_item = inv[2]; 2825~~~ 2826</div> 2827<div class="language-swift"> 2828~~~{.swift} 2829 // Get a the count of objects in the vector 2830 let count = monster.inventoryCount 2831 2832 // get item at index 4 2833 let object = monster.inventory(at: 4) 2834 2835 // or you can fetch the entire array 2836 let inv = monster.inventory 2837 // inv[4] should equal object 2838~~~ 2839</div> 2840 2841For `vector`s of `table`s, you can access the elements like any other vector, 2842except you need to handle the result as a FlatBuffer `table`: 2843 2844<div class="language-cpp"> 2845~~~{.cpp} 2846 auto weapons = monster->weapons(); // A pointer to a `flatbuffers::Vector<>`. 2847 auto weapon_len = weapons->size(); 2848 auto second_weapon_name = weapons->Get(1)->name()->str(); 2849 auto second_weapon_damage = weapons->Get(1)->damage() 2850~~~ 2851</div> 2852<div class="language-java"> 2853~~~{.java} 2854 int weaponsLength = monster.weaponsLength(); 2855 String secondWeaponName = monster.weapons(1).name(); 2856 short secondWeaponDamage = monster.weapons(1).damage(); 2857~~~ 2858</div> 2859<div class="language-kotlin"> 2860~~~{.kt} 2861 val weaponsLength = monster.weaponsLength 2862 val secondWeaponName = monster.weapons(1)!!.name 2863 val secondWeaponDamage = monster.weapons(1)!!.damage 2864~~~ 2865</div> 2866<div class="language-csharp"> 2867~~~{.cs} 2868 int weaponsLength = monster.WeaponsLength; 2869 var secondWeaponName = monster.Weapons(1).Name; 2870 var secondWeaponDamage = monster.Weapons(1).Damage; 2871~~~ 2872</div> 2873<div class="language-go"> 2874~~~{.go} 2875 weaponLength := monster.WeaponsLength() 2876 weapon := new(sample.Weapon) // We need a `sample.Weapon` to pass into `monster.Weapons()` 2877 // to capture the output of the function. 2878 if monster.Weapons(weapon, 1) { 2879 secondWeaponName := weapon.Name() 2880 secondWeaponDamage := weapon.Damage() 2881 } 2882~~~ 2883</div> 2884<div class="language-python"> 2885~~~{.py} 2886 weapons_length = monster.WeaponsLength() 2887 second_weapon_name = monster.Weapons(1).Name() 2888 second_weapon_damage = monster.Weapons(1).Damage() 2889~~~ 2890</div> 2891<div class="language-javascript"> 2892~~~{.js} 2893 var weaponsLength = monster.weaponsLength(); 2894 var secondWeaponName = monster.weapons(1).name(); 2895 var secondWeaponDamage = monster.weapons(1).damage(); 2896~~~ 2897</div> 2898<div class="language-typescript"> 2899~~~{.ts} 2900 let weaponsLength = monster.weaponsLength(); 2901 let secondWeaponName = monster.weapons(1).name(); 2902 let secondWeaponDamage = monster.weapons(1).damage(); 2903~~~ 2904</div> 2905<div class="language-php"> 2906~~~{.php} 2907 $weapons_len = $monster->getWeaponsLength(); 2908 $second_weapon_name = $monster->getWeapons(1)->getName(); 2909 $second_weapon_damage = $monster->getWeapons(1)->getDamage(); 2910~~~ 2911</div> 2912<div class="language-c"> 2913~~~{.c} 2914 ns(Weapon_vec_t) weapons = ns(Monster_weapons(monster)); 2915 size_t weapons_len = ns(Weapon_vec_len(weapons)); 2916 // We can use `const char *` instead of `flatbuffers_string_t`. 2917 const char *second_weapon_name = ns(Weapon_name(ns(Weapon_vec_at(weapons, 1)))); 2918 uint16_t second_weapon_damage = ns(Weapon_damage(ns(Weapon_vec_at(weapons, 1)))); 2919~~~ 2920</div> 2921<div class="language-dart"> 2922~~~{.dart} 2923 int weaponsLength = monster.weapons.length; 2924 var secondWeaponName = monster.weapons[1].name; 2925 var secondWeaponDamage = monster.Weapons[1].damage; 2926~~~ 2927</div> 2928<div class="language-lua"> 2929~~~{.lua} 2930 local weaponsLength = mon:WeaponsLength() 2931 local secondWeaponName = mon:Weapon(2):Name() 2932 local secondWeaponDamage = mon:Weapon(2):Damage() 2933~~~ 2934</div> 2935<div class="language-lobster"> 2936~~~{.lobster} 2937 let weapons_length = monster.weapons_length 2938 let second_weapon_name = monster.weapons(1).name 2939 let second_weapon_damage = monster.weapons(1).damage 2940~~~ 2941</div> 2942<div class="language-rust"> 2943~~~{.rs} 2944 // Get and test the `weapons` FlatBuffers's `vector`. 2945 let weps = monster.weapons().unwrap(); 2946 let weps_len = weps.len(); 2947 2948 let wep2 = weps.get(1); 2949 let second_weapon_name = wep2.name(); 2950 let second_weapon_damage = wep2.damage(); 2951~~~ 2952</div> 2953<div class="language-swift"> 2954~~~{.swift} 2955 // Get the count of weapon objects 2956 let wepsCount = monster.weaponsCount 2957 2958 let weapon2 = monster.weapons(at: 1) 2959 let weaponName = weapon2.name 2960 let weaponDmg = weapon2.damage 2961~~~ 2962</div> 2963 2964Last, we can access our `Equipped` FlatBuffer `union`. Just like when we created 2965the `union`, we need to get both parts of the `union`: the type and the data. 2966 2967We can access the type to dynamically cast the data as needed (since the 2968`union` only stores a FlatBuffer `table`). 2969 2970<div class="language-cpp"> 2971~~~{.cpp} 2972 auto union_type = monster->equipped_type(); 2973 2974 if (union_type == Equipment_Weapon) { 2975 auto weapon = static_cast<const Weapon*>(monster->equipped()); // Requires `static_cast` 2976 // to type `const Weapon*`. 2977 2978 auto weapon_name = weapon->name()->str(); // "Axe" 2979 auto weapon_damage = weapon->damage(); // 5 2980 } 2981~~~ 2982</div> 2983<div class="language-java"> 2984~~~{.java} 2985 int unionType = monster.EquippedType(); 2986 2987 if (unionType == Equipment.Weapon) { 2988 Weapon weapon = (Weapon)monster.equipped(new Weapon()); // Requires explicit cast 2989 // to `Weapon`. 2990 2991 String weaponName = weapon.name(); // "Axe" 2992 short weaponDamage = weapon.damage(); // 5 2993 } 2994~~~ 2995</div> 2996<div class="language-kotlin"> 2997~~~{.kt} 2998 val unionType = monster.EquippedType 2999 3000 if (unionType == Equipment.Weapon) { 3001 val weapon = monster.equipped(Weapon()) as Weapon // Requires explicit cast 3002 // to `Weapon`. 3003 3004 val weaponName = weapon.name // "Axe" 3005 val weaponDamage = weapon.damage // 5 3006 } 3007~~~ 3008</div> 3009<div class="language-csharp"> 3010~~~{.cs} 3011 var unionType = monster.EquippedType; 3012 3013 if (unionType == Equipment.Weapon) { 3014 var weapon = monster.Equipped<Weapon>().Value; 3015 3016 var weaponName = weapon.Name; // "Axe" 3017 var weaponDamage = weapon.Damage; // 5 3018 } 3019~~~ 3020</div> 3021<div class="language-go"> 3022~~~{.go} 3023 // We need a `flatbuffers.Table` to capture the output of the 3024 // `monster.Equipped()` function. 3025 unionTable := new(flatbuffers.Table) 3026 3027 if monster.Equipped(unionTable) { 3028 unionType := monster.EquippedType() 3029 3030 if unionType == sample.EquipmentWeapon { 3031 // Create a `sample.Weapon` object that can be initialized with the contents 3032 // of the `flatbuffers.Table` (`unionTable`), which was populated by 3033 // `monster.Equipped()`. 3034 unionWeapon = new(sample.Weapon) 3035 unionWeapon.Init(unionTable.Bytes, unionTable.Pos) 3036 3037 weaponName = unionWeapon.Name() 3038 weaponDamage = unionWeapon.Damage() 3039 } 3040 } 3041~~~ 3042</div> 3043<div class="language-python"> 3044~~~{.py} 3045 union_type = monster.EquippedType() 3046 3047 if union_type == MyGame.Sample.Equipment.Equipment().Weapon: 3048 # `monster.Equipped()` returns a `flatbuffers.Table`, which can be used to 3049 # initialize a `MyGame.Sample.Weapon.Weapon()`. 3050 union_weapon = MyGame.Sample.Weapon.Weapon() 3051 union_weapon.Init(monster.Equipped().Bytes, monster.Equipped().Pos) 3052 3053 weapon_name = union_weapon.Name() // 'Axe' 3054 weapon_damage = union_weapon.Damage() // 5 3055~~~ 3056</div> 3057<div class="language-javascript"> 3058~~~{.js} 3059 var unionType = monster.equippedType(); 3060 3061 if (unionType == MyGame.Sample.Equipment.Weapon) { 3062 var weaponName = monster.equipped(new MyGame.Sample.Weapon()).name(); // 'Axe' 3063 var weaponDamage = monster.equipped(new MyGame.Sample.Weapon()).damage(); // 5 3064 } 3065~~~ 3066</div> 3067<div class="language-typescript"> 3068~~~{.ts} 3069 let unionType = monster.equippedType(); 3070 3071 if (unionType == MyGame.Sample.Equipment.Weapon) { 3072 let weaponName = monster.equipped(new MyGame.Sample.Weapon()).name(); // 'Axe' 3073 let weaponDamage = monster.equipped(new MyGame.Sample.Weapon()).damage(); // 5 3074 } 3075~~~ 3076</div> 3077<div class="language-php"> 3078~~~{.php} 3079 $union_type = $monster->getEquippedType(); 3080 3081 if ($union_type == \MyGame\Sample\Equipment::Weapon) { 3082 $weapon_name = $monster->getEquipped(new \MyGame\Sample\Weapon())->getName(); // "Axe" 3083 $weapon_damage = $monster->getEquipped(new \MyGame\Sample\Weapon())->getDamage(); // 5 3084 } 3085~~~ 3086</div> 3087<div class="language-c"> 3088~~~{.c} 3089 // Access union type field. 3090 if (ns(Monster_equipped_type(monster)) == ns(Equipment_Weapon)) { 3091 // Cast to appropriate type: 3092 // C allows for silent void pointer assignment, so we need no explicit cast. 3093 ns(Weapon_table_t) weapon = ns(Monster_equipped(monster)); 3094 const char *weapon_name = ns(Weapon_name(weapon)); // "Axe" 3095 uint16_t weapon_damage = ns(Weapon_damage(weapon)); // 5 3096 } 3097~~~ 3098</div> 3099<div class="language-dart"> 3100~~~{.dart} 3101 var unionType = monster.equippedType.value; 3102 3103 if (unionType == myGame.EquipmentTypeId.Weapon.value) { 3104 myGame.Weapon weapon = mon.equipped as myGame.Weapon; 3105 3106 var weaponName = weapon.name; // "Axe" 3107 var weaponDamage = weapon.damage; // 5 3108 } 3109~~~ 3110</div> 3111<div class="language-lua"> 3112~~~{.lua} 3113 local unionType = mon:EquippedType() 3114 3115 if unionType == equipment.Weapon then 3116 local unionWeapon = weapon.New() 3117 unionWeapon:Init(mon:Equipped().bytes, mon:Equipped().pos) 3118 3119 local weaponName = unionWeapon:Name() -- 'Axe' 3120 local weaponDamage = unionWeapon:Damage() -- 5 3121 end 3122~~~ 3123</div> 3124<div class="language-lobster"> 3125~~~{.lobster} 3126 union_type = monster.equipped_type 3127 3128 if union_type == MyGame_Sample_Equipment_Weapon: 3129 // `monster.equipped_as_Weapon` returns a FlatBuffer handle much like normal table fields, 3130 // but this is only valid to call if we already know it is the correct type. 3131 let union_weapon = monster.equipped_as_Weapon 3132 3133 let weapon_name = union_weapon.name // "Axe" 3134 let weapon_damage = union_weapon.damage // 5 3135~~~ 3136</div> 3137<div class="language-rust"> 3138~~~{.rs} 3139 // Get and test the `Equipment` union (`equipped` field). 3140 // `equipped_as_weapon` returns a FlatBuffer handle much like normal table 3141 // fields, but this will return `None` if the union is not actually of that 3142 // type. 3143 if monster.equipped_type() == Equipment::Weapon { 3144 let equipped = monster.equipped_as_weapon().unwrap(); 3145 let weapon_name = equipped.name(); 3146 let weapon_damage = equipped.damage(); 3147~~~ 3148</div> 3149<div class="language-swift"> 3150~~~{.swift} 3151 // Get and check if the monster has an equipped item 3152 if monster.equippedType == .weapon { 3153 let _weapon = monster.equipped(type: Weapon.self) 3154 let name = _weapon.name // should return "Axe" 3155 let dmg = _weapon.damage // should return 5 3156 } 3157~~~ 3158</div> 3159 3160## Mutating FlatBuffers 3161 3162As you saw above, typically once you have created a FlatBuffer, it is read-only 3163from that moment on. There are, however, cases where you have just received a 3164FlatBuffer, and you'd like to modify something about it before sending it on to 3165another recipient. With the above functionality, you'd have to generate an 3166entirely new FlatBuffer, while tracking what you modified in your own data 3167structures. This is inconvenient. 3168 3169For this reason FlatBuffers can also be mutated in-place. While this is great 3170for making small fixes to an existing buffer, you generally want to create 3171buffers from scratch whenever possible, since it is much more efficient and the 3172API is much more general purpose. 3173 3174To get non-const accessors, invoke `flatc` with `--gen-mutable`. 3175 3176Similar to how we read fields using the accessors above, we can now use the 3177mutators like so: 3178 3179<div class="language-cpp"> 3180~~~{.cpp} 3181 auto monster = GetMutableMonster(buffer_pointer); // non-const 3182 monster->mutate_hp(10); // Set the table `hp` field. 3183 monster->mutable_pos()->mutate_z(4); // Set struct field. 3184 monster->mutable_inventory()->Mutate(0, 1); // Set vector element. 3185~~~ 3186</div> 3187<div class="language-java"> 3188~~~{.java} 3189 Monster monster = Monster.getRootAsMonster(buf); 3190 monster.mutateHp(10); // Set table field. 3191 monster.pos().mutateZ(4); // Set struct field. 3192 monster.mutateInventory(0, 1); // Set vector element. 3193~~~ 3194</div> 3195<div class="language-kotlin"> 3196~~~{.kt} 3197 val monster = Monster.getRootAsMonster(buf) 3198 monster.mutateHp(10) // Set table field. 3199 monster.pos!!.mutateZ(4) // Set struct field. 3200 monster.mutateInventory(0, 1) // Set vector element. 3201~~~ 3202</div> 3203<div class="language-csharp"> 3204~~~{.cs} 3205 var monster = Monster.GetRootAsMonster(buf); 3206 monster.MutateHp(10); // Set table field. 3207 monster.Pos.MutateZ(4); // Set struct field. 3208 monster.MutateInventory(0, 1); // Set vector element. 3209~~~ 3210</div> 3211<div class="language-go"> 3212~~~{.go} 3213 <API for mutating FlatBuffers is not yet available in Go.> 3214~~~ 3215</div> 3216<div class="language-python"> 3217~~~{.py} 3218 <API for mutating FlatBuffers is not yet available in Python.> 3219~~~ 3220</div> 3221<div class="language-javascript"> 3222~~~{.js} 3223 <API for mutating FlatBuffers is not yet supported in JavaScript.> 3224~~~ 3225</div> 3226<div class="language-typescript"> 3227~~~{.ts} 3228 <API for mutating FlatBuffers is not yet supported in TypeScript.> 3229~~~ 3230</div> 3231<div class="language-php"> 3232~~~{.php} 3233 <API for mutating FlatBuffers is not yet supported in PHP.> 3234~~~ 3235</div> 3236<div class="language-c"> 3237~~~{.c} 3238 <API for in-place mutating FlatBuffers will not be supported in C 3239 (except in-place vector sorting is possible).> 3240~~~ 3241</div> 3242<div class="language-dart"> 3243~~~{.dart} 3244 <API for mutating FlatBuffers not yet available in Dart.> 3245~~~ 3246</div> 3247<div class="language-lua"> 3248~~~{.lua} 3249 <API for mutating FlatBuffers is not yet available in Lua.> 3250~~~ 3251</div> 3252<div class="language-lobster"> 3253~~~{.lobster} 3254 <API for mutating FlatBuffers is not yet available in Lobster.> 3255~~~ 3256</div> 3257<div class="language-rust"> 3258~~~{.rs} 3259 <API for mutating FlatBuffers is not yet available in Rust.> 3260~~~ 3261</div> 3262<div class="language-swift"> 3263~~~{.swift} 3264 let monster = Monster.getRootAsMonster(bb: ByteBuffer(bytes: buf)) 3265 monster.mutate(hp: 10) // mutates a value in a table 3266 /// to mutate structs in swift you have to use the mutable accessors 3267 monster.mutablePos.mutate(z: 4) // mutates a value in a struct 3268 monster.mutate(inventory: 6, at index: 0) // mutates a value in an Scalar array 3269~~~ 3270</div> 3271 3272We use the somewhat verbose term `mutate` instead of `set` to indicate that this 3273is a special use case, not to be confused with the default way of constructing 3274FlatBuffer data. 3275 3276After the above mutations, you can send on the FlatBuffer to a new recipient 3277without any further work! 3278 3279Note that any `mutate` functions on a table will return a boolean, which is 3280`false` if the field we're trying to set is not present in the buffer. Fields 3281are not present if they weren't set, or even if they happen to be equal to 3282the default value. For example, in the creation code above, the `mana` 3283field is equal to `150`, which is the default value, so it was never stored in 3284the buffer. Trying to call the corresponding `mutate` method for `mana` on such 3285data will return `false`, and the value won't actually be modified! 3286 3287One way to solve this is to call `ForceDefaults` on a FlatBufferBuilder to 3288force all fields you set to actually be written. This, of course, increases the 3289size of the buffer somewhat, but this may be acceptable for a mutable buffer. 3290 3291If this is not sufficient, other ways of mutating FlatBuffers may be supported 3292in your language through an object based API (`--gen-object-api`) or reflection. 3293See the individual language documents for support. 3294 3295## Using `flatc` as a JSON Conversion Tool 3296 3297If you are working with C, C++, or Lobster, you can parse JSON at runtime. 3298If your language does not support JSON at the moment, `flatc` may provide an 3299alternative. Using `flatc` is often the preferred method, as it doesn't require you to 3300add any new code to your program. It is also efficient, since you can ship with 3301the binary data. The drawback is that it requires an extra step for your 3302users/developers to perform (although it may be able to be automated 3303as part of your compilation). 3304 3305#### JSON to binary representation 3306 3307Let's say you have a JSON file that describes your monster. In this example, 3308we will use the file `flatbuffers/samples/monsterdata.json`. 3309 3310Here are the contents of the file: 3311 3312~~~{.json} 3313{ 3314 "pos": { 3315 "x": 1.0, 3316 "y": 2.0, 3317 "z": 3.0 3318 }, 3319 "hp": 300, 3320 "name": "Orc", 3321 "weapons": [ 3322 { 3323 "name": "axe", 3324 "damage": 100 3325 }, 3326 { 3327 "name": "bow", 3328 "damage": 90 3329 } 3330 ], 3331 "equipped_type": "Weapon", 3332 "equipped": { 3333 "name": "bow", 3334 "damage": 90 3335 } 3336} 3337~~~ 3338 3339You can run this file through the `flatc` compiler with the `-b` flag and 3340our `monster.fbs` schema to produce a FlatBuffer binary file. 3341 3342~~~{.sh} 3343./../flatc --binary monster.fbs monsterdata.json 3344~~~ 3345 3346The output of this will be a file `monsterdata.bin`, which will contain the 3347FlatBuffer binary representation of the contents from our `.json` file. 3348 3349<div class="language-cpp"> 3350*Note: If you're working in C++, you can also parse JSON at runtime. See the 3351[Use in C++](@ref flatbuffers_guide_use_cpp) section of the Programmer's 3352Guide for more information.* 3353</div> 3354<div class="language-c"> 3355*Note: If you're working in C, the `flatcc --json` (not `flatc`) 3356compiler will generate schema specific high performance json parsers and 3357printers that you can compile and use at runtime. The `flatc` compiler (not 3358`flatcc`) on the other hand, is still useful for general offline json to 3359flatbuffer conversion from a given schema. There are no current plans 3360for `flatcc` to support this.* 3361</div> 3362<div class="language-lobster"> 3363*Note: If you're working in Lobster, you can also parse JSON at runtime. See the 3364[Use in Lobster](@ref flatbuffers_guide_use_lobster) section of the Programmer's 3365Guide for more information.* 3366</div> 3367 3368#### FlatBuffer binary to JSON 3369 3370Converting from a FlatBuffer binary representation to JSON is supported as well: 3371~~~{.sh} 3372./../flatc --json --raw-binary monster.fbs -- monsterdata.bin 3373~~~ 3374This will convert `monsterdata.bin` back to its original JSON representation. 3375You need to pass the corresponding FlatBuffers schema so that flatc knows how to 3376interpret the binary buffer. Since `monster.fbs` does not specify an explicit 3377`file_identifier` for binary buffers, `flatc` needs to be forced into reading 3378the `.bin` file using the `--raw-binary` option. 3379 3380The FlatBuffer binary representation does not explicitly encode default values, 3381therefore they are not present in the resulting JSON unless you specify 3382`--defaults-json`. 3383 3384If you intend to process the JSON with other tools, you may consider switching 3385on `--strict-json` so that identifiers are quoted properly. 3386 3387*Note: The resulting JSON file is not necessarily identical with the original JSON. 3388If the binary representation contains floating point numbers, floats and doubles 3389are rounded to 6 and 12 digits, respectively, in order to represent them as 3390decimals in the JSON document.* 3391 3392## Advanced Features for Each Language 3393 3394### Vector of Unions 3395 3396Some languages support storing unions directly in a vector. 3397 3398~~~ 3399// File found in tests/union_vector/union_vector.fbs 3400namespace Example.VectorOfUnions; 3401 3402// Demonstrates the ability to have vectors of unions, and also to 3403// store structs and strings in unions. 3404 3405table Attacker { 3406 sword_attack_damage: int; 3407} 3408 3409struct Rapunzel { 3410 hair_length: int; 3411} 3412 3413struct BookReader { 3414 books_read: int; 3415} 3416 3417union Character { 3418 MuLan: Attacker, // Can have name be different from type. 3419 Rapunzel, // Or just both the same, as before. 3420 Belle: BookReader, 3421 BookFan: BookReader, 3422 Other: string, 3423 Unused: string 3424} 3425 3426table Movie { 3427 main_character: Character; 3428 characters: [Character]; 3429} 3430~~~ 3431 3432#### Creating 3433 3434Analagously to how a union adds two fields to a table a vector of unions creates two different vectors: 3435one for the union data and one for the data types. 3436 3437<div class="language-cpp"> 3438C++ supports vectors of unions, but it isn't currently documented. 3439</div> 3440<div class="language-typescript"> 3441Typescript supports vectors of unions, but it isn't currently documented. 3442</div> 3443<div class="language-php"> 3444PHP supports vectors of unions, but it isn't currently documented. 3445</div> 3446<div class="language-java"> 3447Java supports vectors of unions, but it isn't currently documented. 3448</div> 3449<div class="language-csharp"> 3450~~~{.cs} 3451using Google.FlatBuffers; 3452using Example.VectorOfUnions; 3453 3454var fbb = new FlatBufferBuilder(100); 3455 3456var characterTypes = new[] 3457{ 3458 Character.MuLan, 3459 Character.Belle, 3460 Character.Other, 3461}; 3462var characterTypesOffset = Movie.CreateCharactersTypeVector(fbb, characterTypes); 3463 3464var characters = new[] 3465{ 3466 Attacker.CreateAttacker(fbb, 10).Value, 3467 BookReader.CreateBookReader(fbb, 20).Value, 3468 fbb.CreateSharedString("Chip").Value, 3469}; 3470var charactersOffset = Movie.CreateCharactersVector(fbb, characters); 3471 3472var movieOffset = Movie.CreateMovie( 3473 fbb, 3474 Character.Rapunzel, 3475 rapunzel, 3476 characterTypesOffset, 3477 charactersOffset); 3478Movie.FinishMovieBuffer(fbb, movieOffset); 3479~~~ 3480</div> 3481<div class="language-kotlin"> 3482Kotlin supports vectors of unions, but it isn't currently documented. 3483</div> 3484<div class="language-swift"> 3485Swift supports vectors of unions, but it isn't currently documented. 3486</div> 3487 3488#### Reading 3489<div class="language-csharp"> 3490~~~{.cs} 3491var movie = Movie.GetRootAsMovie(fbb.DataBuffer); 3492 3493for (var i = 0; i <= movie.CharactersLength; i++) 3494{ 3495 if (movie.CharactersType(i) == Character.MuLan) 3496 { 3497 var mulanSwordDamage = movie.Characters<Attacker>(i).Value.SwordAttackDamage; 3498 } 3499 else if (movie.CharactersType(i) == Character.Belle) 3500 { 3501 var belleBooksRead = movie.Characters<BookReader>(i).Value.BooksRead; 3502 } 3503 else if (movie.CharactersType(i) == Character.Other) 3504 { 3505 var otherStr = movie.CharactersAsString(i); 3506 } 3507} 3508~~~ 3509</div> 3510 3511### Further Reading 3512 3513Each language has a dedicated `Use in XXX` page in the Programmer's Guide 3514to cover the nuances of FlatBuffers in that language. 3515 3516For your chosen language, see: 3517 3518<div class="language-cpp"> 3519[Use in C++](@ref flatbuffers_guide_use_cpp) 3520</div> 3521<div class="language-java"> 3522[Use in Java](@ref flatbuffers_guide_use_java) 3523</div> 3524<div class="language-kotlin"> 3525[Use in Kotlin](@ref flatbuffers_guide_use_kotlin) 3526</div> 3527<div class="language-csharp"> 3528[Use in C#](@ref flatbuffers_guide_use_c-sharp) 3529</div> 3530<div class="language-go"> 3531[Use in Go](@ref flatbuffers_guide_use_go) 3532</div> 3533<div class="language-python"> 3534[Use in Python](@ref flatbuffers_guide_use_python) 3535</div> 3536<div class="language-javascript"> 3537[Use in JavaScript](@ref flatbuffers_guide_use_javascript) 3538</div> 3539<div class="language-typescript"> 3540[Use in TypeScript](@ref flatbuffers_guide_use_typescript) 3541</div> 3542<div class="language-php"> 3543[Use in PHP](@ref flatbuffers_guide_use_php) 3544</div> 3545<div class="language-c"> 3546[Use in C](@ref flatbuffers_guide_use_c) 3547</div> 3548<div class="language-dart"> 3549[Use in Dart](@ref flatbuffers_guide_use_dart) 3550</div> 3551<div class="language-lua"> 3552[Use in Lua](@ref flatbuffers_guide_use_lua) 3553</div> 3554<div class="language-lobster"> 3555[Use in Lobster](@ref flatbuffers_guide_use_lobster) 3556</div> 3557<div class="language-rust"> 3558[Use in Rust](@ref flatbuffers_guide_use_rust) 3559</div> 3560<div class="language-swift"> 3561[Use in Swift](@ref flatbuffers_guide_use_swift) 3562</div> 3563<br> 3564