add swift flatbuffers
This commit is contained in:
22
flatbuffers/Documentation.docc/Documentation.md
Normal file
22
flatbuffers/Documentation.docc/Documentation.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# ``FlatBuffers``
|
||||
|
||||
FlatBuffers: Memory Efficient Serialization Library
|
||||
|
||||
## Overview
|
||||
|
||||
- Access to serialized data without parsing/unpacking - What sets FlatBuffers apart is that it represents hierarchical data in a flat binary buffer in such a way that it can still be accessed directly without parsing/unpacking, while also still supporting data structure evolution (forwards/backwards compatibility).
|
||||
- Memory efficiency and speed - The only memory needed to access your data is that of the buffer. It requires 0 additional allocations (in C++, other languages may vary). FlatBuffers is also very suitable for use with mmap (or streaming), requiring only part of the buffer to be in memory. Access is close to the speed of raw struct access with only one extra indirection (a kind of vtable) to allow for format evolution and optional fields. It is aimed at projects where spending time and space (many memory allocations) to be able to access or construct serialized data is undesirable, such as in games or any other performance sensitive applications. See the benchmarks for details.
|
||||
- Flexible - Optional fields means not only do you get great forwards and backwards compatibility (increasingly important for long-lived games: don't have to update all data with each new version!). It also means you have a lot of choice in what data you write and what data you don't, and how you design data structures.
|
||||
- Tiny code footprint - Small amounts of generated code, and just a single small header as the minimum dependency, which is very easy to integrate. Again, see the benchmark section for details.
|
||||
- Strongly typed - Errors happen at compile time rather than manually having to write repetitive and error prone run-time checks. Useful code can be generated for you.
|
||||
|
||||
## Topics
|
||||
|
||||
### Read this first
|
||||
|
||||
- <doc:Tutorial_Table_of_Contents>
|
||||
|
||||
### Where to start
|
||||
|
||||
- ``FlatBufferBuilder``
|
||||
- ``ByteBuffer``
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
enum Color:byte { red, green, blue }
|
||||
@@ -0,0 +1,6 @@
|
||||
enum Color:byte { red, green, blue }
|
||||
|
||||
struct Vec3 {
|
||||
x:float;
|
||||
y:float;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
enum Color:byte { red, green, blue }
|
||||
|
||||
struct Vec3 {
|
||||
x:float;
|
||||
y:float;
|
||||
}
|
||||
|
||||
table Monster {
|
||||
pos:Vec3;
|
||||
color:Color = Blue;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
enum Color:byte { red, green, blue }
|
||||
|
||||
struct Vec3 {
|
||||
x:float;
|
||||
y:float;
|
||||
}
|
||||
|
||||
table Monster {
|
||||
pos:Vec3;
|
||||
color:Color = Blue;
|
||||
|
||||
mana:short = 150;
|
||||
hp:short = 100;
|
||||
name:string;
|
||||
equipped:Equipment;
|
||||
weapons:[Weapon];
|
||||
path:[Vec3];
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
enum Color:byte { red, green, blue }
|
||||
|
||||
union Equipment { Weapon } // Optionally add more tables.
|
||||
|
||||
struct Vec3 {
|
||||
x:float;
|
||||
y:float;
|
||||
}
|
||||
|
||||
table Monster {
|
||||
pos:Vec3;
|
||||
color:Color = Blue;
|
||||
|
||||
mana:short = 150;
|
||||
hp:short = 100;
|
||||
name:string;
|
||||
equipped:Equipment;
|
||||
weapons:[Weapon];
|
||||
path:[Vec3];
|
||||
}
|
||||
|
||||
table Weapon {
|
||||
name:string;
|
||||
damage:short;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
enum Color:byte { red, green, blue }
|
||||
|
||||
union Equipment { Weapon } // Optionally add more tables.
|
||||
|
||||
struct Vec3 {
|
||||
x:float;
|
||||
y:float;
|
||||
}
|
||||
|
||||
table Monster {
|
||||
pos:Vec3;
|
||||
color:Color = Blue;
|
||||
|
||||
mana:short = 150;
|
||||
hp:short = 100;
|
||||
name:string;
|
||||
equipped:Equipment;
|
||||
weapons:[Weapon];
|
||||
path:[Vec3];
|
||||
}
|
||||
|
||||
table Weapon {
|
||||
name:string;
|
||||
damage:short;
|
||||
}
|
||||
|
||||
root_type Monster; // flatc --swift monster.fbs
|
||||
@@ -0,0 +1 @@
|
||||
import Foundation
|
||||
@@ -0,0 +1,71 @@
|
||||
import FlatBuffers
|
||||
import Foundation
|
||||
|
||||
func run() {
|
||||
// create a `FlatBufferBuilder`, which will be used to serialize objects
|
||||
let builder = FlatBufferBuilder(initialSize: 1024)
|
||||
|
||||
let weapon1Name = builder.create(string: "Sword")
|
||||
let weapon2Name = builder.create(string: "Axe")
|
||||
|
||||
// start creating the weapon by calling startWeapon
|
||||
let weapon1Start = Weapon.startWeapon(&builder)
|
||||
Weapon.add(name: weapon1Name, &builder)
|
||||
Weapon.add(damage: 3, &builder)
|
||||
// end the object by passing the start point for the weapon 1
|
||||
let sword = Weapon.endWeapon(&builder, start: weapon1Start)
|
||||
|
||||
let weapon2Start = Weapon.startWeapon(&builder)
|
||||
Weapon.add(name: weapon2Name, &builder)
|
||||
Weapon.add(damage: 5, &builder)
|
||||
let axe = Weapon.endWeapon(&builder, start: weapon2Start)
|
||||
|
||||
// Create a FlatBuffer `vector` that contains offsets to the sword and axe
|
||||
// we created above.
|
||||
let weaponsOffset = builder.createVector(ofOffsets: [sword, axe])
|
||||
|
||||
// Name of the Monster.
|
||||
let name = builder.create(string: "Orc")
|
||||
|
||||
let pathOffset = fbb.createVector(ofStructs: [
|
||||
Vec3(x: 0, y: 0),
|
||||
Vec3(x: 5, y: 5),
|
||||
])
|
||||
|
||||
// startVector(len, elementSize: MemoryLayout<Offset>.size)
|
||||
// for o in offsets.reversed() {
|
||||
// push(element: o)
|
||||
// }
|
||||
// endVector(len: len)
|
||||
|
||||
let orc = Monster.createMonster(
|
||||
&builder,
|
||||
pos: Vec3(x: 1, y: 2),
|
||||
hp: 300,
|
||||
nameOffset: name,
|
||||
color: .red,
|
||||
weaponsVectorOffset: weaponsOffset,
|
||||
equippedType: .weapon,
|
||||
equippedOffset: axe,
|
||||
pathOffset: pathOffset)
|
||||
|
||||
// let start = Monster.startMonster(&builder)
|
||||
// Monster.add(pos: Vec3(x: 1, y: 2), &builder)
|
||||
// Monster.add(hp: 300, &builder)
|
||||
// Monster.add(name: name, &builder)
|
||||
// Monster.add(color: .red, &builder)
|
||||
// Monster.addVectorOf(weapons: weaponsOffset, &builder)
|
||||
// Monster.add(equippedType: .weapon, &builder)
|
||||
// Monster.addVectorOf(paths: weaponsOffset, &builder)
|
||||
// Monster.add(equipped: axe, &builder)
|
||||
// var orc = Monster.endMonster(&builder, start: start)
|
||||
|
||||
// Call `finish(offset:)` to instruct the builder that this monster is complete.
|
||||
builder.finish(offset: orc)
|
||||
// This must be called after `finish()`.
|
||||
// `sizedByteArray` returns the finished buf of type [UInt8].
|
||||
let buf = builder.sizedByteArray
|
||||
|
||||
// or you can use to get an object of type Data
|
||||
let bufData = ByteBuffer(data: builder.sizedBuffer)
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import FlatBuffers
|
||||
import Foundation
|
||||
|
||||
func run() {
|
||||
// create a ByteBuffer(:) from an [UInt8] or Data()
|
||||
let buf = [] // Get your data
|
||||
var byteBuffer = ByteBuffer(bytes: buf)
|
||||
// Get an accessor to the root object inside the buffer.
|
||||
let monster: Monster = try! getCheckedRoot(byteBuffer: &byteBuffer)
|
||||
// let monster: Monster = getRoot(byteBuffer: &byteBuffer)
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import FlatBuffers
|
||||
import Foundation
|
||||
|
||||
func run() {
|
||||
// create a ByteBuffer(:) from an [UInt8] or Data()
|
||||
let buf = [] // Get your data
|
||||
var byteBuffer = ByteBuffer(bytes: buf)
|
||||
// Get an accessor to the root object inside the buffer.
|
||||
let monster: Monster = try! getCheckedRoot(byteBuffer: &byteBuffer)
|
||||
// let monster: Monster = getRoot(byteBuffer: &byteBuffer)
|
||||
|
||||
let hp = monster.hp
|
||||
let mana = monster.mana
|
||||
let name = monster.name // returns an optional string
|
||||
|
||||
let pos = monster.pos
|
||||
let x = pos.x
|
||||
let y = pos.y
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import FlatBuffers
|
||||
import Foundation
|
||||
|
||||
func run() {
|
||||
// create a ByteBuffer(:) from an [UInt8] or Data()
|
||||
let buf = [] // Get your data
|
||||
var byteBuffer = ByteBuffer(bytes: buf)
|
||||
// Get an accessor to the root object inside the buffer.
|
||||
let monster: Monster = try! getCheckedRoot(byteBuffer: &byteBuffer)
|
||||
// let monster: Monster = getRoot(byteBuffer: &byteBuffer)
|
||||
|
||||
let hp = monster.hp
|
||||
let mana = monster.mana
|
||||
let name = monster.name // returns an optional string
|
||||
|
||||
let pos = monster.pos
|
||||
let x = pos.x
|
||||
let y = pos.y
|
||||
|
||||
// Get and check if the monster has an equipped item
|
||||
if monster.equippedType == .weapon {
|
||||
let _weapon = monster.equipped(type: Weapon.self)
|
||||
let name = _weapon.name // should return "Axe"
|
||||
let dmg = _weapon.damage // should return 5
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
import FlatBuffers
|
||||
import Foundation
|
||||
@@ -0,0 +1,7 @@
|
||||
import FlatBuffers
|
||||
import Foundation
|
||||
|
||||
func run() {
|
||||
// create a `FlatBufferBuilder`, which will be used to serialize objects
|
||||
let builder = FlatBufferBuilder(initialSize: 1024)
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import FlatBuffers
|
||||
import Foundation
|
||||
|
||||
func run() {
|
||||
// create a `FlatBufferBuilder`, which will be used to serialize objects
|
||||
let builder = FlatBufferBuilder(initialSize: 1024)
|
||||
|
||||
let weapon1Name = builder.create(string: "Sword")
|
||||
let weapon2Name = builder.create(string: "Axe")
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import FlatBuffers
|
||||
import Foundation
|
||||
|
||||
func run() {
|
||||
// create a `FlatBufferBuilder`, which will be used to serialize objects
|
||||
let builder = FlatBufferBuilder(initialSize: 1024)
|
||||
|
||||
let weapon1Name = builder.create(string: "Sword")
|
||||
let weapon2Name = builder.create(string: "Axe")
|
||||
|
||||
// start creating the weapon by calling startWeapon
|
||||
let weapon1Start = Weapon.startWeapon(&builder)
|
||||
Weapon.add(name: weapon1Name, &builder)
|
||||
Weapon.add(damage: 3, &builder)
|
||||
// end the object by passing the start point for the weapon 1
|
||||
let sword = Weapon.endWeapon(&builder, start: weapon1Start)
|
||||
|
||||
let weapon2Start = Weapon.startWeapon(&builder)
|
||||
Weapon.add(name: weapon2Name, &builder)
|
||||
Weapon.add(damage: 5, &builder)
|
||||
let axe = Weapon.endWeapon(&builder, start: weapon2Start)
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import FlatBuffers
|
||||
import Foundation
|
||||
|
||||
func run() {
|
||||
// create a `FlatBufferBuilder`, which will be used to serialize objects
|
||||
let builder = FlatBufferBuilder(initialSize: 1024)
|
||||
|
||||
let weapon1Name = builder.create(string: "Sword")
|
||||
let weapon2Name = builder.create(string: "Axe")
|
||||
|
||||
// start creating the weapon by calling startWeapon
|
||||
let weapon1Start = Weapon.startWeapon(&builder)
|
||||
Weapon.add(name: weapon1Name, &builder)
|
||||
Weapon.add(damage: 3, &builder)
|
||||
// end the object by passing the start point for the weapon 1
|
||||
let sword = Weapon.endWeapon(&builder, start: weapon1Start)
|
||||
|
||||
let weapon2Start = Weapon.startWeapon(&builder)
|
||||
Weapon.add(name: weapon2Name, &builder)
|
||||
Weapon.add(damage: 5, &builder)
|
||||
let axe = Weapon.endWeapon(&builder, start: weapon2Start)
|
||||
|
||||
// Create a FlatBuffer `vector` that contains offsets to the sword and axe
|
||||
// we created above.
|
||||
let weaponsOffset = builder.createVector(ofOffsets: [sword, axe])
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import FlatBuffers
|
||||
import Foundation
|
||||
|
||||
func run() {
|
||||
// create a `FlatBufferBuilder`, which will be used to serialize objects
|
||||
let builder = FlatBufferBuilder(initialSize: 1024)
|
||||
|
||||
let weapon1Name = builder.create(string: "Sword")
|
||||
let weapon2Name = builder.create(string: "Axe")
|
||||
|
||||
// start creating the weapon by calling startWeapon
|
||||
let weapon1Start = Weapon.startWeapon(&builder)
|
||||
Weapon.add(name: weapon1Name, &builder)
|
||||
Weapon.add(damage: 3, &builder)
|
||||
// end the object by passing the start point for the weapon 1
|
||||
let sword = Weapon.endWeapon(&builder, start: weapon1Start)
|
||||
|
||||
let weapon2Start = Weapon.startWeapon(&builder)
|
||||
Weapon.add(name: weapon2Name, &builder)
|
||||
Weapon.add(damage: 5, &builder)
|
||||
let axe = Weapon.endWeapon(&builder, start: weapon2Start)
|
||||
|
||||
// Create a FlatBuffer `vector` that contains offsets to the sword and axe
|
||||
// we created above.
|
||||
let weaponsOffset = builder.createVector(ofOffsets: [sword, axe])
|
||||
|
||||
// Name of the Monster.
|
||||
let name = builder.create(string: "Orc")
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import FlatBuffers
|
||||
import Foundation
|
||||
|
||||
func run() {
|
||||
// create a `FlatBufferBuilder`, which will be used to serialize objects
|
||||
let builder = FlatBufferBuilder(initialSize: 1024)
|
||||
|
||||
let weapon1Name = builder.create(string: "Sword")
|
||||
let weapon2Name = builder.create(string: "Axe")
|
||||
|
||||
// start creating the weapon by calling startWeapon
|
||||
let weapon1Start = Weapon.startWeapon(&builder)
|
||||
Weapon.add(name: weapon1Name, &builder)
|
||||
Weapon.add(damage: 3, &builder)
|
||||
// end the object by passing the start point for the weapon 1
|
||||
let sword = Weapon.endWeapon(&builder, start: weapon1Start)
|
||||
|
||||
let weapon2Start = Weapon.startWeapon(&builder)
|
||||
Weapon.add(name: weapon2Name, &builder)
|
||||
Weapon.add(damage: 5, &builder)
|
||||
let axe = Weapon.endWeapon(&builder, start: weapon2Start)
|
||||
|
||||
// Create a FlatBuffer `vector` that contains offsets to the sword and axe
|
||||
// we created above.
|
||||
let weaponsOffset = builder.createVector(ofOffsets: [sword, axe])
|
||||
|
||||
// Name of the Monster.
|
||||
let name = builder.create(string: "Orc")
|
||||
|
||||
let pathOffset = fbb.createVector(ofStructs: [
|
||||
Vec3(x: 0, y: 0),
|
||||
Vec3(x: 5, y: 5),
|
||||
])
|
||||
|
||||
// startVector(len, elementSize: MemoryLayout<Offset>.size)
|
||||
// for o in offsets.reversed() {
|
||||
// push(element: o)
|
||||
// }
|
||||
// endVector(len: len)
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
import FlatBuffers
|
||||
import Foundation
|
||||
|
||||
func run() {
|
||||
// create a `FlatBufferBuilder`, which will be used to serialize objects
|
||||
let builder = FlatBufferBuilder(initialSize: 1024)
|
||||
|
||||
let weapon1Name = builder.create(string: "Sword")
|
||||
let weapon2Name = builder.create(string: "Axe")
|
||||
|
||||
// start creating the weapon by calling startWeapon
|
||||
let weapon1Start = Weapon.startWeapon(&builder)
|
||||
Weapon.add(name: weapon1Name, &builder)
|
||||
Weapon.add(damage: 3, &builder)
|
||||
// end the object by passing the start point for the weapon 1
|
||||
let sword = Weapon.endWeapon(&builder, start: weapon1Start)
|
||||
|
||||
let weapon2Start = Weapon.startWeapon(&builder)
|
||||
Weapon.add(name: weapon2Name, &builder)
|
||||
Weapon.add(damage: 5, &builder)
|
||||
let axe = Weapon.endWeapon(&builder, start: weapon2Start)
|
||||
|
||||
// Create a FlatBuffer `vector` that contains offsets to the sword and axe
|
||||
// we created above.
|
||||
let weaponsOffset = builder.createVector(ofOffsets: [sword, axe])
|
||||
|
||||
// Name of the Monster.
|
||||
let name = builder.create(string: "Orc")
|
||||
|
||||
let pathOffset = fbb.createVector(ofStructs: [
|
||||
Vec3(x: 0, y: 0),
|
||||
Vec3(x: 5, y: 5),
|
||||
])
|
||||
|
||||
// startVector(len, elementSize: MemoryLayout<Offset>.size)
|
||||
// for o in offsets.reversed() {
|
||||
// push(element: o)
|
||||
// }
|
||||
// endVector(len: len)
|
||||
|
||||
let orc = Monster.createMonster(
|
||||
&builder,
|
||||
pos: Vec3(x: 1, y: 2),
|
||||
hp: 300,
|
||||
nameOffset: name,
|
||||
color: .red,
|
||||
weaponsVectorOffset: weaponsOffset,
|
||||
equippedType: .weapon,
|
||||
equippedOffset: axe,
|
||||
pathOffset: pathOffset)
|
||||
|
||||
// let start = Monster.startMonster(&builder)
|
||||
// Monster.add(pos: Vec3(x: 1, y: 2), &builder)
|
||||
// Monster.add(hp: 300, &builder)
|
||||
// Monster.add(name: name, &builder)
|
||||
// Monster.add(color: .red, &builder)
|
||||
// Monster.addVectorOf(weapons: weaponsOffset, &builder)
|
||||
// Monster.add(equippedType: .weapon, &builder)
|
||||
// Monster.addVectorOf(paths: weaponsOffset, &builder)
|
||||
// Monster.add(equipped: axe, &builder)
|
||||
// var orc = Monster.endMonster(&builder, start: start)
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
@@ -0,0 +1,14 @@
|
||||
@Tutorials(name: "Starting with FlatBuffers") {
|
||||
@Intro(title: "Starting with FlatBuffers") {
|
||||
FlatBuffers is an efficient cross platform serialization library for C++,
|
||||
C#, C, Go, Java, Kotlin, JavaScript, Lobster, Lua, TypeScript, PHP, Python, Rust and Swift.
|
||||
It was originally created at Google for game development and other performance-critical applications.
|
||||
}
|
||||
@Chapter(name: "Generating your code") {
|
||||
Start by generating your first FlatBuffers objects.
|
||||
@Image(source: tutorial_cover_image_1.png, alt: "A code structure for a base struct in flatbuffers")
|
||||
@TutorialReference(tutorial: "doc:creating_flatbuffer_schema")
|
||||
@TutorialReference(tutorial: "doc:create_your_first_buffer")
|
||||
@TutorialReference(tutorial: "doc:reading_bytebuffer")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
@Tutorial(time: 5) {
|
||||
@Intro(title: "After having our code generated") {
|
||||
After generating the code from the previous section, we will know start creating our monster object.
|
||||
We will create a monster object called orc.
|
||||
}
|
||||
|
||||
@Section(title: "Building your first buffer") {
|
||||
@ContentAndMedia {}
|
||||
@Steps {
|
||||
@Step {
|
||||
Starting with a new file, we will create our very first Flatbuffer.
|
||||
@Code(name: "ViewController.swift", file: "swift_code_1.swift")
|
||||
}
|
||||
@Step {
|
||||
First, we need to import ``FlatBuffers``
|
||||
@Code(name: "ViewController.swift", file: "swift_code_2.swift")
|
||||
}
|
||||
@Step {
|
||||
We need to create an instance of the `FlatBufferBuilder`, which will contain the buffer as it grows.
|
||||
You can pass an initial size of the buffer (here 1024 bytes), which will grow automatically if needed.
|
||||
@Code(name: "ViewController.swift", file: "swift_code_3.swift")
|
||||
}
|
||||
@Step {
|
||||
After creating the builder, we can start serializing our data. Before we make our orc Monster,
|
||||
let's create some Weapons: a Sword and an Axe. However we will start by naming our weapons as `Sword` and `Axe`
|
||||
@Code(name: "ViewController.swift", file: "swift_code_4.swift")
|
||||
}
|
||||
@Step {
|
||||
After naming the weapons, we will create two weapon objects with the damage that the weapon is going to deal.
|
||||
That's done by calling the `start` Method on each table you will be creating, in this case its called `startWeapon`
|
||||
and finished by calling `end`.
|
||||
@Code(name: "ViewController.swift", file: "swift_code_5.swift")
|
||||
}
|
||||
@Step {
|
||||
We will take our (Sword and Axe) serialized data and serialize their offsets as a vector of tables into our `ByteBuffer`.
|
||||
So we can reference them later on from our Monster Object
|
||||
@Code(name: "ViewController.swift", file: "swift_code_6.swift")
|
||||
}
|
||||
@Step {
|
||||
We will add our Monster name as a string value just like we did with the weapons.
|
||||
@Code(name: "ViewController.swift", file: "swift_code_7.swift")
|
||||
}
|
||||
|
||||
@Step {
|
||||
We will create a path that our monster should be using while roaming in its den. To create a vector of paths we would us
|
||||
`createVector(ofStructs: [])` which will take a Native `Swift` struct that has been padded to fit the `FlatBuffers` standards.
|
||||
|
||||
There are usually two ways of creating vectors in `FlatBuffers` which you can see in commented out code.
|
||||
And thus there are multiple convenience methods that will cover all the bases
|
||||
when trying to create a vector so that you dont have to create it with `start` and `end`
|
||||
@Code(name: "ViewController.swift", file: "swift_code_8.swift")
|
||||
}
|
||||
|
||||
@Step {
|
||||
Now to serialize our data into our `Monster` object. Which again there are two ways of doing, by calling the `create` method or
|
||||
by serializing the objects yourself. What we added to our Monster were the `Equipped Type` and the `Equipped` union itself, which
|
||||
allows the Monster to have the `Axe` as his equipped weapon.
|
||||
|
||||
Important: Unlike structs, you should not nest tables or other objects,
|
||||
which is why we created all the `strings/vectors/tables` that this monster refers to before start.
|
||||
If you try to create any of them between start and end, you will get an `assert`.
|
||||
@Code(name: "ViewController.swift", file: "swift_code_9.swift")
|
||||
}
|
||||
|
||||
@Step {
|
||||
Finally you can just finalize the buffer by calling `builder.finish` and get the Byte array from the buffer.
|
||||
@Code(name: "ViewController.swift", file: "swift_code_10.swift")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
@Tutorial(time: 2) {
|
||||
@Intro(title: "Creating a schema") {
|
||||
You will need to have the FlatBuffer compiler to be installed on your device
|
||||
}
|
||||
|
||||
@Section(title: "Creating a schema") {
|
||||
@ContentAndMedia {}
|
||||
@Steps {
|
||||
@Step {
|
||||
Start by creating a new empty folder called `monster.fbs`. We want to create a Monster table, that contains
|
||||
position, color, and basic information about the monster.
|
||||
@Code(name: "monster.fbs", file: "monster_step_1.fbs")
|
||||
}
|
||||
@Step {
|
||||
We will start by adding our Color object. We will be using an enumerate, to represent this object
|
||||
@Code(name: "monster.fbs", file: "monster_step_2.fbs")
|
||||
}
|
||||
@Step {
|
||||
We will add a position object and will use a struct to represent that type of data. Where we will need the monsters
|
||||
x and y positions.
|
||||
@Code(name: "monster.fbs", file: "monster_step_3.fbs")
|
||||
}
|
||||
@Step {
|
||||
Then we will be creating our Monster object of type table. This will contain the current position of our
|
||||
monster and its color
|
||||
@Code(name: "monster.fbs", file: "monster_step_4.fbs")
|
||||
}
|
||||
@Step {
|
||||
Our Monster is missing a name, mana, hp, name, equipped Weapon, weapons, and path. We will be adding these
|
||||
fields to our table with a proper data type for each. Example; weapons, and path would be a vector of data.
|
||||
@Code(name: "monster.fbs", file: "monster_step_5.fbs")
|
||||
}
|
||||
@Step {
|
||||
Now we are missing two data types here, `Weapon` and `Equipment`. And since Equipment can be a weapon, we will be using
|
||||
a `Union` enumerate that can contain all the equipment that you would want your monster to have. And the weapon can simply
|
||||
have a name and amount of damage
|
||||
@Code(name: "monster.fbs", file: "monster_step_6.fbs")
|
||||
}
|
||||
@Step {
|
||||
And to finalize our monster table, we can add a root type of type Monster.
|
||||
Then run the command `flatc --swift monster.fbs`
|
||||
Note: Make sure to import the file to your xcode project.
|
||||
@Code(name: "monster.fbs", file: "monster_step_7.fbs")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
@Tutorial(time: 2) {
|
||||
@Intro(title: "Reading ByteBuffers") {
|
||||
After getting our ByteBuffer created, we can now read it.
|
||||
}
|
||||
|
||||
@Section(title: "Reading your first buffer") {
|
||||
@ContentAndMedia {}
|
||||
@Steps {
|
||||
@Step {
|
||||
After fetching the data from disk or network you need to access that data, and that can be done.
|
||||
By simply calling `getCheckedRoot`, which checks if the data is valid before enabling you to read from a corrupt buffer.
|
||||
however, if you are sure that the data is 100% correct you can simply call `getRoot`
|
||||
@Code(name: "ViewController.swift", file: "swift_code_11.swift")
|
||||
}
|
||||
@Step {
|
||||
Now since we have a Monster object, all the fields can be accessed by simply fetching the data. Note, Deprecated fields will not
|
||||
show up
|
||||
@Code(name: "ViewController.swift", file: "swift_code_12.swift")
|
||||
}
|
||||
@Step {
|
||||
And you can access union types as easy as this
|
||||
@Code(name: "ViewController.swift", file: "swift_code_13.swift")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user