Added fenced code blocks to the C++/Java/Go docs for syntax highlighting.

Change-Id: I504915c6b5367e8c05dc056463158b8420ad8c5e
Tested: on Linux.
parent d38b9af2
This diff is collapsed.
...@@ -54,40 +54,47 @@ $(document).ready(function(){initNavTree('md__go_usage.html','');}); ...@@ -54,40 +54,47 @@ $(document).ready(function(){initNavTree('md__go_usage.html','');});
</div><!--header--> </div><!--header-->
<div class="contents"> <div class="contents">
<div class="textblock"><p>There's experimental support for reading FlatBuffers in Go. Generate code for Go with the <code>-g</code> option to <code>flatc</code>.</p> <div class="textblock"><p>There's experimental support for reading FlatBuffers in Go. Generate code for Go with the <code>-g</code> option to <code>flatc</code>.</p>
<p>See <code>go_test.go</code> for an example. You import the generated code, read a FlatBuffer binary file into a <code>[]byte</code>, which you pass to the <code>GetRootAsMonster</code> function: </p><pre class="fragment">import ( <p>See <code>go_test.go</code> for an example. You import the generated code, read a FlatBuffer binary file into a <code>[]byte</code>, which you pass to the <code>GetRootAsMonster</code> function:</p>
example "MyGame/Example" <div class="fragment"><div class="line"><span class="keyword">import</span> (</div>
flatbuffers "github.com/google/flatbuffers/go" <div class="line"> example <span class="stringliteral">&quot;MyGame/Example&quot;</span></div>
<div class="line"> flatbuffers <span class="stringliteral">&quot;github.com/google/flatbuffers/go&quot;</span></div>
io/ioutil <div class="line"></div>
) <div class="line"> io/ioutil</div>
<div class="line">)</div>
buf, err := ioutil.ReadFile("monster.dat") <div class="line"></div>
// handle err <div class="line">buf, err := ioutil.ReadFile(<span class="stringliteral">&quot;monster.dat&quot;</span>)</div>
monster := example.GetRootAsMonster(buf, 0) <div class="line"><span class="comment">// handle err</span></div>
</pre><p>Now you can access values like this: </p><pre class="fragment">hp := monster.Hp() <div class="line">monster := example.GetRootAsMonster(buf, 0)</div>
pos := monster.Pos(nil) </div><!-- fragment --><p>Now you can access values like this:</p>
</pre><p>Note that whenever you access a new object like in the <code>Pos</code> example above, a new temporary accessor object gets created. If your code is very performance sensitive (you iterate through a lot of objects), you can replace nil with a pointer to a <code>Vec3</code> object you've already created. This allows you to reuse it across many calls and reduce the amount of object allocation (and thus garbage collection) your program does.</p> <div class="fragment"><div class="line">hp := monster.Hp()</div>
<p>To access vectors you pass an extra index to the vector field accessor. Then a second method with the same name suffixed by <code>Length</code> let's you know the number of elements you can access: </p><pre class="fragment">for i := 0; i &lt; monster.InventoryLength(); i++ { <div class="line">pos := monster.Pos(nil)</div>
monster.Inventory(i) // do something here </div><!-- fragment --><p>Note that whenever you access a new object like in the <code>Pos</code> example above, a new temporary accessor object gets created. If your code is very performance sensitive (you iterate through a lot of objects), you can replace nil with a pointer to a <code>Vec3</code> object you've already created. This allows you to reuse it across many calls and reduce the amount of object allocation (and thus garbage collection) your program does.</p>
} <p>To access vectors you pass an extra index to the vector field accessor. Then a second method with the same name suffixed by <code>Length</code> let's you know the number of elements you can access:</p>
</pre><p>You can also construct these buffers in Go using the functions found in the generated code, and the FlatBufferBuilder class: </p><pre class="fragment">builder := flatbuffers.NewBuilder(0) <div class="fragment"><div class="line"><span class="keywordflow">for</span> i := 0; i &lt; monster.InventoryLength(); i++ {</div>
</pre><p>Create strings: </p><pre class="fragment">str := builder.CreateString("MyMonster") <div class="line"> monster.Inventory(i) <span class="comment">// do something here</span></div>
</pre><p>Create a table with a struct contained therein: </p><pre class="fragment">example.MonsterStart(builder) <div class="line">}</div>
example.MonsterAddPos(builder, example.CreateVec3(builder, 1.0, 2.0, 3.0, 3.0, 4, 5, 6)) </div><!-- fragment --><p>You can also construct these buffers in Go using the functions found in the generated code, and the FlatBufferBuilder class:</p>
example.MonsterAddHp(builder, 80) <div class="fragment"><div class="line">builder := flatbuffers.NewBuilder(0)</div>
example.MonsterAddName(builder, str) </div><!-- fragment --><p>Create strings:</p>
example.MonsterAddInventory(builder, inv) <div class="fragment"><div class="line">str := builder.CreateString(<span class="stringliteral">&quot;MyMonster&quot;</span>)</div>
example.MonsterAddTest_Type(builder, 1) </div><!-- fragment --><p>Create a table with a struct contained therein:</p>
example.MonsterAddTest(builder, mon2) <div class="fragment"><div class="line">example.MonsterStart(builder)</div>
example.MonsterAddTest4(builder, test4s) <div class="line">example.MonsterAddPos(builder, example.CreateVec3(builder, 1.0, 2.0, 3.0, 3.0, 4, 5, 6))</div>
mon := example.MonsterEnd(builder) <div class="line">example.MonsterAddHp(builder, 80)</div>
</pre><p>Unlike C++, Go does not support table creation functions like 'createMonster()'. This is to create the buffer without using temporary object allocation (since the <code>Vec3</code> is an inline component of <code>Monster</code>, it has to be created right where it is added, whereas the name and the inventory are not inline). Structs do have convenient methods that allow you to construct them in one call. These also have arguments for nested structs, e.g. if a struct has a field <code>a</code> and a nested struct field <code>b</code> (which has fields <code>c</code> and <code>d</code>), then the arguments will be <code>a</code>, <code>c</code> and <code>d</code>.</p> <div class="line">example.MonsterAddName(builder, str)</div>
<p>Vectors also use this start/end pattern to allow vectors of both scalar types and structs: </p><pre class="fragment">example.MonsterStartInventoryVector(builder, 5) <div class="line">example.MonsterAddInventory(builder, inv)</div>
for i := 4; i &gt;= 0; i-- { <div class="line">example.MonsterAddTest_Type(builder, 1)</div>
builder.PrependByte(byte(i)) <div class="line">example.MonsterAddTest(builder, mon2)</div>
} <div class="line">example.MonsterAddTest4(builder, test4s)</div>
inv := builder.EndVector(5) <div class="line">mon := example.MonsterEnd(builder)</div>
</pre><p>The generated method 'StartInventoryVector' is provided as a convenience function which calls 'StartVector' with the correct element size of the vector type which in this case is 'ubyte' or 1 byte per vector element. You pass the number of elements you want to write. You write the elements backwards since the buffer is being constructed back to front.</p> </div><!-- fragment --><p>Unlike C++, Go does not support table creation functions like 'createMonster()'. This is to create the buffer without using temporary object allocation (since the <code>Vec3</code> is an inline component of <code>Monster</code>, it has to be created right where it is added, whereas the name and the inventory are not inline). Structs do have convenient methods that allow you to construct them in one call. These also have arguments for nested structs, e.g. if a struct has a field <code>a</code> and a nested struct field <code>b</code> (which has fields <code>c</code> and <code>d</code>), then the arguments will be <code>a</code>, <code>c</code> and <code>d</code>.</p>
<p>Vectors also use this start/end pattern to allow vectors of both scalar types and structs:</p>
<div class="fragment"><div class="line">example.MonsterStartInventoryVector(builder, 5)</div>
<div class="line"><span class="keywordflow">for</span> i := 4; i &gt;= 0; i-- {</div>
<div class="line"> builder.PrependByte(byte(i))</div>
<div class="line">}</div>
<div class="line">inv := builder.EndVector(5)</div>
</div><!-- fragment --><p>The generated method 'StartInventoryVector' is provided as a convenience function which calls 'StartVector' with the correct element size of the vector type which in this case is 'ubyte' or 1 byte per vector element. You pass the number of elements you want to write. You write the elements backwards since the buffer is being constructed back to front.</p>
<p>There are <code>Prepend</code> functions for all the scalar types. You use <code>PrependUOffset</code> for any previously constructed objects (such as other tables, strings, vectors). For structs, you use the appropriate <code>create</code> function in-line, as shown above in the <code>Monster</code> example.</p> <p>There are <code>Prepend</code> functions for all the scalar types. You use <code>PrependUOffset</code> for any previously constructed objects (such as other tables, strings, vectors). For structs, you use the appropriate <code>create</code> function in-line, as shown above in the <code>Monster</code> example.</p>
<h2>Text Parsing</h2> <h2>Text Parsing</h2>
<p>There currently is no support for parsing text (Schema's and JSON) directly from Go, though you could use the C++ parser through cgo. Please see the C++ documentation for more on text parsing. </p> <p>There currently is no support for parsing text (Schema's and JSON) directly from Go, though you could use the C++ parser through cgo. Please see the C++ documentation for more on text parsing. </p>
......
This diff is collapsed.
...@@ -12,17 +12,21 @@ your program by including the header. As noted, this header relies on ...@@ -12,17 +12,21 @@ your program by including the header. As noted, this header relies on
To start creating a buffer, create an instance of `FlatBufferBuilder` To start creating a buffer, create an instance of `FlatBufferBuilder`
which will contain the buffer as it grows: which will contain the buffer as it grows:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
FlatBufferBuilder fbb; FlatBufferBuilder fbb;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Before we serialize a Monster, we need to first serialize any objects Before we serialize a Monster, we need to first serialize any objects
that are contained there-in, i.e. we serialize the data tree using that are contained there-in, i.e. we serialize the data tree using
depth first, pre-order traversal. This is generally easy to do on depth first, pre-order traversal. This is generally easy to do on
any tree structures. For example: any tree structures. For example:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
auto name = fbb.CreateString("MyMonster"); auto name = fbb.CreateString("MyMonster");
unsigned char inv[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; unsigned char inv[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
auto inventory = fbb.CreateVector(inv, 10); auto inventory = fbb.CreateVector(inv, 10);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
`CreateString` and `CreateVector` serialize these two built-in `CreateString` and `CreateVector` serialize these two built-in
datatypes, and return offsets into the serialized data indicating where datatypes, and return offsets into the serialized data indicating where
...@@ -38,7 +42,9 @@ correct type below. To create a vector of struct objects (which will ...@@ -38,7 +42,9 @@ correct type below. To create a vector of struct objects (which will
be stored as contiguous memory in the buffer, use `CreateVectorOfStructs` be stored as contiguous memory in the buffer, use `CreateVectorOfStructs`
instead. instead.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
Vec3 vec(1, 2, 3); Vec3 vec(1, 2, 3);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
`Vec3` is the first example of code from our generated `Vec3` is the first example of code from our generated
header. Structs (unlike tables) translate to simple structs in C++, so header. Structs (unlike tables) translate to simple structs in C++, so
...@@ -47,7 +53,9 @@ we can construct them in a familiar way. ...@@ -47,7 +53,9 @@ we can construct them in a familiar way.
We have now serialized the non-scalar components of of the monster We have now serialized the non-scalar components of of the monster
example, so we could create the monster something like this: example, so we could create the monster something like this:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
auto mloc = CreateMonster(fbb, &vec, 150, 80, name, inventory, Color_Red, 0, Any_NONE); auto mloc = CreateMonster(fbb, &vec, 150, 80, name, inventory, Color_Red, 0, Any_NONE);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Note that we're passing `150` for the `mana` field, which happens to be the Note that we're passing `150` for the `mana` field, which happens to be the
default value: this means the field will not actually be written to the buffer, default value: this means the field will not actually be written to the buffer,
...@@ -67,12 +75,14 @@ If you want even more control over this (i.e. skip fields even when they are ...@@ -67,12 +75,14 @@ If you want even more control over this (i.e. skip fields even when they are
not default), instead of the convenient `CreateMonster` call we can also not default), instead of the convenient `CreateMonster` call we can also
build the object field-by-field manually: build the object field-by-field manually:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
MonsterBuilder mb(fbb); MonsterBuilder mb(fbb);
mb.add_pos(&vec); mb.add_pos(&vec);
mb.add_hp(80); mb.add_hp(80);
mb.add_name(name); mb.add_name(name);
mb.add_inventory(inventory); mb.add_inventory(inventory);
auto mloc = mb.Finish(); auto mloc = mb.Finish();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We start with a temporary helper class `MonsterBuilder` (which is We start with a temporary helper class `MonsterBuilder` (which is
defined in our generated code also), then call the various `add_` defined in our generated code also), then call the various `add_`
...@@ -88,7 +98,9 @@ Regardless of whether you used `CreateMonster` or `MonsterBuilder`, you ...@@ -88,7 +98,9 @@ Regardless of whether you used `CreateMonster` or `MonsterBuilder`, you
now have an offset to the root of your data, and you can finish the now have an offset to the root of your data, and you can finish the
buffer using: buffer using:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
FinishMonsterBuffer(fbb, mloc); FinishMonsterBuffer(fbb, mloc);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The buffer is now ready to be stored somewhere, sent over the network, The buffer is now ready to be stored somewhere, sent over the network,
be compressed, or whatever you'd like to do with it. You can access the be compressed, or whatever you'd like to do with it. You can access the
...@@ -103,33 +115,41 @@ the code above, that also includes the reading code below. ...@@ -103,33 +115,41 @@ the code above, that also includes the reading code below.
If you've received a buffer from somewhere (disk, network, etc.) you can If you've received a buffer from somewhere (disk, network, etc.) you can
directly start traversing it using: directly start traversing it using:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
auto monster = GetMonster(buffer_pointer); auto monster = GetMonster(buffer_pointer);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
`monster` is of type `Monster *`, and points to somewhere inside your `monster` is of type `Monster *`, and points to somewhere inside your
buffer. If you look in your generated header, you'll see it has buffer. If you look in your generated header, you'll see it has
convenient accessors for all fields, e.g. convenient accessors for all fields, e.g.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
assert(monster->hp() == 80); assert(monster->hp() == 80);
assert(monster->mana() == 150); // default assert(monster->mana() == 150); // default
assert(strcmp(monster->name()->c_str(), "MyMonster") == 0); assert(strcmp(monster->name()->c_str(), "MyMonster") == 0);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
These should all be true. Note that we never stored a `mana` value, so These should all be true. Note that we never stored a `mana` value, so
it will return the default. it will return the default.
To access sub-objects, in this case the `Vec3`: To access sub-objects, in this case the `Vec3`:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
auto pos = monster->pos(); auto pos = monster->pos();
assert(pos); assert(pos);
assert(pos->z() == 3); assert(pos->z() == 3);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If we had not set the `pos` field during serialization, it would be If we had not set the `pos` field during serialization, it would be
`NULL`. `NULL`.
Similarly, we can access elements of the inventory array: Similarly, we can access elements of the inventory array:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
auto inv = monster->inventory(); auto inv = monster->inventory();
assert(inv); assert(inv);
assert(inv->Get(9) == 9); assert(inv->Get(9) == 9);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### Direct memory access ### Direct memory access
...@@ -175,7 +195,9 @@ is accessed, all reads will end up inside the buffer. ...@@ -175,7 +195,9 @@ is accessed, all reads will end up inside the buffer.
Each root type will have a verification function generated for it, Each root type will have a verification function generated for it,
e.g. for `Monster`, you can call: e.g. for `Monster`, you can call:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
bool ok = VerifyMonsterBuffer(Verifier(buf, len)); bool ok = VerifyMonsterBuffer(Verifier(buf, len));
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if `ok` is true, the buffer is safe to read. if `ok` is true, the buffer is safe to read.
...@@ -237,11 +259,15 @@ Load text (either a schema or json) into an in-memory buffer (there is a ...@@ -237,11 +259,15 @@ Load text (either a schema or json) into an in-memory buffer (there is a
convenient `LoadFile()` utility function in `flatbuffers/util.h` if you convenient `LoadFile()` utility function in `flatbuffers/util.h` if you
wish). Construct a parser: wish). Construct a parser:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
flatbuffers::Parser parser; flatbuffers::Parser parser;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Now you can parse any number of text files in sequence: Now you can parse any number of text files in sequence:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
parser.Parse(text_file.c_str()); parser.Parse(text_file.c_str());
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This works similarly to how the command-line compiler works: a sequence This works similarly to how the command-line compiler works: a sequence
of files parsed by the same `Parser` object allow later files to of files parsed by the same `Parser` object allow later files to
......
...@@ -7,6 +7,7 @@ See `go_test.go` for an example. You import the generated code, read a ...@@ -7,6 +7,7 @@ See `go_test.go` for an example. You import the generated code, read a
FlatBuffer binary file into a `[]byte`, which you pass to the FlatBuffer binary file into a `[]byte`, which you pass to the
`GetRootAsMonster` function: `GetRootAsMonster` function:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.go}
import ( import (
example "MyGame/Example" example "MyGame/Example"
flatbuffers "github.com/google/flatbuffers/go" flatbuffers "github.com/google/flatbuffers/go"
...@@ -17,11 +18,14 @@ FlatBuffer binary file into a `[]byte`, which you pass to the ...@@ -17,11 +18,14 @@ FlatBuffer binary file into a `[]byte`, which you pass to the
buf, err := ioutil.ReadFile("monster.dat") buf, err := ioutil.ReadFile("monster.dat")
// handle err // handle err
monster := example.GetRootAsMonster(buf, 0) monster := example.GetRootAsMonster(buf, 0)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Now you can access values like this: Now you can access values like this:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.go}
hp := monster.Hp() hp := monster.Hp()
pos := monster.Pos(nil) pos := monster.Pos(nil)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Note that whenever you access a new object like in the `Pos` example above, Note that whenever you access a new object like in the `Pos` example above,
a new temporary accessor object gets created. If your code is very performance a new temporary accessor object gets created. If your code is very performance
...@@ -34,21 +38,28 @@ To access vectors you pass an extra index to the ...@@ -34,21 +38,28 @@ To access vectors you pass an extra index to the
vector field accessor. Then a second method with the same name suffixed vector field accessor. Then a second method with the same name suffixed
by `Length` let's you know the number of elements you can access: by `Length` let's you know the number of elements you can access:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.go}
for i := 0; i < monster.InventoryLength(); i++ { for i := 0; i < monster.InventoryLength(); i++ {
monster.Inventory(i) // do something here monster.Inventory(i) // do something here
} }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can also construct these buffers in Go using the functions found in the You can also construct these buffers in Go using the functions found in the
generated code, and the FlatBufferBuilder class: generated code, and the FlatBufferBuilder class:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.go}
builder := flatbuffers.NewBuilder(0) builder := flatbuffers.NewBuilder(0)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Create strings: Create strings:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.go}
str := builder.CreateString("MyMonster") str := builder.CreateString("MyMonster")
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Create a table with a struct contained therein: Create a table with a struct contained therein:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.go}
example.MonsterStart(builder) example.MonsterStart(builder)
example.MonsterAddPos(builder, example.CreateVec3(builder, 1.0, 2.0, 3.0, 3.0, 4, 5, 6)) example.MonsterAddPos(builder, example.CreateVec3(builder, 1.0, 2.0, 3.0, 3.0, 4, 5, 6))
example.MonsterAddHp(builder, 80) example.MonsterAddHp(builder, 80)
...@@ -58,6 +69,7 @@ Create a table with a struct contained therein: ...@@ -58,6 +69,7 @@ Create a table with a struct contained therein:
example.MonsterAddTest(builder, mon2) example.MonsterAddTest(builder, mon2)
example.MonsterAddTest4(builder, test4s) example.MonsterAddTest4(builder, test4s)
mon := example.MonsterEnd(builder) mon := example.MonsterEnd(builder)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Unlike C++, Go does not support table creation functions like 'createMonster()'. Unlike C++, Go does not support table creation functions like 'createMonster()'.
This is to create the buffer without This is to create the buffer without
...@@ -72,11 +84,13 @@ will be `a`, `c` and `d`. ...@@ -72,11 +84,13 @@ will be `a`, `c` and `d`.
Vectors also use this start/end pattern to allow vectors of both scalar types Vectors also use this start/end pattern to allow vectors of both scalar types
and structs: and structs:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.go}
example.MonsterStartInventoryVector(builder, 5) example.MonsterStartInventoryVector(builder, 5)
for i := 4; i >= 0; i-- { for i := 4; i >= 0; i-- {
builder.PrependByte(byte(i)) builder.PrependByte(byte(i))
} }
inv := builder.EndVector(5) inv := builder.EndVector(5)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The generated method 'StartInventoryVector' is provided as a convenience The generated method 'StartInventoryVector' is provided as a convenience
function which calls 'StartVector' with the correct element size of the vector function which calls 'StartVector' with the correct element size of the vector
......
...@@ -7,13 +7,17 @@ See `javaTest.java` for an example. Essentially, you read a FlatBuffer binary ...@@ -7,13 +7,17 @@ See `javaTest.java` for an example. Essentially, you read a FlatBuffer binary
file into a `byte[]`, which you then turn into a `ByteBuffer`, which you pass to file into a `byte[]`, which you then turn into a `ByteBuffer`, which you pass to
the `getRootAsMyRootType` function: the `getRootAsMyRootType` function:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.java}
ByteBuffer bb = ByteBuffer.wrap(data); ByteBuffer bb = ByteBuffer.wrap(data);
Monster monster = Monster.getRootAsMonster(bb); Monster monster = Monster.getRootAsMonster(bb);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Now you can access values much like C++: Now you can access values much like C++:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.java}
short hp = monster.hp(); short hp = monster.hp();
Vec3 pos = monster.pos(); Vec3 pos = monster.pos();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Note that whenever you access a new object like in the `pos` example above, Note that whenever you access a new object like in the `pos` example above,
a new temporary accessor object gets created. If your code is very performance a new temporary accessor object gets created. If your code is very performance
...@@ -39,8 +43,10 @@ Vector access is also a bit different from C++: you pass an extra index ...@@ -39,8 +43,10 @@ Vector access is also a bit different from C++: you pass an extra index
to the vector field accessor. Then a second method with the same name to the vector field accessor. Then a second method with the same name
suffixed by `Length` let's you know the number of elements you can access: suffixed by `Length` let's you know the number of elements you can access:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.java}
for (int i = 0; i < monster.inventoryLength(); i++) for (int i = 0; i < monster.inventoryLength(); i++)
monster.inventory(i); // do something here monster.inventory(i); // do something here
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Alternatively, much like strings, you can use `monster.inventoryAsByteBuffer()` Alternatively, much like strings, you can use `monster.inventoryAsByteBuffer()`
to get a `ByteBuffer` referring to the whole vector. Use `ByteBuffer` methods to get a `ByteBuffer` referring to the whole vector. Use `ByteBuffer` methods
...@@ -49,7 +55,9 @@ like `asFloatBuffer` to get specific views if needed. ...@@ -49,7 +55,9 @@ like `asFloatBuffer` to get specific views if needed.
If you specified a file_indentifier in the schema, you can query if the If you specified a file_indentifier in the schema, you can query if the
buffer is of the desired type before accessing it using: buffer is of the desired type before accessing it using:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.java}
if (Monster.MonsterBufferHasIdentifier(bb)) ... if (Monster.MonsterBufferHasIdentifier(bb)) ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
## Buffer construction in Java ## Buffer construction in Java
...@@ -57,14 +65,19 @@ buffer is of the desired type before accessing it using: ...@@ -57,14 +65,19 @@ buffer is of the desired type before accessing it using:
You can also construct these buffers in Java using the static methods found You can also construct these buffers in Java using the static methods found
in the generated code, and the FlatBufferBuilder class: in the generated code, and the FlatBufferBuilder class:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.java}
FlatBufferBuilder fbb = new FlatBufferBuilder(); FlatBufferBuilder fbb = new FlatBufferBuilder();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Create strings: Create strings:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.java}
int str = fbb.createString("MyMonster"); int str = fbb.createString("MyMonster");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Create a table with a struct contained therein: Create a table with a struct contained therein:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.java}
Monster.startMonster(fbb); Monster.startMonster(fbb);
Monster.addPos(fbb, Vec3.createVec3(fbb, 1.0f, 2.0f, 3.0f, 3.0, (byte)4, (short)5, (byte)6)); Monster.addPos(fbb, Vec3.createVec3(fbb, 1.0f, 2.0f, 3.0f, 3.0, (byte)4, (short)5, (byte)6));
Monster.addHp(fbb, (short)80); Monster.addHp(fbb, (short)80);
...@@ -74,6 +87,7 @@ Create a table with a struct contained therein: ...@@ -74,6 +87,7 @@ Create a table with a struct contained therein:
Monster.addTest(fbb, mon2); Monster.addTest(fbb, mon2);
Monster.addTest4(fbb, test4s); Monster.addTest4(fbb, test4s);
int mon = Monster.endMonster(fbb); int mon = Monster.endMonster(fbb);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For some simpler types, you can use a convenient `create` function call that For some simpler types, you can use a convenient `create` function call that
allows you to construct tables in one function call. This example definition allows you to construct tables in one function call. This example definition
...@@ -94,15 +108,19 @@ case must thus be taken that you set the right offset on the right field. ...@@ -94,15 +108,19 @@ case must thus be taken that you set the right offset on the right field.
Vectors can be created from the corresponding Java array like so: Vectors can be created from the corresponding Java array like so:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.java}
int inv = Monster.createInventoryVector(fbb, new byte[] { 0, 1, 2, 3, 4 }); int inv = Monster.createInventoryVector(fbb, new byte[] { 0, 1, 2, 3, 4 });
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This works for arrays of scalars and (int) offsets to strings/tables, This works for arrays of scalars and (int) offsets to strings/tables,
but not structs. If you want to write structs, or what you want to write but not structs. If you want to write structs, or what you want to write
does not sit in an array, you can also use the start/end pattern: does not sit in an array, you can also use the start/end pattern:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.java}
Monster.startInventoryVector(fbb, 5); Monster.startInventoryVector(fbb, 5);
for (byte i = 4; i >=0; i--) fbb.addByte(i); for (byte i = 4; i >=0; i--) fbb.addByte(i);
int inv = fbb.endVector(); int inv = fbb.endVector();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can use the generated method `startInventoryVector` to conveniently call You can use the generated method `startInventoryVector` to conveniently call
`startVector` with the right element size. You pass the number of `startVector` with the right element size. You pass the number of
...@@ -116,7 +134,9 @@ above in the `Monster` example. ...@@ -116,7 +134,9 @@ above in the `Monster` example.
To finish the buffer, call: To finish the buffer, call:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.java}
Monster.finishMonsterBuffer(fbb, mon); Monster.finishMonsterBuffer(fbb, mon);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The buffer is now ready to be transmitted. It is contained in the `ByteBuffer` The buffer is now ready to be transmitted. It is contained in the `ByteBuffer`
which you can obtain from `fbb.dataBuffer()`. Importantly, the valid data does which you can obtain from `fbb.dataBuffer()`. Importantly, the valid data does
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment