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