FlatBuffers implementation for the Lobster programming language

Language, see: http://strlen.com/lobster/ and https://github.com/aardappel/lobster
This commit is contained in:
aardappel
2018-07-23 19:03:11 -07:00
parent ca5aaf62d3
commit 4898809eca
25 changed files with 2017 additions and 41 deletions

View 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()

View File

@@ -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
}
}

View 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!"

View 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