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