Austin Schuh | e89fa2d | 2019-08-14 20:24:23 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2018 Dan Field. All rights reserved. |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | import 'package:flat_buffers/flat_buffers.dart' as fb; |
| 18 | import './monster_my_game.sample_generated.dart' as myGame; |
| 19 | |
| 20 | // Example how to use FlatBuffers to create and read binary buffers. |
| 21 | |
| 22 | void main() { |
| 23 | builderTest(); |
| 24 | objectBuilderTest(); |
| 25 | } |
| 26 | |
| 27 | void builderTest() { |
| 28 | final builder = new fb.Builder(initialSize: 1024); |
| 29 | final int weaponOneName = builder.writeString("Sword"); |
| 30 | final int weaponOneDamage = 3; |
| 31 | |
| 32 | final int weaponTwoName = builder.writeString("Axe"); |
| 33 | final int weaponTwoDamage = 5; |
| 34 | |
| 35 | final swordBuilder = new myGame.WeaponBuilder(builder) |
| 36 | ..begin() |
| 37 | ..addNameOffset(weaponOneName) |
| 38 | ..addDamage(weaponOneDamage); |
| 39 | final int sword = swordBuilder.finish(); |
| 40 | |
| 41 | final axeBuilder = new myGame.WeaponBuilder(builder) |
| 42 | ..begin() |
| 43 | ..addNameOffset(weaponTwoName) |
| 44 | ..addDamage(weaponTwoDamage); |
| 45 | final int axe = axeBuilder.finish(); |
| 46 | |
| 47 | // Serialize a name for our monster, called "Orc". |
| 48 | final int name = builder.writeString('Orc'); |
| 49 | |
| 50 | // Create a list representing the inventory of the Orc. Each number |
| 51 | // could correspond to an item that can be claimed after he is slain. |
| 52 | final List<int> treasure = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; |
| 53 | final inventory = builder.writeListUint8(treasure); |
| 54 | final weapons = builder.writeList([sword, axe]); |
| 55 | |
| 56 | // Struct builders are very easy to reuse. |
| 57 | final vec3Builder = new myGame.Vec3Builder(builder); |
| 58 | |
| 59 | vec3Builder.finish(4.0, 5.0, 6.0); |
| 60 | vec3Builder.finish(1.0, 2.0, 3.0); |
| 61 | // Set his hit points to 300 and his mana to 150. |
| 62 | final int hp = 300; |
| 63 | final int mana = 150; |
| 64 | |
| 65 | final monster = new myGame.MonsterBuilder(builder) |
| 66 | ..begin() |
| 67 | ..addNameOffset(name) |
| 68 | ..addInventoryOffset(inventory) |
| 69 | ..addWeaponsOffset(weapons) |
| 70 | ..addEquippedType(myGame.EquipmentTypeId.Weapon) |
| 71 | ..addEquippedOffset(axe) |
| 72 | ..addHp(hp) |
| 73 | ..addMana(mana) |
| 74 | ..addPos(vec3Builder.finish(1.0, 2.0, 3.0)) |
| 75 | ..addColor(myGame.Color.Red); |
| 76 | |
| 77 | final int monsteroff = monster.finish(); |
| 78 | final buffer = builder.finish(monsteroff); |
| 79 | if (verify(buffer)) { |
| 80 | print( |
| 81 | "The FlatBuffer was successfully created with a builder and verified!"); |
| 82 | } |
| 83 | } |
| 84 | |
| 85 | void objectBuilderTest() { |
| 86 | // Create the builder here so we can use it for both weapons and equipped |
| 87 | // the actual data will only be written to the buffer once. |
| 88 | var axe = new myGame.WeaponObjectBuilder(name: 'Axe', damage: 5); |
| 89 | |
| 90 | var monsterBuilder = new myGame.MonsterObjectBuilder( |
| 91 | pos: new myGame.Vec3ObjectBuilder(x: 1.0, y: 2.0, z: 3.0), |
| 92 | mana: 150, |
| 93 | hp: 300, |
| 94 | name: 'Orc', |
| 95 | inventory: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], |
| 96 | color: myGame.Color.Red, |
| 97 | weapons: [new myGame.WeaponObjectBuilder(name: 'Sword', damage: 3), axe], |
| 98 | equippedType: myGame.EquipmentTypeId.Weapon, |
| 99 | equipped: axe, |
| 100 | ); |
| 101 | |
| 102 | var buffer = monsterBuilder.toBytes(); |
| 103 | |
| 104 | // We now have a FlatBuffer we can store on disk or send over a network. |
| 105 | |
| 106 | // ** file/network code goes here :) ** |
| 107 | |
| 108 | // Instead, we're going to access it right away (as if we just received it). |
| 109 | if (verify(buffer)) { |
| 110 | print( |
| 111 | "The FlatBuffer was successfully created with an object builder and verified!"); |
| 112 | } |
| 113 | } |
| 114 | |
| 115 | bool verify(List<int> buffer) { |
| 116 | // Get access to the root: |
| 117 | var monster = new myGame.Monster(buffer); |
| 118 | |
| 119 | // Get and test some scalar types from the FlatBuffer. |
| 120 | assert(monster.hp == 80); |
| 121 | assert(monster.mana == 150); // default |
| 122 | assert(monster.name == "MyMonster"); |
| 123 | |
| 124 | // Get and test a field of the FlatBuffer's `struct`. |
| 125 | var pos = monster.pos; |
| 126 | assert(pos != null); |
| 127 | assert(pos.z == 3.0); |
| 128 | |
| 129 | // Get a test an element from the `inventory` FlatBuffer's `vector`. |
| 130 | var inv = monster.inventory; |
| 131 | assert(inv != null); |
| 132 | assert(inv.length == 10); |
| 133 | assert(inv[9] == 9); |
| 134 | |
| 135 | // Get and test the `weapons` FlatBuffers's `vector`. |
| 136 | var expected_weapon_names = ["Sword", "Axe"]; |
| 137 | var expected_weapon_damages = [3, 5]; |
| 138 | var weps = monster.weapons; |
| 139 | for (int i = 0; i < weps.length; i++) { |
| 140 | assert(weps[i].name == expected_weapon_names[i]); |
| 141 | assert(weps[i].damage == expected_weapon_damages[i]); |
| 142 | } |
| 143 | |
| 144 | // Get and test the `Equipment` union (`equipped` field). |
| 145 | assert(monster.equippedType.value == myGame.EquipmentTypeId.Weapon.value); |
| 146 | assert(monster.equippedType == myGame.EquipmentTypeId.Weapon); |
| 147 | |
| 148 | assert(monster.equipped is myGame.Weapon); |
| 149 | var equipped = monster.equipped as myGame.Weapon; |
| 150 | assert(equipped.name == "Axe"); |
| 151 | assert(equipped.damage == 5); |
| 152 | |
| 153 | print(monster); |
| 154 | return true; |
| 155 | } |