forked from BigfootDev/flatbuffers
FlatBuffers implementation for the Lobster programming language
Language, see: http://strlen.com/lobster/ and https://github.com/aardappel/lobster
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -55,6 +55,7 @@ tests/monsterdata_java_wire.mon
|
||||
tests/monsterdata_java_wire_sp.mon
|
||||
tests/monsterdata_go_wire.mon
|
||||
tests/monsterdata_javascript_wire.mon
|
||||
tests/monsterdata_lobster_wire.mon
|
||||
tests/unicode_test.mon
|
||||
tests/ts/
|
||||
tests/php/
|
||||
|
||||
1
BUILD
1
BUILD
@@ -94,6 +94,7 @@ cc_binary(
|
||||
"src/idl_gen_js.cpp",
|
||||
"src/idl_gen_json_schema.cpp",
|
||||
"src/idl_gen_lua.cpp",
|
||||
"src/idl_gen_lobster.cpp",
|
||||
"src/idl_gen_php.cpp",
|
||||
"src/idl_gen_python.cpp",
|
||||
"src/idl_gen_text.cpp",
|
||||
|
||||
@@ -52,6 +52,7 @@ set(FlatBuffers_Compiler_SRCS
|
||||
src/idl_gen_js.cpp
|
||||
src/idl_gen_php.cpp
|
||||
src/idl_gen_python.cpp
|
||||
src/idl_gen_lobster.cpp
|
||||
src/idl_gen_lua.cpp
|
||||
src/idl_gen_fbs.cpp
|
||||
src/idl_gen_grpc.cpp
|
||||
|
||||
@@ -31,12 +31,18 @@ For any schema input files, one or more generators can be specified:
|
||||
|
||||
- `--js`, `-s`: Generate JavaScript code.
|
||||
|
||||
- `--ts`: Generate TypeScript code.
|
||||
|
||||
- `--php`: Generate PHP code.
|
||||
|
||||
- `--grpc`: Generate RPC stub code for GRPC.
|
||||
|
||||
- `--dart`: Generate Dart code.
|
||||
|
||||
- `--lua`: Generate Lua code.
|
||||
|
||||
- `--lobster`: Generate Lobster code.
|
||||
|
||||
For any data input files:
|
||||
|
||||
- `--binary`, `-b` : If data is contained in this file, generate a
|
||||
|
||||
@@ -4,7 +4,7 @@ FlatBuffers {#flatbuffers_index}
|
||||
# Overview {#flatbuffers_overview}
|
||||
|
||||
[FlatBuffers](@ref flatbuffers_overview) is an efficient cross platform
|
||||
serialization library for C++, C#, C, Go, Java, JavaScript, Lua, TypeScript, PHP, and Python.
|
||||
serialization library for C++, C#, C, Go, Java, JavaScript, Lobster, Lua, TypeScript, PHP, and Python.
|
||||
It was originally created at Google for game development and other
|
||||
performance-critical applications.
|
||||
|
||||
@@ -142,6 +142,8 @@ sections provide a more in-depth usage guide.
|
||||
own programs.
|
||||
- How to [use FlatBuffers in C with `flatcc`](@ref flatbuffers_guide_use_c) in your
|
||||
own programs.
|
||||
- How to [use the generated Lobster code](@ref flatbuffers_guide_use_lobster) in your
|
||||
own programs.
|
||||
- [Support matrix](@ref flatbuffers_support) for platforms/languages/features.
|
||||
- Some [benchmarks](@ref flatbuffers_benchmarks) showing the advantage of
|
||||
using FlatBuffers.
|
||||
|
||||
85
docs/source/LobsterUsage.md
Normal file
85
docs/source/LobsterUsage.md
Normal file
@@ -0,0 +1,85 @@
|
||||
Use in Lobster {#flatbuffers_guide_use_lobster}
|
||||
==============
|
||||
|
||||
## Before you get started
|
||||
|
||||
Before diving into the FlatBuffers usage in Lobster, 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 Lobster). This
|
||||
page is designed to cover the nuances of FlatBuffers usage, specific to
|
||||
Lobster.
|
||||
|
||||
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 Lobster library code location
|
||||
|
||||
The code for the FlatBuffers Lobster library can be found at
|
||||
`flatbuffers/lobster`. You can browse the library code on the
|
||||
[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/
|
||||
lobster).
|
||||
|
||||
## Testing the FlatBuffers Lobster library
|
||||
|
||||
The code to test the Lobster library can be found at `flatbuffers/tests`.
|
||||
The test code itself is located in [lobstertest.lobster](https://github.com/google/
|
||||
flatbuffers/blob/master/tests/lobstertest.lobster).
|
||||
|
||||
To run the tests, run `lobster lobstertest.lobster`. To obtain Lobster itself,
|
||||
go to the [Lobster homepage](http://strlen.com/lobster) or
|
||||
[github](https://github.com/aardappel/lobster) to learn how to build it for your
|
||||
platform.
|
||||
|
||||
## Using the FlatBuffers Lobster library
|
||||
|
||||
*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth
|
||||
example of how to use FlatBuffers in Lobster.*
|
||||
|
||||
There is support for both reading and writing FlatBuffers in Lobster.
|
||||
|
||||
To use FlatBuffers in your own code, first generate Lobster classes from your
|
||||
schema with the `--lobster` 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 Lobster:
|
||||
First, import the library and the generated code. Then read a FlatBuffer binary
|
||||
file into a string, which you pass to the `GetRootAsMonster` function:
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.lobster}
|
||||
include "monster_generated.lobster"
|
||||
|
||||
let fb = read_file("monsterdata_test.mon")
|
||||
assert fb
|
||||
let monster = MyGame_Example_GetRootAsMonster(fb)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Now you can access values like this:
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.lobster}
|
||||
let hp = monster.hp
|
||||
let pos = monster.pos
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
As you can see, even though `hp` and `pos` are functions that access FlatBuffer
|
||||
data in-place in the string buffer, they appear as field accesses.
|
||||
|
||||
## Speed
|
||||
|
||||
Using FlatBuffers in Lobster should be relatively fast, as the implementation
|
||||
makes use of native support for writing binary values, and access of vtables.
|
||||
Both generated code and the runtime library are therefore small and fast.
|
||||
|
||||
Actual speed will depend on wether you use Lobster as bytecode VM or compiled to
|
||||
C++.
|
||||
|
||||
## Text Parsing
|
||||
|
||||
Lobster has full support for parsing JSON into FlatBuffers, or generating
|
||||
JSON from FlatBuffers. See `samples/sample_test.lobster` for an example.
|
||||
|
||||
This uses the C++ parser and generator underneath, so should be both fast and
|
||||
conformant.
|
||||
|
||||
<br>
|
||||
@@ -18,25 +18,25 @@ In general:
|
||||
|
||||
NOTE: this table is a start, it needs to be extended.
|
||||
|
||||
Feature | C++ | Java | C# | Go | Python | JS | TS | C | PHP | Ruby | Dart
|
||||
------------------------------ | ------ | ------ | ------ | ------ | ------ | --------- | --------- | ------ | --- | ---- | ----
|
||||
Codegen for all basic features | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | WiP | WiP | Yes
|
||||
JSON parsing | Yes | No | No | No | No | No | No | Yes | No | No | No
|
||||
Simple mutation | Yes | Yes | Yes | Yes | No | No | No | No | No | No | No
|
||||
Reflection | Yes | No | No | No | No | No | No | Basic | No | No | No
|
||||
Buffer verifier | Yes | No | No | No | No | No | No | Yes | No | No | No
|
||||
Testing: basic | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | ? | ? | Yes
|
||||
Testing: fuzz | Yes | No | No | Yes | Yes | No | No | No | ? | ? | No
|
||||
Performance: | Superb | Great | Great | Great | Ok | ? | ? | Superb | ? | ? | ?
|
||||
Platform: Windows | VS2010 | Yes | Yes | ? | ? | ? | Yes | VS2010 | ? | ? | Yes
|
||||
Platform: Linux | GCC282 | Yes | ? | Yes | Yes | ? | Yes | Yes | ? | ? | Yes
|
||||
Platform: OS X | Xcode4 | ? | ? | ? | Yes | ? | Yes | Yes | ? | ? | Yes
|
||||
Platform: Android | NDK10d | Yes | ? | ? | ? | ? | ? | ? | ? | ? | Flutter
|
||||
Platform: iOS | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | Flutter
|
||||
Engine: Unity | ? | ? | Yes | ? | ? | ? | ? | ? | ? | ? | ?
|
||||
Primary authors (github) | gwvo | gwvo | ev*/js*| rw | rw | evanw/ev* | kr | mik* | ch* | rw | dnfield
|
||||
|
||||
Feature | C++ | Java | C# | Go | Python | JS | TS | C | PHP | Dart | Lobster
|
||||
------------------------------ | ------ | ------ | ------ | ------ | ------ | --------- | --------- | ------ | --- | ------- | -------
|
||||
Codegen for all basic features | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | WiP | Yes | Yes
|
||||
JSON parsing | Yes | No | No | No | No | No | No | Yes | No | No | Yes
|
||||
Simple mutation | Yes | Yes | Yes | Yes | No | No | No | No | No | No | No
|
||||
Reflection | Yes | No | No | No | No | No | No | Basic | No | No | No
|
||||
Buffer verifier | Yes | No | No | No | No | No | No | Yes | No | No | No
|
||||
Testing: basic | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | ? | Yes | Yes
|
||||
Testing: fuzz | Yes | No | No | Yes | Yes | No | No | No | ? | No | No
|
||||
Performance: | Superb | Great | Great | Great | Ok | ? | ? | Superb | ? | ? | Great
|
||||
Platform: Windows | VS2010 | Yes | Yes | ? | ? | ? | Yes | VS2010 | ? | Yes | Yes
|
||||
Platform: Linux | GCC282 | Yes | ? | Yes | Yes | ? | Yes | Yes | ? | Yes | Yes
|
||||
Platform: OS X | Xcode4 | ? | ? | ? | Yes | ? | Yes | Yes | ? | Yes | Yes
|
||||
Platform: Android | NDK10d | Yes | ? | ? | ? | ? | ? | ? | ? | Flutter | Yes
|
||||
Platform: iOS | ? | ? | ? | ? | ? | ? | ? | ? | ? | Flutter | Yes
|
||||
Engine: Unity | ? | ? | Yes | ? | ? | ? | ? | ? | ? | ? | No
|
||||
Primary authors (github) | aard* | aard* | ev*/js*| rw | rw | evanw/ev* | kr* | mik* | ch* | dnfield | aard*
|
||||
|
||||
* aard = aardappel (previously: gwvo)
|
||||
* ev = evolutional
|
||||
* js = jonsimantov
|
||||
* mik = mikkelfj
|
||||
|
||||
@@ -32,6 +32,7 @@ Please select your desired language for our quest:
|
||||
<input type="radio" name="language" value="c">C</input>
|
||||
<input type="radio" name="language" value="dart">Dart</input>
|
||||
<input type="radio" name="language" value="lua">Lua</input>
|
||||
<input type="radio" name="language" value="lobster">Lobster</input>
|
||||
</form>
|
||||
\endhtmlonly
|
||||
|
||||
@@ -138,7 +139,10 @@ For your chosen language, please cross-reference with:
|
||||
[example.dart](https://github.com/google/flatbuffers/blob/master/dart/example/example.dart)
|
||||
</div>
|
||||
<div class="language-lua">
|
||||
[sample_binary.lua](https://github.com/google/flatbuffers/blob/master/dart/example/sample_binary.lua)
|
||||
[sample_binary.lua](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.lua)
|
||||
</div>
|
||||
<div class="language-lobster">
|
||||
[sample_binary.lobster](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.lobster)
|
||||
</div>
|
||||
|
||||
|
||||
@@ -333,6 +337,12 @@ Please be aware of the difference between `flatc` and `flatcc` tools.
|
||||
./../flatc --lua monster.fbs
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-lobster">
|
||||
~~~{.sh}
|
||||
cd flatbuffers/sample
|
||||
./../flatc --lobster monster.fbs
|
||||
~~~
|
||||
</div>
|
||||
|
||||
For a more complete guide to using the `flatc` compiler, please read the
|
||||
[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler)
|
||||
@@ -463,6 +473,12 @@ The first step is to import/include the library, generated files, etc.
|
||||
local weapon = require("MyGame.Sample.Weapon")
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-lobster">
|
||||
~~~{.lobster}
|
||||
include from "../lobster/" // Where to find flatbuffers.lobster
|
||||
include "monster_generated.lobster"
|
||||
~~~
|
||||
</div>
|
||||
|
||||
Now we are ready to start building some buffers. In order to start, we need
|
||||
to create an instance of the `FlatBufferBuilder`, which will contain the buffer
|
||||
@@ -548,6 +564,12 @@ which will grow automatically if needed:
|
||||
local builder = flatbuffers.Builder(1024)
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-lobster">
|
||||
~~~{.lobster}
|
||||
-- get access to the builder
|
||||
let builder = flatbuffers_builder {}
|
||||
~~~
|
||||
</div>
|
||||
|
||||
After creating the `builder`, we can start serializing our data. Before we make
|
||||
our `orc` Monster, lets create some `Weapon`s: a `Sword` and an `Axe`.
|
||||
@@ -753,6 +775,19 @@ our `orc` Monster, lets create some `Weapon`s: a `Sword` and an `Axe`.
|
||||
local axe = weapon.End(builder)
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-lobster">
|
||||
~~~{.lobster}
|
||||
let weapon_names = [ "Sword", "Axe" ]
|
||||
let weapon_damages = [ 3, 5 ]
|
||||
|
||||
weapon_offsets := map(weapon_names) name, i:
|
||||
let ns = builder.CreateString(name)
|
||||
builder.MyGame_Sample_WeaponStart()
|
||||
builder.MyGame_Sample_WeaponAddName(ns)
|
||||
builder.MyGame_Sample_WeaponAddDamage(weapon_damages[i])
|
||||
builder.MyGame_Sample_WeaponEnd()
|
||||
~~~
|
||||
</div>
|
||||
|
||||
Now let's create our monster, the `orc`. For this `orc`, lets make him
|
||||
`red` with rage, positioned at `(1.0, 2.0, 3.0)`, and give him
|
||||
@@ -915,6 +950,15 @@ traversal. This is generally easy to do on any tree structures.
|
||||
local inv = builder:EndVector(10)
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-lobster">
|
||||
~~~{.lobster}
|
||||
// Name of the monster.
|
||||
let name = builder.CreateString("Orc")
|
||||
|
||||
// Inventory.
|
||||
let inv = builder.MyGame_Sample_MonsterCreateInventoryVector(map(10): _)
|
||||
~~~
|
||||
</div>
|
||||
|
||||
We serialized two built-in data types (`string` and `vector`) and captured
|
||||
their return values. These values are offsets into the serialized data,
|
||||
@@ -1037,6 +1081,11 @@ offsets.
|
||||
local weapons = builder:EndVector(2)
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-lobster">
|
||||
~~~{.lobster}
|
||||
let weapons = builder.MyGame_Sample_MonsterCreateWeaponsVector(weapon_offsets)
|
||||
~~~
|
||||
</div>
|
||||
|
||||
<div class="language-cpp">
|
||||
<br>
|
||||
@@ -1146,6 +1195,14 @@ for the `path` field above:
|
||||
local path = builder:EndVector(2)
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-lobster">
|
||||
~~~{.lobster}
|
||||
builder.MyGame_Sample_MonsterStartPathVector(2)
|
||||
builder.MyGame_Sample_CreateVec3(1.0, 2.0, 3.0)
|
||||
builder.MyGame_Sample_CreateVec3(4.0, 5.0, 6.0)
|
||||
let path = builder.EndVector(2)
|
||||
~~~
|
||||
</div>
|
||||
|
||||
We have now serialized the non-scalar components of the orc, so we
|
||||
can serialize the monster itself:
|
||||
@@ -1366,6 +1423,21 @@ can serialize the monster itself:
|
||||
local orc = monster.End(builder)
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-lobster">
|
||||
~~~{.lobster}
|
||||
builder.MyGame_Sample_MonsterStart()
|
||||
builder.MyGame_Sample_MonsterAddPos(builder.MyGame_Sample_CreateVec3(1.0, 2.0, 3.0))
|
||||
builder.MyGame_Sample_MonsterAddHp(300)
|
||||
builder.MyGame_Sample_MonsterAddName(name)
|
||||
builder.MyGame_Sample_MonsterAddInventory(inv)
|
||||
builder.MyGame_Sample_MonsterAddColor(MyGame_Sample_Color_Red)
|
||||
builder.MyGame_Sample_MonsterAddWeapons(weapons)
|
||||
builder.MyGame_Sample_MonsterAddEquippedType(MyGame_Sample_Equipment_Weapon)
|
||||
builder.MyGame_Sample_MonsterAddEquipped(weapon_offsets[1])
|
||||
builder.MyGame_Sample_MonsterAddPath(path)
|
||||
let orc = builder.MyGame_Sample_MonsterEnd()
|
||||
~~~
|
||||
</div>
|
||||
|
||||
Note how we create `Vec3` struct in-line in the table. Unlike tables, structs
|
||||
are simple combinations of scalars that are always stored inline, just like
|
||||
@@ -1514,6 +1586,12 @@ Here is a repetition these lines, to help highlight them more clearly:
|
||||
monster.AddEquipped(builder, axe) -- Union data
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-lobster">
|
||||
~~~{.lobster}
|
||||
builder.MyGame_Sample_MonsterAddEquippedType(MyGame_Sample_Equipment_Weapon)
|
||||
builder.MyGame_Sample_MonsterAddEquipped(axe)
|
||||
~~~
|
||||
</div>
|
||||
|
||||
After you have created your buffer, you will have the offset to the root of the
|
||||
data in the `orc` variable, so you can finish the buffer by calling the
|
||||
@@ -1591,7 +1669,12 @@ appropriate `finish` method.
|
||||
builder:Finish(orc)
|
||||
~~~
|
||||
</div>
|
||||
|
||||
<div class="language-lobster">
|
||||
~~~{.lobster}
|
||||
// Call `Finish()` to instruct the builder that this monster is complete.
|
||||
builder.Finish(orc)
|
||||
~~~
|
||||
</div>
|
||||
|
||||
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 buffer
|
||||
@@ -1695,6 +1778,12 @@ like so:
|
||||
local bufAsString = builder:Output()
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-lobster">
|
||||
~~~{.lobster}
|
||||
// This must be called after `Finish()`.
|
||||
let buf = builder.SizedCopy() // Of type `string`.
|
||||
~~~
|
||||
</div>
|
||||
|
||||
|
||||
Now you can write the bytes to a file, send them over the network..
|
||||
@@ -1706,7 +1795,7 @@ which will lead to hard to find problems when you read the buffer.
|
||||
|
||||
Now that we have successfully created an `Orc` FlatBuffer, the monster data can
|
||||
be saved, sent over a network, etc. Let's now adventure into the inverse, and
|
||||
deserialize a FlatBuffer.
|
||||
access a FlatBuffer.
|
||||
|
||||
This section requires the same import/include, namespace, etc. requirements as
|
||||
before:
|
||||
@@ -1822,6 +1911,12 @@ import './monster_my_game.sample_generated.dart' as myGame;
|
||||
local weapon = require("MyGame.Sample.Weapon")
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-lobster">
|
||||
~~~{.lobster}
|
||||
include from "../lobster/" // Where to find flatbuffers.lobster
|
||||
include "monster_generated.lobster"
|
||||
~~~
|
||||
</div>
|
||||
|
||||
Then, assuming you have a buffer of bytes received from disk,
|
||||
network, etc., you can create start accessing the buffer like so:
|
||||
@@ -1941,6 +2036,14 @@ myGame.Monster monster = new myGame.Monster(data);
|
||||
local mon = monster.GetRootAsMonster(buf, 0)
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-lobster">
|
||||
~~~{.lobster}
|
||||
buf = /* the data you just read, in a string */
|
||||
|
||||
// Get an accessor to the root object inside the buffer.
|
||||
let monster = MyGame_Sample_GetRootAsMonster(buf)
|
||||
~~~
|
||||
</div>
|
||||
|
||||
If you look in the generated files from the schema compiler, you will see it generated
|
||||
accessors for all non-`deprecated` fields. For example:
|
||||
@@ -2026,6 +2129,13 @@ accessors for all non-`deprecated` fields. For example:
|
||||
local name = mon:Name()
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-lobster">
|
||||
~~~{.lobster}
|
||||
let hp = monster.hp
|
||||
let mana = monster.mana
|
||||
let name = monster.name
|
||||
~~~
|
||||
</div>
|
||||
|
||||
These should hold `300`, `150`, and `"Orc"` respectively.
|
||||
|
||||
@@ -2127,7 +2237,14 @@ To access sub-objects, in the case of our `pos`, which is a `Vec3`:
|
||||
local z = pos:Z()
|
||||
~~~
|
||||
</div>
|
||||
|
||||
<div class="language-lobster">
|
||||
~~~{.lobster}
|
||||
let pos = monster.pos
|
||||
let x = pos.x
|
||||
let y = pos.y
|
||||
let z = pos.z
|
||||
~~~
|
||||
</div>
|
||||
|
||||
`x`, `y`, and `z` will contain `1.0`, `2.0`, and `3.0`, respectively.
|
||||
|
||||
@@ -2206,6 +2323,12 @@ FlatBuffers `vector`.
|
||||
local thirdItem = mon:Inventory(3) -- Lua is 1-based
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-lobster">
|
||||
~~~{.lobster}
|
||||
let inv_len = monster.inventory_length
|
||||
let third_item = monster.inventory(2)
|
||||
~~~
|
||||
</div>
|
||||
|
||||
For `vector`s of `table`s, you can access the elements like any other vector,
|
||||
except your need to handle the result as a FlatBuffer `table`:
|
||||
@@ -2294,6 +2417,13 @@ except your need to handle the result as a FlatBuffer `table`:
|
||||
local secondWeaponDamage = mon:Weapon(2):Damage()
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-lobster">
|
||||
~~~{.lobster}
|
||||
let weapons_length = monster.weapons_length
|
||||
let second_weapon_name = monster.weapons(1).name
|
||||
let second_weapon_damage = monster.weapons(1).damage
|
||||
~~~
|
||||
</div>
|
||||
|
||||
Last, we can access our `Equipped` FlatBuffer `union`. Just like when we created
|
||||
the `union`, we need to get both parts of the `union`: the type and the data.
|
||||
@@ -2442,6 +2572,19 @@ We can access the type to dynamically cast the data as needed (since the
|
||||
end
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-lobster">
|
||||
~~~{.lobster}
|
||||
union_type = monster.equipped_type
|
||||
|
||||
if union_type == MyGame_Sample_Equipment_Weapon:
|
||||
// `monster.equipped_as_Weapon` returns a FlatBuffer handle much like normal table fields,
|
||||
// but this is only valid to call if we already know it is the correct type.
|
||||
let union_weapon = monster.equipped_as_Weapon
|
||||
|
||||
let weapon_name = union_weapon.name // "Axe"
|
||||
let weapon_damage = union_weapon.damage // 5
|
||||
~~~
|
||||
</div>
|
||||
|
||||
## Mutating FlatBuffers
|
||||
|
||||
@@ -2527,6 +2670,11 @@ mutators like so:
|
||||
<API for mutating FlatBuffers is not yet available in Lua.>
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-lobster">
|
||||
~~~{.lobster}
|
||||
<API for mutating FlatBuffers is not yet available in Lobster.>
|
||||
~~~
|
||||
</div>
|
||||
|
||||
We use the somewhat verbose term `mutate` instead of `set` to indicate that this
|
||||
is a special use case, not to be confused with the default way of constructing
|
||||
@@ -2601,6 +2749,11 @@ printers that you can compile and use at runtime. The `flatc` compiler (not
|
||||
flatbuffer conversion from a given schema. There are no current plans
|
||||
for `flatcc` to support this.*
|
||||
</div>
|
||||
<div class="language-lobster">
|
||||
*Note: If you're working in Lobster, you can also parse JSON at runtime. See the
|
||||
[Use in Lobster](@ref flatbuffers_guide_use_lobster) section of the Programmer's
|
||||
Guide for more information.*
|
||||
</div>
|
||||
|
||||
## Advanced Features for Each Language
|
||||
|
||||
@@ -2642,6 +2795,8 @@ For your chosen language, see:
|
||||
<div class="language-lua">
|
||||
[Use in Lua](@ref flatbuffers_guide_use_lua)
|
||||
</div>
|
||||
|
||||
<div class="language-lobster">
|
||||
[Use in Lobster](@ref flatbuffers_guide_use_lobster)
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
@@ -759,6 +759,7 @@ INPUT = "FlatBuffers.md" \
|
||||
"PHPUsage.md" \
|
||||
"PythonUsage.md" \
|
||||
"LuaUsage.md" \
|
||||
"LobsterUsage.md" \
|
||||
"Support.md" \
|
||||
"Benchmarks.md" \
|
||||
"WhitePaper.md" \
|
||||
|
||||
@@ -43,6 +43,8 @@
|
||||
title="Use in Dart"/>
|
||||
<tab type="user" url="@ref flatbuffers_guide_use_lua"
|
||||
title="Use in Lua"/>
|
||||
<tab type="user" url="@ref flatbuffers_guide_use_lobster"
|
||||
title="Use in Lobster"/>
|
||||
<tab type="user" url="@ref flexbuffers"
|
||||
title="Schema-less version"/>
|
||||
<tab type="usergroup" url="" title="gRPC">
|
||||
|
||||
@@ -409,6 +409,7 @@ struct IDLOptions {
|
||||
kJsonSchema = 1 << 10,
|
||||
kDart = 1 << 11,
|
||||
kLua = 1 << 12,
|
||||
kLobster = 1 << 13,
|
||||
kMAX
|
||||
};
|
||||
|
||||
@@ -820,6 +821,12 @@ extern bool GeneratePython(const Parser &parser,
|
||||
const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
// Generate Lobster files from the definitions in the Parser object.
|
||||
// See idl_gen_lobster.cpp.
|
||||
extern bool GenerateLobster(const Parser &parser,
|
||||
const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
// Generate Lua files from the definitions in the Parser object.
|
||||
// See idl_gen_lua.cpp.
|
||||
extern bool GenerateLua(const Parser &parser,
|
||||
|
||||
278
lobster/flatbuffers.lobster
Normal file
278
lobster/flatbuffers.lobster
Normal file
@@ -0,0 +1,278 @@
|
||||
// Copyright 2018 Google Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
include "std.lobster"
|
||||
|
||||
namespace flatbuffers
|
||||
|
||||
struct handle:
|
||||
buf_:string
|
||||
pos_:int
|
||||
|
||||
enum + sz_8 = 1,
|
||||
sz_16 = 2,
|
||||
sz_32 = 4,
|
||||
sz_64 = 8,
|
||||
sz_voffset = 2,
|
||||
sz_uoffset = 4,
|
||||
sz_soffset = 4,
|
||||
sz_metadata_fields = 2
|
||||
|
||||
struct builder:
|
||||
buf:string = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
current_vtable:[int] = []
|
||||
head:int = 0
|
||||
minalign:int = 1
|
||||
object_end:int = 0
|
||||
vtables:[int] = []
|
||||
nested:int = false
|
||||
finished:int = false
|
||||
|
||||
// Optionally call this right after creating the builder for a larger initial buffer.
|
||||
def Initial(initial_size:int):
|
||||
buf = "\x00".repeat_string(initial_size)
|
||||
|
||||
def Start():
|
||||
// Get the start of useful data in the underlying byte buffer.
|
||||
return buf.length - head
|
||||
|
||||
def Offset():
|
||||
// Offset relative to the end of the buffer.
|
||||
return head
|
||||
|
||||
// Returns a copy of the part of the buffer containing only the finished FlatBuffer
|
||||
def SizedCopy():
|
||||
assert finished
|
||||
return buf.substring(Start(), -1)
|
||||
|
||||
def StartNesting():
|
||||
assert not nested
|
||||
nested = true
|
||||
|
||||
def EndNesting():
|
||||
assert nested
|
||||
nested = false
|
||||
|
||||
def StartObject(numfields):
|
||||
StartNesting()
|
||||
current_vtable = map(numfields): 0
|
||||
object_end = head
|
||||
minalign = 1
|
||||
|
||||
def EndObject():
|
||||
EndNesting()
|
||||
// Prepend a zero scalar to the object. Later in this function we'll
|
||||
// write an offset here that points to the object's vtable:
|
||||
PrependInt32(0)
|
||||
object_offset := head
|
||||
// Write out new vtable speculatively.
|
||||
vtable_size := (current_vtable.length + sz_metadata_fields) * sz_voffset
|
||||
while current_vtable.length:
|
||||
o := current_vtable.pop()
|
||||
PrependVOffsetT(if o: object_offset - o else: 0)
|
||||
// The two metadata fields are written last.
|
||||
// First, store the object bytesize:
|
||||
PrependVOffsetT(object_offset - object_end)
|
||||
// Second, store the vtable bytesize:
|
||||
PrependVOffsetT(vtable_size)
|
||||
// Search backwards through existing vtables, because similar vtables
|
||||
// are likely to have been recently appended. See
|
||||
// BenchmarkVtableDeduplication for a case in which this heuristic
|
||||
// saves about 30% of the time used in writing objects with duplicate
|
||||
// tables.
|
||||
existing_vtable := do():
|
||||
reverse(vtables) vt2_offset:
|
||||
// Find the other vtable:
|
||||
vt2_start := buf.length - vt2_offset
|
||||
vt2_len := buf.read_int16_le(vt2_start)
|
||||
// Compare the other vtable to the one under consideration.
|
||||
// If they are equal, return the offset:
|
||||
if vtable_size == vt2_len and
|
||||
not compare_substring(buf, Start(), buf, vt2_start, vtable_size):
|
||||
return vt2_offset from do
|
||||
0
|
||||
if existing_vtable:
|
||||
// Found a duplicate vtable, remove the one we wrote.
|
||||
head = object_offset
|
||||
// Write the offset to the found vtable in the
|
||||
// already-allocated offset at the beginning of this object:
|
||||
buf.write_int32_le(Start(), existing_vtable - object_offset)
|
||||
else:
|
||||
// Did not find a vtable, so keep the one we wrote.
|
||||
// Next, write the offset to the new vtable in the
|
||||
// already-allocated offset at the beginning of this object:
|
||||
buf.write_int32_le(buf.length - object_offset, head - object_offset)
|
||||
// Finally, store this vtable in memory for future
|
||||
// deduplication:
|
||||
vtables.push(head)
|
||||
return object_offset
|
||||
|
||||
def Pad(n):
|
||||
for(n): buf, head = buf.write_int8_le_back(head, 0)
|
||||
|
||||
def Prep(size, additional_bytes):
|
||||
// Track the biggest thing we've ever aligned to.
|
||||
if size > minalign:
|
||||
minalign = size
|
||||
// Find the amount of alignment needed such that `size` is properly
|
||||
// aligned after `additionalBytes`:
|
||||
align_size := ((~(head + additional_bytes)) + 1) & (size - 1)
|
||||
Pad(align_size)
|
||||
|
||||
def PrependUOffsetTRelative(off):
|
||||
// Prepends an unsigned offset into vector data, relative to where it will be written.
|
||||
Prep(sz_uoffset, 0)
|
||||
assert off <= head
|
||||
PlaceUOffsetT(head - off + sz_uoffset)
|
||||
|
||||
def StartVector(elem_size, num_elems, alignment):
|
||||
// Initializes bookkeeping for writing a new vector.
|
||||
StartNesting()
|
||||
Prep(sz_32, elem_size * num_elems)
|
||||
Prep(alignment, elem_size * num_elems) // In case alignment > int.
|
||||
return head
|
||||
|
||||
def EndVector(vector_num_elems):
|
||||
EndNesting()
|
||||
// we already made space for this, so write without PrependUint32
|
||||
PlaceUOffsetT(vector_num_elems)
|
||||
return head
|
||||
|
||||
def CreateString(s:string):
|
||||
// writes a null-terminated byte string.
|
||||
StartNesting()
|
||||
Prep(sz_32, s.length + 1)
|
||||
buf, head = buf.write_substring_back(head, s, true)
|
||||
return EndVector(s.length)
|
||||
|
||||
def CreateByteVector(s:string):
|
||||
// writes a non-null-terminated byte string.
|
||||
StartNesting()
|
||||
Prep(sz_32, s.length)
|
||||
buf, head = buf.write_substring_back(head, s, false)
|
||||
return EndVector(s.length)
|
||||
|
||||
def Slot(slotnum):
|
||||
assert nested
|
||||
while current_vtable.length <= slotnum: current_vtable.push(0)
|
||||
current_vtable[slotnum] = head
|
||||
|
||||
def __Finish(root_table:int, size_prefix:int):
|
||||
// Finish finalizes a buffer, pointing to the given root_table
|
||||
assert not finished
|
||||
assert not nested
|
||||
prep_size := sz_32
|
||||
if size_prefix:
|
||||
prep_size += sz_32
|
||||
Prep(minalign, prep_size)
|
||||
PrependUOffsetTRelative(root_table)
|
||||
if size_prefix:
|
||||
PrependInt32(head)
|
||||
finished = true
|
||||
return Start()
|
||||
|
||||
def Finish(root_table:int):
|
||||
return __Finish(root_table, false)
|
||||
|
||||
def FinishSizePrefixed(root_table:int):
|
||||
return __Finish(root_table, true)
|
||||
|
||||
def PrependBool(x):
|
||||
buf, head = buf.write_int8_le_back(head, x)
|
||||
|
||||
def PrependByte(x):
|
||||
buf, head = buf.write_int8_le_back(head, x)
|
||||
|
||||
def PrependUint8(x):
|
||||
buf, head = buf.write_int8_le_back(head, x)
|
||||
|
||||
def PrependUint16(x):
|
||||
Prep(sz_16, 0)
|
||||
buf, head = buf.write_int16_le_back(head, x)
|
||||
|
||||
def PrependUint32(x):
|
||||
Prep(sz_32, 0)
|
||||
buf, head = buf.write_int32_le_back(head, x)
|
||||
|
||||
def PrependUint64(x):
|
||||
Prep(sz_64, 0)
|
||||
buf, head = buf.write_int64_le_back(head, x)
|
||||
|
||||
def PrependInt8(x):
|
||||
buf, head = buf.write_int8_le_back(head, x)
|
||||
|
||||
def PrependInt16(x):
|
||||
Prep(sz_16, 0)
|
||||
buf, head = buf.write_int16_le_back(head, x)
|
||||
|
||||
def PrependInt32(x):
|
||||
Prep(sz_32, 0)
|
||||
buf, head = buf.write_int32_le_back(head, x)
|
||||
|
||||
def PrependInt64(x):
|
||||
Prep(sz_64, 0)
|
||||
buf, head = buf.write_int64_le_back(head, x)
|
||||
|
||||
def PrependFloat32(x):
|
||||
Prep(sz_32, 0)
|
||||
buf, head = buf.write_float32_le_back(head, x)
|
||||
|
||||
def PrependFloat64(x):
|
||||
Prep(sz_64, 0)
|
||||
buf, head = buf.write_float64_le_back(head, x)
|
||||
|
||||
def PrependVOffsetT(x):
|
||||
Prep(sz_voffset, 0)
|
||||
buf, head = buf.write_int16_le_back(head, x)
|
||||
|
||||
def PlaceVOffsetT(x):
|
||||
buf, head = buf.write_int16_le_back(head, x)
|
||||
|
||||
def PlaceSOffsetT(x):
|
||||
buf, head = buf.write_int32_le_back(head, x)
|
||||
|
||||
def PlaceUOffsetT(x):
|
||||
buf, head = buf.write_int32_le_back(head, x)
|
||||
|
||||
def PrependSlot(o:int, x, d, f):
|
||||
if x != d:
|
||||
f(x)
|
||||
Slot(o)
|
||||
|
||||
def PrependBoolSlot(o, x, d): PrependSlot(o, x, d): PrependBool(_)
|
||||
def PrependByteSlot(o, x, d): PrependSlot(o, x, d): PrependByte(_)
|
||||
def PrependUint8Slot(o, x, d): PrependSlot(o, x, d): PrependUint8(_)
|
||||
def PrependUint16Slot(o, x, d): PrependSlot(o, x, d): PrependUint16(_)
|
||||
def PrependUint32Slot(o, x, d): PrependSlot(o, x, d): PrependUint32(_)
|
||||
def PrependUint64Slot(o, x, d): PrependSlot(o, x, d): PrependUint64(_)
|
||||
def PrependInt8Slot(o, x, d): PrependSlot(o, x, d): PrependInt8(_)
|
||||
def PrependInt16Slot(o, x, d): PrependSlot(o, x, d): PrependInt16(_)
|
||||
def PrependInt32Slot(o, x, d): PrependSlot(o, x, d): PrependInt32(_)
|
||||
def PrependInt64Slot(o, x, d): PrependSlot(o, x, d): PrependInt64(_)
|
||||
def PrependFloat32Slot(o, x, d): PrependSlot(o, x, d): PrependFloat32(_)
|
||||
def PrependFloat64Slot(o, x, d): PrependSlot(o, x, d): PrependFloat64(_)
|
||||
|
||||
def PrependUOffsetTRelativeSlot(o, x, d):
|
||||
if x != d:
|
||||
PrependUOffsetTRelative(x)
|
||||
Slot(o)
|
||||
|
||||
def PrependStructSlot(v, x, d):
|
||||
if x != d:
|
||||
// Structs are always stored inline, so need to be created right
|
||||
// where they are used. You'll get this error if you created it
|
||||
//elsewhere.
|
||||
assert x == head
|
||||
Slot(v)
|
||||
|
||||
115
samples/monster_generated.lobster
Normal file
115
samples/monster_generated.lobster
Normal file
@@ -0,0 +1,115 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
include "flatbuffers.lobster"
|
||||
|
||||
namespace MyGame_Sample
|
||||
|
||||
enum +
|
||||
Color_Red = 0,
|
||||
Color_Green = 1,
|
||||
Color_Blue = 2
|
||||
|
||||
enum +
|
||||
Equipment_NONE = 0,
|
||||
Equipment_Weapon = 1
|
||||
|
||||
struct Vec3
|
||||
|
||||
struct Monster
|
||||
|
||||
struct Weapon
|
||||
|
||||
struct Vec3 : flatbuffers_handle
|
||||
def x():
|
||||
buf_.read_float32_le(pos_ + 0)
|
||||
def y():
|
||||
buf_.read_float32_le(pos_ + 4)
|
||||
def z():
|
||||
buf_.read_float32_le(pos_ + 8)
|
||||
|
||||
def CreateVec3(b_:flatbuffers_builder, x:float, y:float, z:float):
|
||||
b_.Prep(4, 12)
|
||||
b_.PrependFloat32(z)
|
||||
b_.PrependFloat32(y)
|
||||
b_.PrependFloat32(x)
|
||||
return b_.Offset()
|
||||
|
||||
struct Monster : flatbuffers_handle
|
||||
def pos():
|
||||
o := buf_.flatbuffers_field_struct(pos_, 4)
|
||||
if o: MyGame_Sample_Vec3 { buf_, o } else: nil
|
||||
def mana():
|
||||
buf_.flatbuffers_field_int16(pos_, 6, 150)
|
||||
def hp():
|
||||
buf_.flatbuffers_field_int16(pos_, 8, 100)
|
||||
def name():
|
||||
buf_.flatbuffers_field_string(pos_, 10)
|
||||
def inventory(i:int):
|
||||
buf_.read_int8_le(buf_.flatbuffers_field_vector(pos_, 14) + i * 1)
|
||||
def inventory_length():
|
||||
buf_.flatbuffers_field_vector_len(pos_, 14)
|
||||
def color():
|
||||
buf_.flatbuffers_field_int8(pos_, 16, 2)
|
||||
def weapons(i:int):
|
||||
MyGame_Sample_Weapon { buf_, buf_.flatbuffers_indirect(buf_.flatbuffers_field_vector(pos_, 18) + i * 4) }
|
||||
def weapons_length():
|
||||
buf_.flatbuffers_field_vector_len(pos_, 18)
|
||||
def equipped_type():
|
||||
buf_.flatbuffers_field_int8(pos_, 20, 0)
|
||||
def equipped_as_Weapon():
|
||||
MyGame_Sample_Weapon { buf_, buf_.flatbuffers_field_table(pos_, 22) }
|
||||
|
||||
def GetRootAsMonster(buf:string): Monster { buf, buf.flatbuffers_indirect(0) }
|
||||
|
||||
def MonsterStart(b_:flatbuffers_builder):
|
||||
b_.StartObject(10)
|
||||
def MonsterAddPos(b_:flatbuffers_builder, pos:int):
|
||||
b_.PrependStructSlot(0, pos, 0)
|
||||
def MonsterAddMana(b_:flatbuffers_builder, mana:int):
|
||||
b_.PrependInt16Slot(1, mana, 150)
|
||||
def MonsterAddHp(b_:flatbuffers_builder, hp:int):
|
||||
b_.PrependInt16Slot(2, hp, 100)
|
||||
def MonsterAddName(b_:flatbuffers_builder, name:int):
|
||||
b_.PrependUOffsetTRelativeSlot(3, name, 0)
|
||||
def MonsterAddInventory(b_:flatbuffers_builder, inventory:int):
|
||||
b_.PrependUOffsetTRelativeSlot(5, inventory, 0)
|
||||
def MonsterStartInventoryVector(b_:flatbuffers_builder, n_:int):
|
||||
b_.StartVector(1, n_, 1)
|
||||
def MonsterCreateInventoryVector(b_:flatbuffers_builder, v_:[int]):
|
||||
b_.StartVector(1, v_.length, 1)
|
||||
reverse(v_) e_: b_.PrependUint8(e_)
|
||||
b_.EndVector(v_.length)
|
||||
def MonsterAddColor(b_:flatbuffers_builder, color:int):
|
||||
b_.PrependInt8Slot(6, color, 2)
|
||||
def MonsterAddWeapons(b_:flatbuffers_builder, weapons:int):
|
||||
b_.PrependUOffsetTRelativeSlot(7, weapons, 0)
|
||||
def MonsterStartWeaponsVector(b_:flatbuffers_builder, n_:int):
|
||||
b_.StartVector(4, n_, 4)
|
||||
def MonsterCreateWeaponsVector(b_:flatbuffers_builder, v_:[int]):
|
||||
b_.StartVector(4, v_.length, 4)
|
||||
reverse(v_) e_: b_.PrependUOffsetTRelative(e_)
|
||||
b_.EndVector(v_.length)
|
||||
def MonsterAddEquippedType(b_:flatbuffers_builder, equipped_type:int):
|
||||
b_.PrependUint8Slot(8, equipped_type, 0)
|
||||
def MonsterAddEquipped(b_:flatbuffers_builder, equipped:int):
|
||||
b_.PrependUOffsetTRelativeSlot(9, equipped, 0)
|
||||
def MonsterEnd(b_:flatbuffers_builder):
|
||||
b_.EndObject()
|
||||
|
||||
struct Weapon : flatbuffers_handle
|
||||
def name():
|
||||
buf_.flatbuffers_field_string(pos_, 4)
|
||||
def damage():
|
||||
buf_.flatbuffers_field_int16(pos_, 6, 0)
|
||||
|
||||
def GetRootAsWeapon(buf:string): Weapon { buf, buf.flatbuffers_indirect(0) }
|
||||
|
||||
def WeaponStart(b_:flatbuffers_builder):
|
||||
b_.StartObject(2)
|
||||
def WeaponAddName(b_:flatbuffers_builder, name:int):
|
||||
b_.PrependUOffsetTRelativeSlot(0, name, 0)
|
||||
def WeaponAddDamage(b_:flatbuffers_builder, damage:int):
|
||||
b_.PrependInt16Slot(1, damage, 0)
|
||||
def WeaponEnd(b_:flatbuffers_builder):
|
||||
b_.EndObject()
|
||||
|
||||
@@ -1,25 +1,24 @@
|
||||
{
|
||||
pos: {
|
||||
x: 1,
|
||||
y: 2,
|
||||
z: 3
|
||||
x: 1.0,
|
||||
y: 2.0,
|
||||
z: 3.0
|
||||
},
|
||||
hp: 300,
|
||||
name: "Orc",
|
||||
weapons:[
|
||||
weapons: [
|
||||
{
|
||||
name: "axe",
|
||||
damage:100
|
||||
damage: 100
|
||||
},
|
||||
{
|
||||
name: "bow",
|
||||
damage:90
|
||||
damage: 90
|
||||
}
|
||||
],
|
||||
equipped_type: "Weapon",
|
||||
equipped:
|
||||
{
|
||||
name: "bow",
|
||||
damage:90
|
||||
}
|
||||
equipped: {
|
||||
name: "bow",
|
||||
damage: 90
|
||||
}
|
||||
}
|
||||
|
||||
98
samples/sample_binary.lobster
Normal file
98
samples/sample_binary.lobster
Normal file
@@ -0,0 +1,98 @@
|
||||
// Copyright 2018 Google Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
include from "../lobster/"
|
||||
include "monster_generated.lobster"
|
||||
|
||||
// Example of how to use FlatBuffers to create and read binary buffers.
|
||||
|
||||
// Create a builder.
|
||||
let b = flatbuffers_builder {}
|
||||
|
||||
// Create some weapons for our monster.
|
||||
let weapon_names = [ "Sword", "Axe" ]
|
||||
let weapon_damages = [ 3, 5 ]
|
||||
|
||||
weapon_offsets := map(weapon_names) name, i:
|
||||
let ns = b.CreateString(name)
|
||||
b.MyGame_Sample_WeaponStart()
|
||||
b.MyGame_Sample_WeaponAddName(ns)
|
||||
b.MyGame_Sample_WeaponAddDamage(weapon_damages[i])
|
||||
b.MyGame_Sample_WeaponEnd()
|
||||
|
||||
let weapons = b.MyGame_Sample_MonsterCreateWeaponsVector(weapon_offsets)
|
||||
|
||||
// Name of the monster.
|
||||
let name = b.CreateString("Orc")
|
||||
|
||||
// Inventory.
|
||||
let inv = b.MyGame_Sample_MonsterCreateInventoryVector(map(10): _)
|
||||
|
||||
// Now pack it all together in our root monster object.
|
||||
b.MyGame_Sample_MonsterStart()
|
||||
b.MyGame_Sample_MonsterAddPos(b.MyGame_Sample_CreateVec3(1.0, 2.0, 3.0))
|
||||
b.MyGame_Sample_MonsterAddHp(300)
|
||||
b.MyGame_Sample_MonsterAddName(name)
|
||||
b.MyGame_Sample_MonsterAddInventory(inv)
|
||||
b.MyGame_Sample_MonsterAddColor(MyGame_Sample_Color_Red)
|
||||
b.MyGame_Sample_MonsterAddWeapons(weapons)
|
||||
b.MyGame_Sample_MonsterAddEquippedType(MyGame_Sample_Equipment_Weapon)
|
||||
b.MyGame_Sample_MonsterAddEquipped(weapon_offsets[1])
|
||||
let orc = b.MyGame_Sample_MonsterEnd()
|
||||
|
||||
// Finish the buffer!
|
||||
b.Finish(orc)
|
||||
|
||||
// We now have a FlatBuffer that we could store on disk or send over a network.
|
||||
|
||||
let buf = b.SizedCopy()
|
||||
|
||||
// ...Saving to file or sending over a network code goes here...
|
||||
|
||||
// Instead, we are going to access this buffer right away (as if we just
|
||||
// received it).
|
||||
|
||||
// Get the root object accessor.
|
||||
let monster = MyGame_Sample_GetRootAsMonster(buf)
|
||||
|
||||
// Note: We did not set the `mana` field explicitly, so we get a default value.
|
||||
assert monster.mana == 150
|
||||
assert monster.hp == 300
|
||||
assert monster.name == "Orc"
|
||||
assert monster.color == MyGame_Sample_Color_Red
|
||||
let pos = monster.pos
|
||||
assert pos
|
||||
assert pos.x == 1.0
|
||||
assert pos.y == 2.0
|
||||
assert pos.z == 3.0
|
||||
|
||||
// Get and test the `inventory` FlatBuffer vector.
|
||||
for(monster.inventory_length) e, i:
|
||||
assert monster.inventory(i) == e
|
||||
|
||||
// Get and test the `weapons` FlatBuffer vector of tables.
|
||||
for(monster.weapons_length) i:
|
||||
assert monster.weapons(i).name == weapon_names[i]
|
||||
assert monster.weapons(i).damage == weapon_damages[i]
|
||||
|
||||
// Get and test the `equipped` FlatBuffer union.
|
||||
assert monster.equipped_type() == MyGame_Sample_Equipment_Weapon
|
||||
|
||||
// Now that we know the union value is a weapon, we can safely call as_Weapon:
|
||||
let union_weapon = monster.equipped_as_Weapon
|
||||
|
||||
assert union_weapon.name == "Axe"
|
||||
assert union_weapon.damage == 5
|
||||
|
||||
print "The FlatBuffer was successfully created and verified!"
|
||||
43
samples/sample_text.lobster
Normal file
43
samples/sample_text.lobster
Normal file
@@ -0,0 +1,43 @@
|
||||
// Copyright 2018 Google Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
include from "../lobster/"
|
||||
include "monster_generated.lobster"
|
||||
|
||||
// Example how to interop with JSON.
|
||||
|
||||
// Test loading some JSON, converting it to a binary FlatBuffer and back again.
|
||||
|
||||
// First read the schema and JSON data.
|
||||
schema := read_file("monster.fbs", true)
|
||||
json := read_file("monsterdata.json", true)
|
||||
assert schema and json
|
||||
|
||||
// Parse JSON to binary:
|
||||
fb, err1 := flatbuffers_json_to_binary(schema, json, [])
|
||||
assert not err1
|
||||
|
||||
// Access one field in it, just to check:
|
||||
let monster = MyGame_Sample_GetRootAsMonster(fb)
|
||||
assert monster.name == "Orc"
|
||||
|
||||
// Convert binary back to JSON:
|
||||
json2, err2 := flatbuffers_binary_to_json(schema, fb, [])
|
||||
assert not err2
|
||||
|
||||
// The generated JSON should be exactly equal to the original!
|
||||
assert json == json2
|
||||
|
||||
// Print what we've been converting for good measure:
|
||||
print json
|
||||
@@ -71,6 +71,10 @@ int main(int argc, const char *argv[]) {
|
||||
flatbuffers::IDLOptions::kPython,
|
||||
"Generate Python files for tables/structs",
|
||||
flatbuffers::GeneralMakeRule },
|
||||
{ flatbuffers::GenerateLobster, nullptr, "--lobster", "Lobster", true, nullptr,
|
||||
flatbuffers::IDLOptions::kLobster,
|
||||
"Generate Lobster files for tables/structs",
|
||||
flatbuffers::GeneralMakeRule },
|
||||
{ flatbuffers::GenerateLua, "-l", "--lua", "Lua", true, nullptr,
|
||||
flatbuffers::IDLOptions::kLua,
|
||||
"Generate Lua files for tables/structs",
|
||||
|
||||
369
src/idl_gen_lobster.cpp
Normal file
369
src/idl_gen_lobster.cpp
Normal file
@@ -0,0 +1,369 @@
|
||||
/*
|
||||
* Copyright 2018 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "flatbuffers/code_generators.h"
|
||||
#include "flatbuffers/flatbuffers.h"
|
||||
#include "flatbuffers/idl.h"
|
||||
#include "flatbuffers/util.h"
|
||||
|
||||
namespace flatbuffers {
|
||||
namespace lobster {
|
||||
|
||||
class LobsterGenerator : public BaseGenerator {
|
||||
public:
|
||||
LobsterGenerator(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name)
|
||||
: BaseGenerator(parser, path, file_name, "" /* not used */, "_") {
|
||||
static const char * const keywords[] = {
|
||||
"nil", "true", "false", "return", "struct", "value", "include", "int",
|
||||
"float", "string", "any", "def", "is", "from", "program", "private",
|
||||
"coroutine", "resource", "enum", "typeof", "var", "let", "pakfile",
|
||||
"switch", "case", "default", "namespace", "not", "and", "or", "bool",
|
||||
};
|
||||
keywords_.insert(std::begin(keywords), std::end(keywords));
|
||||
}
|
||||
|
||||
std::string EscapeKeyword(const std::string &name) const {
|
||||
return keywords_.find(name) == keywords_.end() ? name : name + "_";
|
||||
}
|
||||
|
||||
std::string NormalizedName(const Definition &definition) const {
|
||||
return EscapeKeyword(definition.name);
|
||||
}
|
||||
|
||||
std::string NormalizedName(const EnumVal &ev) const {
|
||||
return EscapeKeyword(ev.name);
|
||||
}
|
||||
|
||||
std::string NamespacedName(const Definition &def) {
|
||||
return WrapInNameSpace(def.defined_namespace, NormalizedName(def));
|
||||
}
|
||||
|
||||
std::string GenTypeName(const Type &type) {
|
||||
auto bits = NumToString(SizeOf(type.base_type) * 8);
|
||||
if (IsInteger(type.base_type)) return "int" + bits;
|
||||
if (IsFloat(type.base_type)) return "float" + bits;
|
||||
if (type.base_type == BASE_TYPE_STRING) return "string";
|
||||
if (type.base_type == BASE_TYPE_STRUCT) return "table";
|
||||
return "none";
|
||||
}
|
||||
|
||||
std::string LobsterType(const Type &type) {
|
||||
if (IsFloat(type.base_type)) return "float";
|
||||
return "int";
|
||||
}
|
||||
|
||||
// Returns the method name for use with add/put calls.
|
||||
std::string GenMethod(const Type &type) {
|
||||
return IsScalar(type.base_type)
|
||||
? MakeCamel(GenTypeBasic(type))
|
||||
: (IsStruct(type) ? "Struct" : "UOffsetTRelative");
|
||||
}
|
||||
|
||||
// This uses Python names for now..
|
||||
std::string GenTypeBasic(const Type &type) {
|
||||
static const char *ctypename[] = {
|
||||
// clang-format off
|
||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \
|
||||
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
|
||||
#PTYPE,
|
||||
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
|
||||
#undef FLATBUFFERS_TD
|
||||
// clang-format on
|
||||
};
|
||||
return ctypename[type.base_type];
|
||||
}
|
||||
|
||||
// Generate a struct field, conditioned on its child type(s).
|
||||
void GenStructAccessor(const StructDef &struct_def,
|
||||
const FieldDef &field, std::string *code_ptr) {
|
||||
GenComment(field.doc_comment, code_ptr, nullptr, " ");
|
||||
std::string &code = *code_ptr;
|
||||
auto offsets = NumToString(field.value.offset);
|
||||
auto def = " def " + NormalizedName(field);
|
||||
if (IsScalar(field.value.type.base_type)) {
|
||||
if (struct_def.fixed) {
|
||||
code += def + "():\n buf_.read_" +
|
||||
GenTypeName(field.value.type) + "_le(pos_ + " + offsets +
|
||||
")\n";
|
||||
} else {
|
||||
code += def + "():\n buf_.flatbuffers_field_" +
|
||||
GenTypeName(field.value.type) + "(pos_, " + offsets + ", " +
|
||||
field.value.constant + ")\n";
|
||||
}
|
||||
return;
|
||||
}
|
||||
switch (field.value.type.base_type) {
|
||||
case BASE_TYPE_STRUCT: {
|
||||
auto name = NamespacedName(*field.value.type.struct_def);
|
||||
code += def + "():\n ";
|
||||
if (struct_def.fixed) {
|
||||
code += name + "{ buf_, pos_ + " + offsets + " }\n";
|
||||
} else {
|
||||
code += std::string("o := buf_.flatbuffers_field_") +
|
||||
(field.value.type.struct_def->fixed ? "struct" : "table") +
|
||||
"(pos_, " + offsets + ")\n if o: " + name +
|
||||
" { buf_, o } else: nil\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BASE_TYPE_STRING:
|
||||
code += def + "():\n buf_.flatbuffers_field_string(pos_, " +
|
||||
offsets + ")\n";
|
||||
break;
|
||||
case BASE_TYPE_VECTOR: {
|
||||
auto vectortype = field.value.type.VectorType();
|
||||
code += def + "(i:int):\n ";
|
||||
if (vectortype.base_type == BASE_TYPE_STRUCT) {
|
||||
auto start = "buf_.flatbuffers_field_vector(pos_, " + offsets +
|
||||
") + i * " + NumToString(InlineSize(vectortype));
|
||||
if (!(vectortype.struct_def->fixed)) {
|
||||
start = "buf_.flatbuffers_indirect(" + start + ")";
|
||||
}
|
||||
code += NamespacedName(*field.value.type.struct_def) + " { buf_, " +
|
||||
start + " }\n";
|
||||
} else {
|
||||
if (vectortype.base_type == BASE_TYPE_STRING)
|
||||
code += "buf_.flatbuffers_string";
|
||||
else
|
||||
code += "buf_.read_" + GenTypeName(vectortype) + "_le";
|
||||
code += "(buf_.flatbuffers_field_vector(pos_, " + offsets +
|
||||
") + i * " + NumToString(InlineSize(vectortype)) + ")\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BASE_TYPE_UNION: {
|
||||
for (auto &ev : field.value.type.enum_def->vals.vec) if (ev->value) {
|
||||
code += def + "_as_" + ev->name + "():\n " +
|
||||
NamespacedName(*ev->union_type.struct_def) +
|
||||
" { buf_, buf_.flatbuffers_field_table(pos_, " + offsets +
|
||||
") }\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: FLATBUFFERS_ASSERT(0);
|
||||
}
|
||||
if (field.value.type.base_type == BASE_TYPE_VECTOR) {
|
||||
code += def +
|
||||
"_length():\n buf_.flatbuffers_field_vector_len(pos_, " +
|
||||
offsets + ")\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Generate table constructors, conditioned on its members' types.
|
||||
void GenTableBuilders(const StructDef &struct_def,
|
||||
std::string *code_ptr) {
|
||||
std::string &code = *code_ptr;
|
||||
code += "def " + NormalizedName(struct_def) +
|
||||
"Start(b_:flatbuffers_builder):\n b_.StartObject(" +
|
||||
NumToString(struct_def.fields.vec.size()) + ")\n";
|
||||
for (auto it = struct_def.fields.vec.begin();
|
||||
it != struct_def.fields.vec.end(); ++it) {
|
||||
auto &field = **it;
|
||||
if (field.deprecated) continue;
|
||||
auto offset = it - struct_def.fields.vec.begin();
|
||||
code += "def " + NormalizedName(struct_def) + "Add" +
|
||||
MakeCamel(NormalizedName(field)) + "(b_:flatbuffers_builder, " +
|
||||
NormalizedName(field) + ":" + LobsterType(field.value.type) +
|
||||
"):\n b_.Prepend" + GenMethod(field.value.type) + "Slot(" +
|
||||
NumToString(offset) + ", " + NormalizedName(field) + ", " +
|
||||
field.value.constant + ")\n";
|
||||
if (field.value.type.base_type == BASE_TYPE_VECTOR) {
|
||||
code += "def " + NormalizedName(struct_def) + "Start" +
|
||||
MakeCamel(NormalizedName(field)) +
|
||||
"Vector(b_:flatbuffers_builder, n_:int):\n b_.StartVector(";
|
||||
auto vector_type = field.value.type.VectorType();
|
||||
auto alignment = InlineAlignment(vector_type);
|
||||
auto elem_size = InlineSize(vector_type);
|
||||
code += NumToString(elem_size) + ", n_, " + NumToString(alignment) +
|
||||
")\n";
|
||||
if (vector_type.base_type != BASE_TYPE_STRUCT ||
|
||||
!vector_type.struct_def->fixed) {
|
||||
code += "def " + NormalizedName(struct_def) + "Create" +
|
||||
MakeCamel(NormalizedName(field)) +
|
||||
"Vector(b_:flatbuffers_builder, v_:[" +
|
||||
LobsterType(vector_type) + "]):\n b_.StartVector(" +
|
||||
NumToString(elem_size) + ", v_.length, " +
|
||||
NumToString(alignment) +
|
||||
")\n reverse(v_) e_: b_.Prepend" +
|
||||
GenMethod(vector_type) +
|
||||
"(e_)\n b_.EndVector(v_.length)\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
code += "def " + NormalizedName(struct_def) +
|
||||
"End(b_:flatbuffers_builder):\n b_.EndObject()\n\n";
|
||||
}
|
||||
|
||||
void GenStructPreDecl(const StructDef &struct_def, std::string *code_ptr) {
|
||||
if (struct_def.generated) return;
|
||||
std::string &code = *code_ptr;
|
||||
CheckNameSpace(struct_def, &code);
|
||||
code += "struct " + NormalizedName(struct_def) + "\n\n";
|
||||
}
|
||||
|
||||
// Generate struct or table methods.
|
||||
void GenStruct(const StructDef &struct_def, std::string *code_ptr) {
|
||||
if (struct_def.generated) return;
|
||||
std::string &code = *code_ptr;
|
||||
CheckNameSpace(struct_def, &code);
|
||||
GenComment(struct_def.doc_comment, code_ptr, nullptr, "");
|
||||
code += "struct " + NormalizedName(struct_def) + " : flatbuffers_handle\n";
|
||||
for (auto it = struct_def.fields.vec.begin();
|
||||
it != struct_def.fields.vec.end(); ++it) {
|
||||
auto &field = **it;
|
||||
if (field.deprecated) continue;
|
||||
GenStructAccessor(struct_def, field, code_ptr);
|
||||
}
|
||||
code += "\n";
|
||||
if (!struct_def.fixed) {
|
||||
// Generate a special accessor for the table that has been declared as
|
||||
// the root type.
|
||||
code += "def GetRootAs" + NormalizedName(struct_def) + "(buf:string): " +
|
||||
NormalizedName(struct_def) +
|
||||
" { buf, buf.flatbuffers_indirect(0) }\n\n";
|
||||
}
|
||||
if (struct_def.fixed) {
|
||||
// create a struct constructor function
|
||||
GenStructBuilder(struct_def, code_ptr);
|
||||
} else {
|
||||
// Create a set of functions that allow table construction.
|
||||
GenTableBuilders(struct_def, code_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
// Generate enum declarations.
|
||||
void GenEnum(const EnumDef &enum_def, std::string *code_ptr) {
|
||||
if (enum_def.generated) return;
|
||||
std::string &code = *code_ptr;
|
||||
CheckNameSpace(enum_def, &code);
|
||||
GenComment(enum_def.doc_comment, code_ptr, nullptr, "");
|
||||
code += "enum + \n";
|
||||
for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end();
|
||||
++it) {
|
||||
auto &ev = **it;
|
||||
GenComment(ev.doc_comment, code_ptr, nullptr, " ");
|
||||
code += " " + enum_def.name + "_" + NormalizedName(ev) + " = " +
|
||||
NumToString(ev.value);
|
||||
if (it + 1 != enum_def.vals.vec.end()) code += ",";
|
||||
code += "\n";
|
||||
}
|
||||
code += "\n";
|
||||
}
|
||||
|
||||
// Recursively generate arguments for a constructor, to deal with nested
|
||||
// structs.
|
||||
void StructBuilderArgs(const StructDef &struct_def,
|
||||
const char *nameprefix, std::string *code_ptr) {
|
||||
for (auto it = struct_def.fields.vec.begin();
|
||||
it != struct_def.fields.vec.end(); ++it) {
|
||||
auto &field = **it;
|
||||
if (IsStruct(field.value.type)) {
|
||||
// Generate arguments for a struct inside a struct. To ensure names
|
||||
// don't clash, and to make it obvious these arguments are constructing
|
||||
// a nested struct, prefix the name with the field name.
|
||||
StructBuilderArgs(*field.value.type.struct_def,
|
||||
(nameprefix + (NormalizedName(field) + "_")).c_str(), code_ptr);
|
||||
} else {
|
||||
std::string &code = *code_ptr;
|
||||
code += ", " + (nameprefix + NormalizedName(field)) + ":" +
|
||||
LobsterType(field.value.type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Recursively generate struct construction statements and instert manual
|
||||
// padding.
|
||||
void StructBuilderBody(const StructDef &struct_def,
|
||||
const char *nameprefix, std::string *code_ptr) {
|
||||
std::string &code = *code_ptr;
|
||||
code += " b_.Prep(" + NumToString(struct_def.minalign) + ", " +
|
||||
NumToString(struct_def.bytesize) + ")\n";
|
||||
for (auto it = struct_def.fields.vec.rbegin();
|
||||
it != struct_def.fields.vec.rend(); ++it) {
|
||||
auto &field = **it;
|
||||
if (field.padding)
|
||||
code += " b_.Pad(" + NumToString(field.padding) + ")\n";
|
||||
if (IsStruct(field.value.type)) {
|
||||
StructBuilderBody(*field.value.type.struct_def,
|
||||
(nameprefix + (NormalizedName(field) + "_")).c_str(), code_ptr);
|
||||
} else {
|
||||
code += " b_.Prepend" + GenMethod(field.value.type) + "(" +
|
||||
nameprefix + NormalizedName(field) + ")\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create a struct with a builder and the struct's arguments.
|
||||
void GenStructBuilder(const StructDef &struct_def,
|
||||
std::string *code_ptr) {
|
||||
std::string &code = *code_ptr;
|
||||
code += "def Create" + NormalizedName(struct_def) +
|
||||
"(b_:flatbuffers_builder";
|
||||
StructBuilderArgs(struct_def, "", code_ptr);
|
||||
code += "):\n";
|
||||
StructBuilderBody(struct_def, "", code_ptr);
|
||||
code += " return b_.Offset()\n\n";
|
||||
}
|
||||
|
||||
void CheckNameSpace(const Definition &def, std::string *code_ptr) {
|
||||
auto ns = GetNameSpace(def);
|
||||
if (ns == current_namespace_) return;
|
||||
current_namespace_ = ns;
|
||||
std::string &code = *code_ptr;
|
||||
code += "namespace " + ns + "\n\n";
|
||||
}
|
||||
|
||||
bool generate() {
|
||||
std::string code;
|
||||
code += std::string("// ") + FlatBuffersGeneratedWarning() +
|
||||
"\n\ninclude \"flatbuffers.lobster\"\n\n";
|
||||
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
|
||||
++it) {
|
||||
auto &enum_def = **it;
|
||||
GenEnum(enum_def, &code);
|
||||
}
|
||||
for (auto it = parser_.structs_.vec.begin();
|
||||
it != parser_.structs_.vec.end(); ++it) {
|
||||
auto &struct_def = **it;
|
||||
GenStructPreDecl(struct_def, &code);
|
||||
}
|
||||
for (auto it = parser_.structs_.vec.begin();
|
||||
it != parser_.structs_.vec.end(); ++it) {
|
||||
auto &struct_def = **it;
|
||||
GenStruct(struct_def, &code);
|
||||
}
|
||||
return SaveFile((path_ + file_name_ + "_generated.lobster").c_str(),
|
||||
code, false);
|
||||
}
|
||||
|
||||
private:
|
||||
std::unordered_set<std::string> keywords_;
|
||||
std::string current_namespace_;
|
||||
};
|
||||
|
||||
} // namespace lobster
|
||||
|
||||
bool GenerateLobster(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name) {
|
||||
lobster::LobsterGenerator generator(parser, path, file_name);
|
||||
return generator.generate();
|
||||
}
|
||||
|
||||
} // namespace flatbuffers
|
||||
@@ -40,6 +40,11 @@ echo "************************ Dart:"
|
||||
|
||||
sh DartTest.sh
|
||||
|
||||
echo "************************ Lobster:"
|
||||
|
||||
# TODO: test if available.
|
||||
# lobster lobstertest.lobster
|
||||
|
||||
echo "************************ C:"
|
||||
|
||||
echo "(in a different repo)"
|
||||
|
||||
@@ -15,13 +15,13 @@
|
||||
set buildtype=Release
|
||||
if "%1"=="-b" set buildtype=%2
|
||||
|
||||
..\%buildtype%\flatc.exe --cpp --java --csharp --go --binary --python --lua --js --ts --php --grpc --gen-mutable --reflect-names --gen-object-api --no-includes --cpp-ptr-type flatbuffers::unique_ptr --no-fb-import -I include_test monster_test.fbs monsterdata_test.json
|
||||
..\%buildtype%\flatc.exe --cpp --java --csharp --go --binary --python --lua --js --ts --php --gen-mutable --reflect-names --no-fb-import --cpp-ptr-type flatbuffers::unique_ptr -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs
|
||||
..\%buildtype%\flatc.exe --cpp --java --csharp --go --binary --python --lobster --lua --js --ts --php --grpc --gen-mutable --reflect-names --gen-object-api --no-includes --cpp-ptr-type flatbuffers::unique_ptr --no-fb-import -I include_test monster_test.fbs monsterdata_test.json
|
||||
..\%buildtype%\flatc.exe --cpp --java --csharp --go --binary --python --lobster --lua --js --ts --php --gen-mutable --reflect-names --no-fb-import --cpp-ptr-type flatbuffers::unique_ptr -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs
|
||||
..\%buildtype%\flatc.exe --cpp --js --ts --php --gen-mutable --reflect-names --gen-object-api --cpp-ptr-type flatbuffers::unique_ptr -o union_vector ./union_vector/union_vector.fbs
|
||||
..\%buildtype%\flatc.exe -b --schema --bfbs-comments -I include_test monster_test.fbs
|
||||
..\%buildtype%\flatc.exe --jsonschema --schema -I include_test monster_test.fbs
|
||||
cd ../samples
|
||||
..\%buildtype%\flatc.exe --cpp --gen-mutable --reflect-names --gen-object-api --cpp-ptr-type flatbuffers::unique_ptr monster.fbs
|
||||
..\%buildtype%\flatc.exe --cpp --lobster --gen-mutable --reflect-names --gen-object-api --cpp-ptr-type flatbuffers::unique_ptr monster.fbs
|
||||
cd ../reflection
|
||||
|
||||
cd ../tests
|
||||
@@ -14,11 +14,11 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
../flatc --cpp --java --csharp --dart --go --binary --lua --python --js --ts --php --grpc --gen-mutable --reflect-names --gen-object-api --no-includes --cpp-ptr-type flatbuffers::unique_ptr --no-fb-import -I include_test monster_test.fbs monsterdata_test.json
|
||||
../flatc --cpp --java --csharp --dart --go --binary --lua --python --js --ts --php --gen-mutable --reflect-names --no-fb-import --cpp-ptr-type flatbuffers::unique_ptr -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs
|
||||
../flatc --cpp --java --csharp --dart --go --binary --lobster --lua --python --js --ts --php --grpc --gen-mutable --reflect-names --gen-object-api --no-includes --cpp-ptr-type flatbuffers::unique_ptr --no-fb-import -I include_test monster_test.fbs monsterdata_test.json
|
||||
../flatc --cpp --java --csharp --dart --go --binary --lobster --lua --python --js --ts --php --gen-mutable --reflect-names --no-fb-import --cpp-ptr-type flatbuffers::unique_ptr -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs
|
||||
../flatc --cpp --js --ts --php --gen-mutable --reflect-names --gen-object-api --cpp-ptr-type flatbuffers::unique_ptr -o union_vector ./union_vector/union_vector.fbs
|
||||
../flatc -b --schema --bfbs-comments -I include_test monster_test.fbs
|
||||
../flatc --jsonschema --schema -I include_test monster_test.fbs
|
||||
cd ../samples
|
||||
../flatc --cpp --gen-mutable --reflect-names --gen-object-api --cpp-ptr-type flatbuffers::unique_ptr monster.fbs
|
||||
../flatc --cpp --lobster --gen-mutable --reflect-names --gen-object-api --cpp-ptr-type flatbuffers::unique_ptr monster.fbs
|
||||
cd ../reflection
|
||||
|
||||
134
tests/lobstertest.lobster
Normal file
134
tests/lobstertest.lobster
Normal file
@@ -0,0 +1,134 @@
|
||||
// Copyright 2018 Google Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
include from "../lobster/"
|
||||
include "monster_test_generated.lobster"
|
||||
|
||||
def check_read_buffer(buf):
|
||||
// CheckReadBuffer checks that the given buffer is evaluated correctly as the example Monster.
|
||||
let monster = MyGame_Example_GetRootAsMonster(buf)
|
||||
|
||||
assert monster.hp == 80
|
||||
assert monster.mana == 150
|
||||
assert monster.name == "MyMonster"
|
||||
|
||||
let vec = monster.pos
|
||||
assert vec
|
||||
assert vec.x == 1.0
|
||||
assert vec.y == 2.0
|
||||
assert vec.z == 3.0
|
||||
assert vec.test1 == 3.0
|
||||
assert vec.test2 == 2
|
||||
|
||||
let t = vec.test3
|
||||
assert t
|
||||
assert t.a == 5
|
||||
assert t.b == 6
|
||||
|
||||
assert monster.test_type == MyGame_Example_Any_Monster
|
||||
assert monster.test_as_Monster.name == "Fred"
|
||||
|
||||
assert monster.inventory_length == 5
|
||||
assert sum(map(monster.inventory_length) i: monster.inventory(i)) == 10
|
||||
|
||||
for(5) i:
|
||||
assert monster.vector_of_longs(i) == pow(10, i * 2)
|
||||
|
||||
assert equal([-1.7976931348623157e+308, 0, 1.7976931348623157e+308],
|
||||
(map(monster.vector_of_doubles_length) i: monster.vector_of_doubles(i)))
|
||||
|
||||
assert monster.test4_length == 2
|
||||
let test0 = monster.test4(0)
|
||||
let test1 = monster.test4(1)
|
||||
assert test0.a + test0.b + test1.a + test1.b == 100
|
||||
|
||||
assert monster.testarrayofstring_length == 2
|
||||
assert monster.testarrayofstring(0) == "test1"
|
||||
assert monster.testarrayofstring(1) == "test2"
|
||||
|
||||
assert monster.testarrayoftables_length == 0
|
||||
assert monster.testnestedflatbuffer_length == 0
|
||||
assert not monster.testempty()
|
||||
|
||||
def make_monster_from_generated_code():
|
||||
// Use generated code to build the example Monster.
|
||||
let b = flatbuffers_builder {}
|
||||
|
||||
let name = b.CreateString("MyMonster")
|
||||
let fred = b.CreateString("Fred")
|
||||
|
||||
let inv = b.MyGame_Example_MonsterCreateInventoryVector([ 0, 1, 2, 3, 4 ])
|
||||
|
||||
b.MyGame_Example_MonsterStart()
|
||||
b.MyGame_Example_MonsterAddName(fred)
|
||||
let mon2 = b.MyGame_Example_MonsterEnd()
|
||||
|
||||
b.MyGame_Example_MonsterStartTest4Vector(2)
|
||||
b.MyGame_Example_CreateTest(10, 20)
|
||||
b.MyGame_Example_CreateTest(30, 40)
|
||||
let test4 = b.EndVector(2)
|
||||
|
||||
let test_array_of_string = b.MyGame_Example_MonsterCreateTestarrayofstringVector(
|
||||
[ b.CreateString("test1"), b.CreateString("test2") ])
|
||||
|
||||
let vector_of_longs = b.MyGame_Example_MonsterCreateVectorOfLongsVector(
|
||||
[ 1, 100, 10000, 1000000, 100000000 ])
|
||||
|
||||
let vector_of_doubles = b.MyGame_Example_MonsterCreateVectorOfDoublesVector(
|
||||
[ -1.7976931348623157e+308, 0, 1.7976931348623157e+308 ])
|
||||
|
||||
b.MyGame_Example_MonsterStart()
|
||||
b.MyGame_Example_MonsterAddPos(b.MyGame_Example_CreateVec3(1.0, 2.0, 3.0, 3.0, 2, 5, 6))
|
||||
b.MyGame_Example_MonsterAddHp(80)
|
||||
b.MyGame_Example_MonsterAddName(name)
|
||||
b.MyGame_Example_MonsterAddInventory(inv)
|
||||
b.MyGame_Example_MonsterAddTestType(MyGame_Example_Any_Monster)
|
||||
b.MyGame_Example_MonsterAddTest(mon2)
|
||||
b.MyGame_Example_MonsterAddTest4(test4)
|
||||
b.MyGame_Example_MonsterAddTestarrayofstring(test_array_of_string)
|
||||
b.MyGame_Example_MonsterAddVectorOfLongs(vector_of_longs)
|
||||
b.MyGame_Example_MonsterAddVectorOfDoubles(vector_of_doubles)
|
||||
let mon = b.MyGame_Example_MonsterEnd()
|
||||
|
||||
b.Finish(mon)
|
||||
|
||||
return b.SizedCopy()
|
||||
|
||||
// Verify that the canonical flatbuffer file (produced by the C++ implementation)
|
||||
// is readable by the generated Lobster code.
|
||||
let fb2 = read_file("monsterdata_test.mon")
|
||||
assert fb2
|
||||
check_read_buffer(fb2)
|
||||
|
||||
// Verify that using the generated Lobster code builds a buffer without
|
||||
// returning errors, and is interpreted correctly.
|
||||
let fb1 = make_monster_from_generated_code()
|
||||
check_read_buffer(fb1)
|
||||
// Write the result to file for no good reason.
|
||||
write_file("monsterdata_lobster_wire.mon", fb1)
|
||||
|
||||
// Test converting the buffer to JSON and parsing the JSON back again.
|
||||
schema := read_file("monster_test.fbs")
|
||||
assert schema
|
||||
includedirs := [ "include_test" ]
|
||||
// Convert binary to JSON:
|
||||
json, err1 := flatbuffers_binary_to_json(schema, fb1, includedirs)
|
||||
assert not err1
|
||||
// Parse JSON back to binary:
|
||||
fb3, err2 := flatbuffers_json_to_binary(schema, json, includedirs)
|
||||
assert not err2
|
||||
// Check the resulting binary again (full roundtrip test):
|
||||
check_read_buffer(fb3)
|
||||
|
||||
print "Lobster test succesful!"
|
||||
554
tests/monster_test_generated.lobster
Normal file
554
tests/monster_test_generated.lobster
Normal file
@@ -0,0 +1,554 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
include "flatbuffers.lobster"
|
||||
|
||||
namespace MyGame_Example
|
||||
|
||||
enum +
|
||||
Color_Red = 1,
|
||||
Color_Green = 2,
|
||||
Color_Blue = 8
|
||||
|
||||
enum +
|
||||
Any_NONE = 0,
|
||||
Any_Monster = 1,
|
||||
Any_TestSimpleTableWithEnum = 2,
|
||||
Any_MyGame_Example2_Monster = 3
|
||||
|
||||
namespace MyGame
|
||||
|
||||
struct InParentNamespace
|
||||
|
||||
namespace MyGame_Example2
|
||||
|
||||
struct Monster
|
||||
|
||||
namespace MyGame_Example
|
||||
|
||||
struct Test
|
||||
|
||||
struct TestSimpleTableWithEnum
|
||||
|
||||
struct Vec3
|
||||
|
||||
struct Ability
|
||||
|
||||
struct Stat
|
||||
|
||||
struct Referrable
|
||||
|
||||
struct Monster
|
||||
|
||||
struct TypeAliases
|
||||
|
||||
namespace MyGame
|
||||
|
||||
struct InParentNamespace : flatbuffers_handle
|
||||
|
||||
def GetRootAsInParentNamespace(buf:string): InParentNamespace { buf, buf.flatbuffers_indirect(0) }
|
||||
|
||||
def InParentNamespaceStart(b_:flatbuffers_builder):
|
||||
b_.StartObject(0)
|
||||
def InParentNamespaceEnd(b_:flatbuffers_builder):
|
||||
b_.EndObject()
|
||||
|
||||
namespace MyGame_Example2
|
||||
|
||||
struct Monster : flatbuffers_handle
|
||||
|
||||
def GetRootAsMonster(buf:string): Monster { buf, buf.flatbuffers_indirect(0) }
|
||||
|
||||
def MonsterStart(b_:flatbuffers_builder):
|
||||
b_.StartObject(0)
|
||||
def MonsterEnd(b_:flatbuffers_builder):
|
||||
b_.EndObject()
|
||||
|
||||
namespace MyGame_Example
|
||||
|
||||
struct Test : flatbuffers_handle
|
||||
def a():
|
||||
buf_.read_int16_le(pos_ + 0)
|
||||
def b():
|
||||
buf_.read_int8_le(pos_ + 2)
|
||||
|
||||
def CreateTest(b_:flatbuffers_builder, a:int, b:int):
|
||||
b_.Prep(2, 4)
|
||||
b_.Pad(1)
|
||||
b_.PrependInt8(b)
|
||||
b_.PrependInt16(a)
|
||||
return b_.Offset()
|
||||
|
||||
struct TestSimpleTableWithEnum : flatbuffers_handle
|
||||
def color():
|
||||
buf_.flatbuffers_field_int8(pos_, 4, 2)
|
||||
|
||||
def GetRootAsTestSimpleTableWithEnum(buf:string): TestSimpleTableWithEnum { buf, buf.flatbuffers_indirect(0) }
|
||||
|
||||
def TestSimpleTableWithEnumStart(b_:flatbuffers_builder):
|
||||
b_.StartObject(1)
|
||||
def TestSimpleTableWithEnumAddColor(b_:flatbuffers_builder, color:int):
|
||||
b_.PrependInt8Slot(0, color, 2)
|
||||
def TestSimpleTableWithEnumEnd(b_:flatbuffers_builder):
|
||||
b_.EndObject()
|
||||
|
||||
struct Vec3 : flatbuffers_handle
|
||||
def x():
|
||||
buf_.read_float32_le(pos_ + 0)
|
||||
def y():
|
||||
buf_.read_float32_le(pos_ + 4)
|
||||
def z():
|
||||
buf_.read_float32_le(pos_ + 8)
|
||||
def test1():
|
||||
buf_.read_float64_le(pos_ + 16)
|
||||
def test2():
|
||||
buf_.read_int8_le(pos_ + 24)
|
||||
def test3():
|
||||
MyGame_Example_Test{ buf_, pos_ + 26 }
|
||||
|
||||
def CreateVec3(b_:flatbuffers_builder, x:float, y:float, z:float, test1:float, test2:int, test3_a:int, test3_b:int):
|
||||
b_.Prep(16, 32)
|
||||
b_.Pad(2)
|
||||
b_.Prep(2, 4)
|
||||
b_.Pad(1)
|
||||
b_.PrependInt8(test3_b)
|
||||
b_.PrependInt16(test3_a)
|
||||
b_.Pad(1)
|
||||
b_.PrependInt8(test2)
|
||||
b_.PrependFloat64(test1)
|
||||
b_.Pad(4)
|
||||
b_.PrependFloat32(z)
|
||||
b_.PrependFloat32(y)
|
||||
b_.PrependFloat32(x)
|
||||
return b_.Offset()
|
||||
|
||||
struct Ability : flatbuffers_handle
|
||||
def id():
|
||||
buf_.read_int32_le(pos_ + 0)
|
||||
def distance():
|
||||
buf_.read_int32_le(pos_ + 4)
|
||||
|
||||
def CreateAbility(b_:flatbuffers_builder, id:int, distance:int):
|
||||
b_.Prep(4, 8)
|
||||
b_.PrependUint32(distance)
|
||||
b_.PrependUint32(id)
|
||||
return b_.Offset()
|
||||
|
||||
struct Stat : flatbuffers_handle
|
||||
def id():
|
||||
buf_.flatbuffers_field_string(pos_, 4)
|
||||
def val():
|
||||
buf_.flatbuffers_field_int64(pos_, 6, 0)
|
||||
def count():
|
||||
buf_.flatbuffers_field_int16(pos_, 8, 0)
|
||||
|
||||
def GetRootAsStat(buf:string): Stat { buf, buf.flatbuffers_indirect(0) }
|
||||
|
||||
def StatStart(b_:flatbuffers_builder):
|
||||
b_.StartObject(3)
|
||||
def StatAddId(b_:flatbuffers_builder, id:int):
|
||||
b_.PrependUOffsetTRelativeSlot(0, id, 0)
|
||||
def StatAddVal(b_:flatbuffers_builder, val:int):
|
||||
b_.PrependInt64Slot(1, val, 0)
|
||||
def StatAddCount(b_:flatbuffers_builder, count:int):
|
||||
b_.PrependUint16Slot(2, count, 0)
|
||||
def StatEnd(b_:flatbuffers_builder):
|
||||
b_.EndObject()
|
||||
|
||||
struct Referrable : flatbuffers_handle
|
||||
def id():
|
||||
buf_.flatbuffers_field_int64(pos_, 4, 0)
|
||||
|
||||
def GetRootAsReferrable(buf:string): Referrable { buf, buf.flatbuffers_indirect(0) }
|
||||
|
||||
def ReferrableStart(b_:flatbuffers_builder):
|
||||
b_.StartObject(1)
|
||||
def ReferrableAddId(b_:flatbuffers_builder, id:int):
|
||||
b_.PrependUint64Slot(0, id, 0)
|
||||
def ReferrableEnd(b_:flatbuffers_builder):
|
||||
b_.EndObject()
|
||||
|
||||
/// an example documentation comment: monster object
|
||||
struct Monster : flatbuffers_handle
|
||||
def pos():
|
||||
o := buf_.flatbuffers_field_struct(pos_, 4)
|
||||
if o: MyGame_Example_Vec3 { buf_, o } else: nil
|
||||
def mana():
|
||||
buf_.flatbuffers_field_int16(pos_, 6, 150)
|
||||
def hp():
|
||||
buf_.flatbuffers_field_int16(pos_, 8, 100)
|
||||
def name():
|
||||
buf_.flatbuffers_field_string(pos_, 10)
|
||||
def inventory(i:int):
|
||||
buf_.read_int8_le(buf_.flatbuffers_field_vector(pos_, 14) + i * 1)
|
||||
def inventory_length():
|
||||
buf_.flatbuffers_field_vector_len(pos_, 14)
|
||||
def color():
|
||||
buf_.flatbuffers_field_int8(pos_, 16, 8)
|
||||
def test_type():
|
||||
buf_.flatbuffers_field_int8(pos_, 18, 0)
|
||||
def test_as_Monster():
|
||||
MyGame_Example_Monster { buf_, buf_.flatbuffers_field_table(pos_, 20) }
|
||||
def test_as_TestSimpleTableWithEnum():
|
||||
MyGame_Example_TestSimpleTableWithEnum { buf_, buf_.flatbuffers_field_table(pos_, 20) }
|
||||
def test_as_MyGame_Example2_Monster():
|
||||
MyGame_Example2_Monster { buf_, buf_.flatbuffers_field_table(pos_, 20) }
|
||||
def test4(i:int):
|
||||
MyGame_Example_Test { buf_, buf_.flatbuffers_field_vector(pos_, 22) + i * 4 }
|
||||
def test4_length():
|
||||
buf_.flatbuffers_field_vector_len(pos_, 22)
|
||||
def testarrayofstring(i:int):
|
||||
buf_.flatbuffers_string(buf_.flatbuffers_field_vector(pos_, 24) + i * 4)
|
||||
def testarrayofstring_length():
|
||||
buf_.flatbuffers_field_vector_len(pos_, 24)
|
||||
/// an example documentation comment: this will end up in the generated code
|
||||
/// multiline too
|
||||
def testarrayoftables(i:int):
|
||||
MyGame_Example_Monster { buf_, buf_.flatbuffers_indirect(buf_.flatbuffers_field_vector(pos_, 26) + i * 4) }
|
||||
def testarrayoftables_length():
|
||||
buf_.flatbuffers_field_vector_len(pos_, 26)
|
||||
def enemy():
|
||||
o := buf_.flatbuffers_field_table(pos_, 28)
|
||||
if o: MyGame_Example_Monster { buf_, o } else: nil
|
||||
def testnestedflatbuffer(i:int):
|
||||
buf_.read_int8_le(buf_.flatbuffers_field_vector(pos_, 30) + i * 1)
|
||||
def testnestedflatbuffer_length():
|
||||
buf_.flatbuffers_field_vector_len(pos_, 30)
|
||||
def testempty():
|
||||
o := buf_.flatbuffers_field_table(pos_, 32)
|
||||
if o: MyGame_Example_Stat { buf_, o } else: nil
|
||||
def testbool():
|
||||
buf_.flatbuffers_field_int8(pos_, 34, 0)
|
||||
def testhashs32_fnv1():
|
||||
buf_.flatbuffers_field_int32(pos_, 36, 0)
|
||||
def testhashu32_fnv1():
|
||||
buf_.flatbuffers_field_int32(pos_, 38, 0)
|
||||
def testhashs64_fnv1():
|
||||
buf_.flatbuffers_field_int64(pos_, 40, 0)
|
||||
def testhashu64_fnv1():
|
||||
buf_.flatbuffers_field_int64(pos_, 42, 0)
|
||||
def testhashs32_fnv1a():
|
||||
buf_.flatbuffers_field_int32(pos_, 44, 0)
|
||||
def testhashu32_fnv1a():
|
||||
buf_.flatbuffers_field_int32(pos_, 46, 0)
|
||||
def testhashs64_fnv1a():
|
||||
buf_.flatbuffers_field_int64(pos_, 48, 0)
|
||||
def testhashu64_fnv1a():
|
||||
buf_.flatbuffers_field_int64(pos_, 50, 0)
|
||||
def testarrayofbools(i:int):
|
||||
buf_.read_int8_le(buf_.flatbuffers_field_vector(pos_, 52) + i * 1)
|
||||
def testarrayofbools_length():
|
||||
buf_.flatbuffers_field_vector_len(pos_, 52)
|
||||
def testf():
|
||||
buf_.flatbuffers_field_float32(pos_, 54, 3.14159)
|
||||
def testf2():
|
||||
buf_.flatbuffers_field_float32(pos_, 56, 3.0)
|
||||
def testf3():
|
||||
buf_.flatbuffers_field_float32(pos_, 58, 0.0)
|
||||
def testarrayofstring2(i:int):
|
||||
buf_.flatbuffers_string(buf_.flatbuffers_field_vector(pos_, 60) + i * 4)
|
||||
def testarrayofstring2_length():
|
||||
buf_.flatbuffers_field_vector_len(pos_, 60)
|
||||
def testarrayofsortedstruct(i:int):
|
||||
MyGame_Example_Ability { buf_, buf_.flatbuffers_field_vector(pos_, 62) + i * 8 }
|
||||
def testarrayofsortedstruct_length():
|
||||
buf_.flatbuffers_field_vector_len(pos_, 62)
|
||||
def flex(i:int):
|
||||
buf_.read_int8_le(buf_.flatbuffers_field_vector(pos_, 64) + i * 1)
|
||||
def flex_length():
|
||||
buf_.flatbuffers_field_vector_len(pos_, 64)
|
||||
def test5(i:int):
|
||||
MyGame_Example_Test { buf_, buf_.flatbuffers_field_vector(pos_, 66) + i * 4 }
|
||||
def test5_length():
|
||||
buf_.flatbuffers_field_vector_len(pos_, 66)
|
||||
def vector_of_longs(i:int):
|
||||
buf_.read_int64_le(buf_.flatbuffers_field_vector(pos_, 68) + i * 8)
|
||||
def vector_of_longs_length():
|
||||
buf_.flatbuffers_field_vector_len(pos_, 68)
|
||||
def vector_of_doubles(i:int):
|
||||
buf_.read_float64_le(buf_.flatbuffers_field_vector(pos_, 70) + i * 8)
|
||||
def vector_of_doubles_length():
|
||||
buf_.flatbuffers_field_vector_len(pos_, 70)
|
||||
def parent_namespace_test():
|
||||
o := buf_.flatbuffers_field_table(pos_, 72)
|
||||
if o: MyGame_InParentNamespace { buf_, o } else: nil
|
||||
def vector_of_referrables(i:int):
|
||||
MyGame_Example_Referrable { buf_, buf_.flatbuffers_indirect(buf_.flatbuffers_field_vector(pos_, 74) + i * 4) }
|
||||
def vector_of_referrables_length():
|
||||
buf_.flatbuffers_field_vector_len(pos_, 74)
|
||||
def single_weak_reference():
|
||||
buf_.flatbuffers_field_int64(pos_, 76, 0)
|
||||
def vector_of_weak_references(i:int):
|
||||
buf_.read_int64_le(buf_.flatbuffers_field_vector(pos_, 78) + i * 8)
|
||||
def vector_of_weak_references_length():
|
||||
buf_.flatbuffers_field_vector_len(pos_, 78)
|
||||
def vector_of_strong_referrables(i:int):
|
||||
MyGame_Example_Referrable { buf_, buf_.flatbuffers_indirect(buf_.flatbuffers_field_vector(pos_, 80) + i * 4) }
|
||||
def vector_of_strong_referrables_length():
|
||||
buf_.flatbuffers_field_vector_len(pos_, 80)
|
||||
def co_owning_reference():
|
||||
buf_.flatbuffers_field_int64(pos_, 82, 0)
|
||||
def vector_of_co_owning_references(i:int):
|
||||
buf_.read_int64_le(buf_.flatbuffers_field_vector(pos_, 84) + i * 8)
|
||||
def vector_of_co_owning_references_length():
|
||||
buf_.flatbuffers_field_vector_len(pos_, 84)
|
||||
def non_owning_reference():
|
||||
buf_.flatbuffers_field_int64(pos_, 86, 0)
|
||||
def vector_of_non_owning_references(i:int):
|
||||
buf_.read_int64_le(buf_.flatbuffers_field_vector(pos_, 88) + i * 8)
|
||||
def vector_of_non_owning_references_length():
|
||||
buf_.flatbuffers_field_vector_len(pos_, 88)
|
||||
|
||||
def GetRootAsMonster(buf:string): Monster { buf, buf.flatbuffers_indirect(0) }
|
||||
|
||||
def MonsterStart(b_:flatbuffers_builder):
|
||||
b_.StartObject(43)
|
||||
def MonsterAddPos(b_:flatbuffers_builder, pos:int):
|
||||
b_.PrependStructSlot(0, pos, 0)
|
||||
def MonsterAddMana(b_:flatbuffers_builder, mana:int):
|
||||
b_.PrependInt16Slot(1, mana, 150)
|
||||
def MonsterAddHp(b_:flatbuffers_builder, hp:int):
|
||||
b_.PrependInt16Slot(2, hp, 100)
|
||||
def MonsterAddName(b_:flatbuffers_builder, name:int):
|
||||
b_.PrependUOffsetTRelativeSlot(3, name, 0)
|
||||
def MonsterAddInventory(b_:flatbuffers_builder, inventory:int):
|
||||
b_.PrependUOffsetTRelativeSlot(5, inventory, 0)
|
||||
def MonsterStartInventoryVector(b_:flatbuffers_builder, n_:int):
|
||||
b_.StartVector(1, n_, 1)
|
||||
def MonsterCreateInventoryVector(b_:flatbuffers_builder, v_:[int]):
|
||||
b_.StartVector(1, v_.length, 1)
|
||||
reverse(v_) e_: b_.PrependUint8(e_)
|
||||
b_.EndVector(v_.length)
|
||||
def MonsterAddColor(b_:flatbuffers_builder, color:int):
|
||||
b_.PrependInt8Slot(6, color, 8)
|
||||
def MonsterAddTestType(b_:flatbuffers_builder, test_type:int):
|
||||
b_.PrependUint8Slot(7, test_type, 0)
|
||||
def MonsterAddTest(b_:flatbuffers_builder, test:int):
|
||||
b_.PrependUOffsetTRelativeSlot(8, test, 0)
|
||||
def MonsterAddTest4(b_:flatbuffers_builder, test4:int):
|
||||
b_.PrependUOffsetTRelativeSlot(9, test4, 0)
|
||||
def MonsterStartTest4Vector(b_:flatbuffers_builder, n_:int):
|
||||
b_.StartVector(4, n_, 2)
|
||||
def MonsterAddTestarrayofstring(b_:flatbuffers_builder, testarrayofstring:int):
|
||||
b_.PrependUOffsetTRelativeSlot(10, testarrayofstring, 0)
|
||||
def MonsterStartTestarrayofstringVector(b_:flatbuffers_builder, n_:int):
|
||||
b_.StartVector(4, n_, 4)
|
||||
def MonsterCreateTestarrayofstringVector(b_:flatbuffers_builder, v_:[int]):
|
||||
b_.StartVector(4, v_.length, 4)
|
||||
reverse(v_) e_: b_.PrependUOffsetTRelative(e_)
|
||||
b_.EndVector(v_.length)
|
||||
def MonsterAddTestarrayoftables(b_:flatbuffers_builder, testarrayoftables:int):
|
||||
b_.PrependUOffsetTRelativeSlot(11, testarrayoftables, 0)
|
||||
def MonsterStartTestarrayoftablesVector(b_:flatbuffers_builder, n_:int):
|
||||
b_.StartVector(4, n_, 4)
|
||||
def MonsterCreateTestarrayoftablesVector(b_:flatbuffers_builder, v_:[int]):
|
||||
b_.StartVector(4, v_.length, 4)
|
||||
reverse(v_) e_: b_.PrependUOffsetTRelative(e_)
|
||||
b_.EndVector(v_.length)
|
||||
def MonsterAddEnemy(b_:flatbuffers_builder, enemy:int):
|
||||
b_.PrependUOffsetTRelativeSlot(12, enemy, 0)
|
||||
def MonsterAddTestnestedflatbuffer(b_:flatbuffers_builder, testnestedflatbuffer:int):
|
||||
b_.PrependUOffsetTRelativeSlot(13, testnestedflatbuffer, 0)
|
||||
def MonsterStartTestnestedflatbufferVector(b_:flatbuffers_builder, n_:int):
|
||||
b_.StartVector(1, n_, 1)
|
||||
def MonsterCreateTestnestedflatbufferVector(b_:flatbuffers_builder, v_:[int]):
|
||||
b_.StartVector(1, v_.length, 1)
|
||||
reverse(v_) e_: b_.PrependUint8(e_)
|
||||
b_.EndVector(v_.length)
|
||||
def MonsterAddTestempty(b_:flatbuffers_builder, testempty:int):
|
||||
b_.PrependUOffsetTRelativeSlot(14, testempty, 0)
|
||||
def MonsterAddTestbool(b_:flatbuffers_builder, testbool:int):
|
||||
b_.PrependBoolSlot(15, testbool, 0)
|
||||
def MonsterAddTesthashs32Fnv1(b_:flatbuffers_builder, testhashs32_fnv1:int):
|
||||
b_.PrependInt32Slot(16, testhashs32_fnv1, 0)
|
||||
def MonsterAddTesthashu32Fnv1(b_:flatbuffers_builder, testhashu32_fnv1:int):
|
||||
b_.PrependUint32Slot(17, testhashu32_fnv1, 0)
|
||||
def MonsterAddTesthashs64Fnv1(b_:flatbuffers_builder, testhashs64_fnv1:int):
|
||||
b_.PrependInt64Slot(18, testhashs64_fnv1, 0)
|
||||
def MonsterAddTesthashu64Fnv1(b_:flatbuffers_builder, testhashu64_fnv1:int):
|
||||
b_.PrependUint64Slot(19, testhashu64_fnv1, 0)
|
||||
def MonsterAddTesthashs32Fnv1a(b_:flatbuffers_builder, testhashs32_fnv1a:int):
|
||||
b_.PrependInt32Slot(20, testhashs32_fnv1a, 0)
|
||||
def MonsterAddTesthashu32Fnv1a(b_:flatbuffers_builder, testhashu32_fnv1a:int):
|
||||
b_.PrependUint32Slot(21, testhashu32_fnv1a, 0)
|
||||
def MonsterAddTesthashs64Fnv1a(b_:flatbuffers_builder, testhashs64_fnv1a:int):
|
||||
b_.PrependInt64Slot(22, testhashs64_fnv1a, 0)
|
||||
def MonsterAddTesthashu64Fnv1a(b_:flatbuffers_builder, testhashu64_fnv1a:int):
|
||||
b_.PrependUint64Slot(23, testhashu64_fnv1a, 0)
|
||||
def MonsterAddTestarrayofbools(b_:flatbuffers_builder, testarrayofbools:int):
|
||||
b_.PrependUOffsetTRelativeSlot(24, testarrayofbools, 0)
|
||||
def MonsterStartTestarrayofboolsVector(b_:flatbuffers_builder, n_:int):
|
||||
b_.StartVector(1, n_, 1)
|
||||
def MonsterCreateTestarrayofboolsVector(b_:flatbuffers_builder, v_:[int]):
|
||||
b_.StartVector(1, v_.length, 1)
|
||||
reverse(v_) e_: b_.PrependBool(e_)
|
||||
b_.EndVector(v_.length)
|
||||
def MonsterAddTestf(b_:flatbuffers_builder, testf:float):
|
||||
b_.PrependFloat32Slot(25, testf, 3.14159)
|
||||
def MonsterAddTestf2(b_:flatbuffers_builder, testf2:float):
|
||||
b_.PrependFloat32Slot(26, testf2, 3.0)
|
||||
def MonsterAddTestf3(b_:flatbuffers_builder, testf3:float):
|
||||
b_.PrependFloat32Slot(27, testf3, 0.0)
|
||||
def MonsterAddTestarrayofstring2(b_:flatbuffers_builder, testarrayofstring2:int):
|
||||
b_.PrependUOffsetTRelativeSlot(28, testarrayofstring2, 0)
|
||||
def MonsterStartTestarrayofstring2Vector(b_:flatbuffers_builder, n_:int):
|
||||
b_.StartVector(4, n_, 4)
|
||||
def MonsterCreateTestarrayofstring2Vector(b_:flatbuffers_builder, v_:[int]):
|
||||
b_.StartVector(4, v_.length, 4)
|
||||
reverse(v_) e_: b_.PrependUOffsetTRelative(e_)
|
||||
b_.EndVector(v_.length)
|
||||
def MonsterAddTestarrayofsortedstruct(b_:flatbuffers_builder, testarrayofsortedstruct:int):
|
||||
b_.PrependUOffsetTRelativeSlot(29, testarrayofsortedstruct, 0)
|
||||
def MonsterStartTestarrayofsortedstructVector(b_:flatbuffers_builder, n_:int):
|
||||
b_.StartVector(8, n_, 4)
|
||||
def MonsterAddFlex(b_:flatbuffers_builder, flex:int):
|
||||
b_.PrependUOffsetTRelativeSlot(30, flex, 0)
|
||||
def MonsterStartFlexVector(b_:flatbuffers_builder, n_:int):
|
||||
b_.StartVector(1, n_, 1)
|
||||
def MonsterCreateFlexVector(b_:flatbuffers_builder, v_:[int]):
|
||||
b_.StartVector(1, v_.length, 1)
|
||||
reverse(v_) e_: b_.PrependUint8(e_)
|
||||
b_.EndVector(v_.length)
|
||||
def MonsterAddTest5(b_:flatbuffers_builder, test5:int):
|
||||
b_.PrependUOffsetTRelativeSlot(31, test5, 0)
|
||||
def MonsterStartTest5Vector(b_:flatbuffers_builder, n_:int):
|
||||
b_.StartVector(4, n_, 2)
|
||||
def MonsterAddVectorOfLongs(b_:flatbuffers_builder, vector_of_longs:int):
|
||||
b_.PrependUOffsetTRelativeSlot(32, vector_of_longs, 0)
|
||||
def MonsterStartVectorOfLongsVector(b_:flatbuffers_builder, n_:int):
|
||||
b_.StartVector(8, n_, 8)
|
||||
def MonsterCreateVectorOfLongsVector(b_:flatbuffers_builder, v_:[int]):
|
||||
b_.StartVector(8, v_.length, 8)
|
||||
reverse(v_) e_: b_.PrependInt64(e_)
|
||||
b_.EndVector(v_.length)
|
||||
def MonsterAddVectorOfDoubles(b_:flatbuffers_builder, vector_of_doubles:int):
|
||||
b_.PrependUOffsetTRelativeSlot(33, vector_of_doubles, 0)
|
||||
def MonsterStartVectorOfDoublesVector(b_:flatbuffers_builder, n_:int):
|
||||
b_.StartVector(8, n_, 8)
|
||||
def MonsterCreateVectorOfDoublesVector(b_:flatbuffers_builder, v_:[float]):
|
||||
b_.StartVector(8, v_.length, 8)
|
||||
reverse(v_) e_: b_.PrependFloat64(e_)
|
||||
b_.EndVector(v_.length)
|
||||
def MonsterAddParentNamespaceTest(b_:flatbuffers_builder, parent_namespace_test:int):
|
||||
b_.PrependUOffsetTRelativeSlot(34, parent_namespace_test, 0)
|
||||
def MonsterAddVectorOfReferrables(b_:flatbuffers_builder, vector_of_referrables:int):
|
||||
b_.PrependUOffsetTRelativeSlot(35, vector_of_referrables, 0)
|
||||
def MonsterStartVectorOfReferrablesVector(b_:flatbuffers_builder, n_:int):
|
||||
b_.StartVector(4, n_, 4)
|
||||
def MonsterCreateVectorOfReferrablesVector(b_:flatbuffers_builder, v_:[int]):
|
||||
b_.StartVector(4, v_.length, 4)
|
||||
reverse(v_) e_: b_.PrependUOffsetTRelative(e_)
|
||||
b_.EndVector(v_.length)
|
||||
def MonsterAddSingleWeakReference(b_:flatbuffers_builder, single_weak_reference:int):
|
||||
b_.PrependUint64Slot(36, single_weak_reference, 0)
|
||||
def MonsterAddVectorOfWeakReferences(b_:flatbuffers_builder, vector_of_weak_references:int):
|
||||
b_.PrependUOffsetTRelativeSlot(37, vector_of_weak_references, 0)
|
||||
def MonsterStartVectorOfWeakReferencesVector(b_:flatbuffers_builder, n_:int):
|
||||
b_.StartVector(8, n_, 8)
|
||||
def MonsterCreateVectorOfWeakReferencesVector(b_:flatbuffers_builder, v_:[int]):
|
||||
b_.StartVector(8, v_.length, 8)
|
||||
reverse(v_) e_: b_.PrependUint64(e_)
|
||||
b_.EndVector(v_.length)
|
||||
def MonsterAddVectorOfStrongReferrables(b_:flatbuffers_builder, vector_of_strong_referrables:int):
|
||||
b_.PrependUOffsetTRelativeSlot(38, vector_of_strong_referrables, 0)
|
||||
def MonsterStartVectorOfStrongReferrablesVector(b_:flatbuffers_builder, n_:int):
|
||||
b_.StartVector(4, n_, 4)
|
||||
def MonsterCreateVectorOfStrongReferrablesVector(b_:flatbuffers_builder, v_:[int]):
|
||||
b_.StartVector(4, v_.length, 4)
|
||||
reverse(v_) e_: b_.PrependUOffsetTRelative(e_)
|
||||
b_.EndVector(v_.length)
|
||||
def MonsterAddCoOwningReference(b_:flatbuffers_builder, co_owning_reference:int):
|
||||
b_.PrependUint64Slot(39, co_owning_reference, 0)
|
||||
def MonsterAddVectorOfCoOwningReferences(b_:flatbuffers_builder, vector_of_co_owning_references:int):
|
||||
b_.PrependUOffsetTRelativeSlot(40, vector_of_co_owning_references, 0)
|
||||
def MonsterStartVectorOfCoOwningReferencesVector(b_:flatbuffers_builder, n_:int):
|
||||
b_.StartVector(8, n_, 8)
|
||||
def MonsterCreateVectorOfCoOwningReferencesVector(b_:flatbuffers_builder, v_:[int]):
|
||||
b_.StartVector(8, v_.length, 8)
|
||||
reverse(v_) e_: b_.PrependUint64(e_)
|
||||
b_.EndVector(v_.length)
|
||||
def MonsterAddNonOwningReference(b_:flatbuffers_builder, non_owning_reference:int):
|
||||
b_.PrependUint64Slot(41, non_owning_reference, 0)
|
||||
def MonsterAddVectorOfNonOwningReferences(b_:flatbuffers_builder, vector_of_non_owning_references:int):
|
||||
b_.PrependUOffsetTRelativeSlot(42, vector_of_non_owning_references, 0)
|
||||
def MonsterStartVectorOfNonOwningReferencesVector(b_:flatbuffers_builder, n_:int):
|
||||
b_.StartVector(8, n_, 8)
|
||||
def MonsterCreateVectorOfNonOwningReferencesVector(b_:flatbuffers_builder, v_:[int]):
|
||||
b_.StartVector(8, v_.length, 8)
|
||||
reverse(v_) e_: b_.PrependUint64(e_)
|
||||
b_.EndVector(v_.length)
|
||||
def MonsterEnd(b_:flatbuffers_builder):
|
||||
b_.EndObject()
|
||||
|
||||
struct TypeAliases : flatbuffers_handle
|
||||
def i8():
|
||||
buf_.flatbuffers_field_int8(pos_, 4, 0)
|
||||
def u8():
|
||||
buf_.flatbuffers_field_int8(pos_, 6, 0)
|
||||
def i16():
|
||||
buf_.flatbuffers_field_int16(pos_, 8, 0)
|
||||
def u16():
|
||||
buf_.flatbuffers_field_int16(pos_, 10, 0)
|
||||
def i32():
|
||||
buf_.flatbuffers_field_int32(pos_, 12, 0)
|
||||
def u32():
|
||||
buf_.flatbuffers_field_int32(pos_, 14, 0)
|
||||
def i64():
|
||||
buf_.flatbuffers_field_int64(pos_, 16, 0)
|
||||
def u64():
|
||||
buf_.flatbuffers_field_int64(pos_, 18, 0)
|
||||
def f32():
|
||||
buf_.flatbuffers_field_float32(pos_, 20, 0.0)
|
||||
def f64():
|
||||
buf_.flatbuffers_field_float64(pos_, 22, 0.0)
|
||||
def v8(i:int):
|
||||
buf_.read_int8_le(buf_.flatbuffers_field_vector(pos_, 24) + i * 1)
|
||||
def v8_length():
|
||||
buf_.flatbuffers_field_vector_len(pos_, 24)
|
||||
def vf64(i:int):
|
||||
buf_.read_float64_le(buf_.flatbuffers_field_vector(pos_, 26) + i * 8)
|
||||
def vf64_length():
|
||||
buf_.flatbuffers_field_vector_len(pos_, 26)
|
||||
|
||||
def GetRootAsTypeAliases(buf:string): TypeAliases { buf, buf.flatbuffers_indirect(0) }
|
||||
|
||||
def TypeAliasesStart(b_:flatbuffers_builder):
|
||||
b_.StartObject(12)
|
||||
def TypeAliasesAddI8(b_:flatbuffers_builder, i8:int):
|
||||
b_.PrependInt8Slot(0, i8, 0)
|
||||
def TypeAliasesAddU8(b_:flatbuffers_builder, u8:int):
|
||||
b_.PrependUint8Slot(1, u8, 0)
|
||||
def TypeAliasesAddI16(b_:flatbuffers_builder, i16:int):
|
||||
b_.PrependInt16Slot(2, i16, 0)
|
||||
def TypeAliasesAddU16(b_:flatbuffers_builder, u16:int):
|
||||
b_.PrependUint16Slot(3, u16, 0)
|
||||
def TypeAliasesAddI32(b_:flatbuffers_builder, i32:int):
|
||||
b_.PrependInt32Slot(4, i32, 0)
|
||||
def TypeAliasesAddU32(b_:flatbuffers_builder, u32:int):
|
||||
b_.PrependUint32Slot(5, u32, 0)
|
||||
def TypeAliasesAddI64(b_:flatbuffers_builder, i64:int):
|
||||
b_.PrependInt64Slot(6, i64, 0)
|
||||
def TypeAliasesAddU64(b_:flatbuffers_builder, u64:int):
|
||||
b_.PrependUint64Slot(7, u64, 0)
|
||||
def TypeAliasesAddF32(b_:flatbuffers_builder, f32:float):
|
||||
b_.PrependFloat32Slot(8, f32, 0.0)
|
||||
def TypeAliasesAddF64(b_:flatbuffers_builder, f64:float):
|
||||
b_.PrependFloat64Slot(9, f64, 0.0)
|
||||
def TypeAliasesAddV8(b_:flatbuffers_builder, v8:int):
|
||||
b_.PrependUOffsetTRelativeSlot(10, v8, 0)
|
||||
def TypeAliasesStartV8Vector(b_:flatbuffers_builder, n_:int):
|
||||
b_.StartVector(1, n_, 1)
|
||||
def TypeAliasesCreateV8Vector(b_:flatbuffers_builder, v_:[int]):
|
||||
b_.StartVector(1, v_.length, 1)
|
||||
reverse(v_) e_: b_.PrependInt8(e_)
|
||||
b_.EndVector(v_.length)
|
||||
def TypeAliasesAddVf64(b_:flatbuffers_builder, vf64:int):
|
||||
b_.PrependUOffsetTRelativeSlot(11, vf64, 0)
|
||||
def TypeAliasesStartVf64Vector(b_:flatbuffers_builder, n_:int):
|
||||
b_.StartVector(8, n_, 8)
|
||||
def TypeAliasesCreateVf64Vector(b_:flatbuffers_builder, v_:[float]):
|
||||
b_.StartVector(8, v_.length, 8)
|
||||
reverse(v_) e_: b_.PrependFloat64(e_)
|
||||
b_.EndVector(v_.length)
|
||||
def TypeAliasesEnd(b_:flatbuffers_builder):
|
||||
b_.EndObject()
|
||||
|
||||
40
tests/namespace_test/namespace_test1_generated.lobster
Normal file
40
tests/namespace_test/namespace_test1_generated.lobster
Normal file
@@ -0,0 +1,40 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
include "flatbuffers.lobster"
|
||||
|
||||
namespace NamespaceA_NamespaceB
|
||||
|
||||
enum +
|
||||
EnumInNestedNS_A = 0,
|
||||
EnumInNestedNS_B = 1,
|
||||
EnumInNestedNS_C = 2
|
||||
|
||||
struct TableInNestedNS
|
||||
|
||||
struct StructInNestedNS
|
||||
|
||||
struct TableInNestedNS : flatbuffers_handle
|
||||
def foo():
|
||||
buf_.flatbuffers_field_int32(pos_, 4, 0)
|
||||
|
||||
def GetRootAsTableInNestedNS(buf:string): TableInNestedNS { buf, buf.flatbuffers_indirect(0) }
|
||||
|
||||
def TableInNestedNSStart(b_:flatbuffers_builder):
|
||||
b_.StartObject(1)
|
||||
def TableInNestedNSAddFoo(b_:flatbuffers_builder, foo:int):
|
||||
b_.PrependInt32Slot(0, foo, 0)
|
||||
def TableInNestedNSEnd(b_:flatbuffers_builder):
|
||||
b_.EndObject()
|
||||
|
||||
struct StructInNestedNS : flatbuffers_handle
|
||||
def a():
|
||||
buf_.read_int32_le(pos_ + 0)
|
||||
def b():
|
||||
buf_.read_int32_le(pos_ + 4)
|
||||
|
||||
def CreateStructInNestedNS(b_:flatbuffers_builder, a:int, b:int):
|
||||
b_.Prep(4, 8)
|
||||
b_.PrependInt32(b)
|
||||
b_.PrependInt32(a)
|
||||
return b_.Offset()
|
||||
|
||||
76
tests/namespace_test/namespace_test2_generated.lobster
Normal file
76
tests/namespace_test/namespace_test2_generated.lobster
Normal file
@@ -0,0 +1,76 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
include "flatbuffers.lobster"
|
||||
|
||||
namespace NamespaceA
|
||||
|
||||
struct TableInFirstNS
|
||||
|
||||
namespace NamespaceC
|
||||
|
||||
struct TableInC
|
||||
|
||||
namespace NamespaceA
|
||||
|
||||
struct SecondTableInA
|
||||
|
||||
struct TableInFirstNS : flatbuffers_handle
|
||||
def foo_table():
|
||||
o := buf_.flatbuffers_field_table(pos_, 4)
|
||||
if o: NamespaceA_NamespaceB_TableInNestedNS { buf_, o } else: nil
|
||||
def foo_enum():
|
||||
buf_.flatbuffers_field_int8(pos_, 6, 0)
|
||||
def foo_struct():
|
||||
o := buf_.flatbuffers_field_struct(pos_, 8)
|
||||
if o: NamespaceA_NamespaceB_StructInNestedNS { buf_, o } else: nil
|
||||
|
||||
def GetRootAsTableInFirstNS(buf:string): TableInFirstNS { buf, buf.flatbuffers_indirect(0) }
|
||||
|
||||
def TableInFirstNSStart(b_:flatbuffers_builder):
|
||||
b_.StartObject(3)
|
||||
def TableInFirstNSAddFooTable(b_:flatbuffers_builder, foo_table:int):
|
||||
b_.PrependUOffsetTRelativeSlot(0, foo_table, 0)
|
||||
def TableInFirstNSAddFooEnum(b_:flatbuffers_builder, foo_enum:int):
|
||||
b_.PrependInt8Slot(1, foo_enum, 0)
|
||||
def TableInFirstNSAddFooStruct(b_:flatbuffers_builder, foo_struct:int):
|
||||
b_.PrependStructSlot(2, foo_struct, 0)
|
||||
def TableInFirstNSEnd(b_:flatbuffers_builder):
|
||||
b_.EndObject()
|
||||
|
||||
namespace NamespaceC
|
||||
|
||||
struct TableInC : flatbuffers_handle
|
||||
def refer_to_a1():
|
||||
o := buf_.flatbuffers_field_table(pos_, 4)
|
||||
if o: NamespaceA_TableInFirstNS { buf_, o } else: nil
|
||||
def refer_to_a2():
|
||||
o := buf_.flatbuffers_field_table(pos_, 6)
|
||||
if o: NamespaceA_SecondTableInA { buf_, o } else: nil
|
||||
|
||||
def GetRootAsTableInC(buf:string): TableInC { buf, buf.flatbuffers_indirect(0) }
|
||||
|
||||
def TableInCStart(b_:flatbuffers_builder):
|
||||
b_.StartObject(2)
|
||||
def TableInCAddReferToA1(b_:flatbuffers_builder, refer_to_a1:int):
|
||||
b_.PrependUOffsetTRelativeSlot(0, refer_to_a1, 0)
|
||||
def TableInCAddReferToA2(b_:flatbuffers_builder, refer_to_a2:int):
|
||||
b_.PrependUOffsetTRelativeSlot(1, refer_to_a2, 0)
|
||||
def TableInCEnd(b_:flatbuffers_builder):
|
||||
b_.EndObject()
|
||||
|
||||
namespace NamespaceA
|
||||
|
||||
struct SecondTableInA : flatbuffers_handle
|
||||
def refer_to_c():
|
||||
o := buf_.flatbuffers_field_table(pos_, 4)
|
||||
if o: NamespaceC_TableInC { buf_, o } else: nil
|
||||
|
||||
def GetRootAsSecondTableInA(buf:string): SecondTableInA { buf, buf.flatbuffers_indirect(0) }
|
||||
|
||||
def SecondTableInAStart(b_:flatbuffers_builder):
|
||||
b_.StartObject(1)
|
||||
def SecondTableInAAddReferToC(b_:flatbuffers_builder, refer_to_c:int):
|
||||
b_.PrependUOffsetTRelativeSlot(0, refer_to_c, 0)
|
||||
def SecondTableInAEnd(b_:flatbuffers_builder):
|
||||
b_.EndObject()
|
||||
|
||||
Reference in New Issue
Block a user