| Use in Dart {#flatbuffers_guide_use_dart} | |
| =========== | |
| ## Before you get started | |
| Before diving into the FlatBuffers usage in Dart, it should be noted that | |
| the [Tutorial](@ref flatbuffers_guide_tutorial) page has a complete guide | |
| to general FlatBuffers usage in all of the supported languages (including Dart). | |
| This page is designed to cover the nuances of FlatBuffers usage, specific to | |
| Dart. | |
| You should also have read the [Building](@ref flatbuffers_guide_building) | |
| documentation to build `flatc` and should be familiar with | |
| [Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler) and | |
| [Writing a schema](@ref flatbuffers_guide_writing_schema). | |
| ## FlatBuffers Dart library code location | |
| The code for the FlatBuffers Dart library can be found at | |
| `flatbuffers/dart`. You can browse the library code on the [FlatBuffers | |
| GitHub page](https://github.com/google/flatbuffers/tree/master/dart). | |
| ## Testing the FlatBuffers Dart library | |
| The code to test the Dart library can be found at `flatbuffers/tests`. | |
| The test code itself is located in [dart_test.dart](https://github.com/google/ | |
| flatbuffers/blob/master/tests/dart_test.dart). | |
| To run the tests, use the [DartTest.sh](https://github.com/google/flatbuffers/ | |
| blob/master/tests/DartTest.sh) shell script. | |
| *Note: The shell script requires the [Dart SDK](https://www.dartlang.org/tools/sdk) | |
| to be installed.* | |
| ## Using the FlatBuffers Dart library | |
| *Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth | |
| example of how to use FlatBuffers in Dart.* | |
| FlatBuffers supports reading and writing binary FlatBuffers in Dart. | |
| To use FlatBuffers in your own code, first generate Dart classes from your | |
| schema with the `--dart` option to `flatc`. Then you can include both FlatBuffers | |
| and the generated code to read or write a FlatBuffer. | |
| For example, here is how you would read a FlatBuffer binary file in Dart: First, | |
| include the library and generated code. Then read a FlatBuffer binary file into | |
| a `List<int>`, which you pass to the factory constructor for `Monster`: | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.dart} | |
| import 'dart:io' as io; | |
| import 'package:flat_buffers/flat_buffers.dart' as fb; | |
| import './monster_my_game.sample_generated.dart' as myGame; | |
| List<int> data = await new io.File('monster.dat').readAsBytes(); | |
| var monster = new myGame.Monster(data); | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| Now you can access values like this: | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.dart} | |
| var hp = monster.hp; | |
| var pos = monster.pos; | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| ## Differences from the Dart SDK Front End flat_buffers | |
| The work in this repository is signfiicantly based on the implementation used | |
| internally by the Dart SDK in the front end/analyzer package. Several | |
| significant changes have been made. | |
| 1. Support for packed boolean lists has been removed. This is not standard | |
| in other implementations and is not compatible with them. Do note that, | |
| like in the JavaScript implementation, __null values in boolean lists | |
| will be treated as false__. It is also still entirely possible to pack data | |
| in a single scalar field, but that would have to be done on the application | |
| side. | |
| 2. The SDK implementation supports enums with regular Dart enums, which | |
| works if enums are always indexed at 1; however, FlatBuffers does not | |
| require that. This implementation uses specialized enum-like classes to | |
| ensure proper mapping from FlatBuffers to Dart and other platforms. | |
| 3. The SDK implementation does not appear to support FlatBuffer structs or | |
| vectors of structs - it treated everything as a built-in scalar or a table. | |
| This implementation treats structs in a way that is compatible with other | |
| non-Dart implementations, and properly handles vectors of structs. Many of | |
| the methods prefixed with 'low' have been prepurposed to support this. | |
| 4. The SDK implementation treats int64 and uint64 as float64s. This | |
| implementation does not. This may cause problems with JavaScript | |
| compatibility - however, it should be possible to use the JavaScript | |
| implementation, or to do a customized implementation that treats all 64 bit | |
| numbers as floats. Supporting the Dart VM and Flutter was a more important | |
| goal of this implementation. Support for 16 bit integers was also added. | |
| 5. The code generation in this offers an "ObjectBuilder", which generates code | |
| very similar to the SDK classes that consume FlatBuffers, as well as Builder | |
| classes, which produces code which more closely resembles the builders in | |
| other languages. The ObjectBuilder classes are easier to use, at the cost of | |
| additional references allocated. | |
| ## Text Parsing | |
| There currently is no support for parsing text (Schema's and JSON) directly | |
| from Dart, though you could use the C++ parser through Dart Native Extensions. | |
| Please see the C++ documentation for more on text parsing (note that this is | |
| not currently an option in Flutter - follow [this issue](https://github.com/flutter/flutter/issues/7053) | |
| for the latest). | |
| ## Object based API | |
| FlatBuffers is all about memory efficiency, which is why its base API is written | |
| around using as little as possible of it. This does make the API clumsier | |
| (requiring pre-order construction of all data, and making mutation harder). | |
| For times when efficiency is less important a more convenient object based API | |
| can be used (through `--gen-object-api`) that is able to unpack & pack a FlatBuffer | |
| into objects and lists, allowing for convenient construction, access and mutation. | |
| To use: | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.dart} | |
| // Deserialize from buffer into object. | |
| MonsterT monster = Monster(flatbuffer).unpack(); | |
| // Update object directly like a Dart class instance. | |
| print(monster.Name); | |
| monster.Name = "Bob"; // Change the name. | |
| // Serialize into new flatbuffer. | |
| final fbb = Builder(); | |
| fbb.Finish(monster.pack(fbb)); | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |