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