mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-13 16:15:26 +00:00
Revamping the FlatBuffers docs.
Adding an API reference for the supported languages. General docs cleanup, including a new `tutorial` section that supports all of the supported languages. Added samples for each supported language to mirror the new tutorial page. Cleaned up all the links by making them `@ref` style links, instead of referencing the names of the generated `.html` files. Removed all generated files that were unnecessarily committed. Also fixed the C# tests (two were failing due to a missing file). Bug: b/25801305 Tested: Tested all samples on Ubuntu, Mac, and Android. Docs were generated using doxygen and viewed on Chrome. Change-Id: I2acaba6e332a15ae2deff5f26a4a25da7bd2c954
This commit is contained in:
137
samples/SampleBinary.cs
Normal file
137
samples/SampleBinary.cs
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright 2015 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.
|
||||
*/
|
||||
|
||||
// To run, use the `csharp_sample.sh` script.
|
||||
|
||||
using System;
|
||||
using FlatBuffers;
|
||||
using MyGame.Sample;
|
||||
|
||||
class SampleBinary
|
||||
{
|
||||
// Example how to use FlatBuffers to create and read binary buffers.
|
||||
static void Main()
|
||||
{
|
||||
var builder = new FlatBufferBuilder(1);
|
||||
|
||||
// Create some weapons for our Monster ('Sword' and 'Axe').
|
||||
var weapon1Name = builder.CreateString("Sword");
|
||||
var weapon1Damage = 3;
|
||||
var weapon2Name = builder.CreateString("Axe");
|
||||
var weapon2Damage = 5;
|
||||
|
||||
// Use the `CreateWeapon()` helper function to create the weapons, since we set every field.
|
||||
var weaps = new Offset<Weapon>[2];
|
||||
weaps[0] = Weapon.CreateWeapon(builder, weapon1Name, (short)weapon1Damage);
|
||||
weaps[1] = Weapon.CreateWeapon(builder, weapon2Name, (short)weapon2Damage);
|
||||
|
||||
// Serialize the FlatBuffer data.
|
||||
var name = builder.CreateString("Orc");
|
||||
var treasure = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
var inv = Monster.CreateInventoryVector(builder, treasure);
|
||||
var weapons = Monster.CreateWeaponsVector(builder, weaps);
|
||||
var pos = Vec3.CreateVec3(builder, 1.0f, 2.0f, 3.0f);
|
||||
|
||||
Monster.StartMonster(builder);
|
||||
Monster.AddPos(builder, pos);
|
||||
Monster.AddHp(builder, (short)300);
|
||||
Monster.AddName(builder, name);
|
||||
Monster.AddInventory(builder, inv);
|
||||
Monster.AddColor(builder, Color.Red);
|
||||
Monster.AddWeapons(builder, weapons);
|
||||
Monster.AddEquippedType(builder, Equipment.Weapon);
|
||||
Monster.AddEquipped(builder, weaps[1].Value);
|
||||
var orc = Monster.EndMonster(builder);
|
||||
|
||||
builder.Finish(orc.Value); // You could also call `Monster.FinishMonsterBuffer(builder, orc);`.
|
||||
|
||||
// We now have a FlatBuffer that we could store on disk or send over a network.
|
||||
|
||||
// ...Code to store to disk or send over a network goes here...
|
||||
|
||||
// Instead, we are going to access it right away, as if we just received it.
|
||||
|
||||
var buf = builder.DataBuffer;
|
||||
|
||||
// Get access to the root:
|
||||
var monster = Monster.GetRootAsMonster(buf);
|
||||
|
||||
// For C#, unlike other languages, most values (except for vectors and unions) are available as
|
||||
// properties instead of accessor methods.
|
||||
|
||||
// Note: We did not set the `Mana` field explicitly, so we get back the default value.
|
||||
Assert(monster.Mana == 150, "monster.Mana", Convert.ToString(monster.Mana),
|
||||
Convert.ToString(150));
|
||||
Assert(monster.Hp == 300, "monster.Hp", Convert.ToString(monster.Hp), Convert.ToString(30));
|
||||
Assert(monster.Name.Equals("Orc", StringComparison.Ordinal), "monster.Name", monster.Name,
|
||||
"Orc");
|
||||
Assert(monster.Color == Color.Red, "monster.Color", Convert.ToString(monster.Color),
|
||||
Convert.ToString(Color.Red));
|
||||
|
||||
// C# also allows you to use performance-enhanced methods to fill an object that has already
|
||||
// been created. These functions are prefixed with "Get". For example: `monster.GetPos()`.
|
||||
var myAlreadyCreatedVector = new Vec3();
|
||||
monster.GetPos(myAlreadyCreatedVector); // Instead of `var myNewVec3 = monster.Pos`.
|
||||
Assert(myAlreadyCreatedVector.X == 1.0f, "myAlreadyCreatedVector.X",
|
||||
Convert.ToString(myAlreadyCreatedVector.X), Convert.ToString(1.0f));
|
||||
Assert(myAlreadyCreatedVector.Y == 2.0f, "myAlreadyCreatedVector.Y",
|
||||
Convert.ToString(myAlreadyCreatedVector.Y), Convert.ToString(2.0f));
|
||||
Assert(myAlreadyCreatedVector.Z == 3.0f, "myAlreadyCreatedVector.Z",
|
||||
Convert.ToString(myAlreadyCreatedVector.Z), Convert.ToString(3.0f));
|
||||
|
||||
// Get and test the `Inventory` FlatBuffer `vector`.
|
||||
for (int i = 0; i < monster.InventoryLength; i++)
|
||||
{
|
||||
Assert(monster.GetInventory(i) == i, "monster.GetInventory",
|
||||
Convert.ToString(monster.GetInventory(i)), Convert.ToString(i));
|
||||
}
|
||||
|
||||
// Get and test the `Weapons` FlatBuffer `vector` of `table`s.
|
||||
var expectedWeaponNames = new string[] {"Sword", "Axe"};
|
||||
var expectedWeaponDamages = new short[] {3, 5};
|
||||
for (int i = 0; i < monster.WeaponsLength; i++)
|
||||
{
|
||||
Assert(monster.GetWeapons(i).Name.Equals(expectedWeaponNames[i], StringComparison.Ordinal),
|
||||
"monster.GetWeapons", monster.GetWeapons(i).Name, expectedWeaponNames[i]);
|
||||
Assert(monster.GetWeapons(i).Damage == expectedWeaponDamages[i], "monster.GetWeapons",
|
||||
Convert.ToString(monster.GetWeapons(i).Damage),
|
||||
Convert.ToString(expectedWeaponDamages[i]));
|
||||
}
|
||||
|
||||
// Get and test the `Equipped` FlatBuffer `union`.
|
||||
Assert(monster.EquippedType == Equipment.Weapon, "monster.EquippedType",
|
||||
Convert.ToString(monster.EquippedType), Convert.ToString(Equipment.Weapon));
|
||||
var equipped = (Weapon)monster.GetEquipped(new Weapon());
|
||||
Assert(equipped.Name.Equals("Axe", StringComparison.Ordinal), "equipped.Name", equipped.Name,
|
||||
"Axe");
|
||||
Assert(equipped.Damage == 5, "equipped.Damage", Convert.ToString(equipped.Damage),
|
||||
Convert.ToString(5));
|
||||
|
||||
Console.WriteLine("The FlatBuffer was successfully created and verified!");
|
||||
}
|
||||
|
||||
// A helper function to handle assertions.
|
||||
static void Assert(bool assertPassed, string codeExecuted, string actualValue,
|
||||
string expectedValue)
|
||||
{
|
||||
if (assertPassed == false)
|
||||
{
|
||||
Console.WriteLine("Assert failed! " + codeExecuted + " (" + actualValue +
|
||||
") was not equal to " + expectedValue + ".");
|
||||
System.Environment.Exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
106
samples/SampleBinary.java
Normal file
106
samples/SampleBinary.java
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright 2015 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.
|
||||
*/
|
||||
|
||||
// Run this file with the `java_sample.sh` script.
|
||||
|
||||
import MyGame.Sample.Color;
|
||||
import MyGame.Sample.Equipment;
|
||||
import MyGame.Sample.Monster;
|
||||
import MyGame.Sample.Vec3;
|
||||
import MyGame.Sample.Weapon;
|
||||
|
||||
import com.google.flatbuffers.FlatBufferBuilder;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
class SampleBinary {
|
||||
// Example how to use FlatBuffers to create and read binary buffers.
|
||||
public static void main(String[] args) {
|
||||
FlatBufferBuilder builder = new FlatBufferBuilder(0);
|
||||
|
||||
// Create some weapons for our Monster ('Sword' and 'Axe').
|
||||
int weaponOneName = builder.createString("Sword");
|
||||
short weaponOneDamage = 3;
|
||||
int weaponTwoName = builder.createString("Axe");
|
||||
short weaponTwoDamage = 5;
|
||||
|
||||
// Use the `createWeapon()` helper function to create the weapons, since we set every field.
|
||||
int[] weaps = new int[2];
|
||||
weaps[0] = Weapon.createWeapon(builder, weaponOneName, weaponOneDamage);
|
||||
weaps[1] = Weapon.createWeapon(builder, weaponTwoName, weaponTwoDamage);
|
||||
|
||||
// Serialize the FlatBuffer data.
|
||||
int name = builder.createString("Orc");
|
||||
byte[] treasure = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
int inv = Monster.createInventoryVector(builder, treasure);
|
||||
int weapons = Monster.createWeaponsVector(builder, weaps);
|
||||
int pos = Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f);
|
||||
|
||||
Monster.startMonster(builder);
|
||||
Monster.addPos(builder, pos);
|
||||
Monster.addName(builder, name);
|
||||
Monster.addColor(builder, Color.Red);
|
||||
Monster.addHp(builder, (short)300);
|
||||
Monster.addInventory(builder, inv);
|
||||
Monster.addWeapons(builder, weapons);
|
||||
Monster.addEquippedType(builder, Equipment.Weapon);
|
||||
Monster.addEquipped(builder, weaps[1]);
|
||||
int orc = Monster.endMonster(builder);
|
||||
|
||||
builder.finish(orc); // You could also call `Monster.finishMonsterBuffer(builder, orc);`.
|
||||
|
||||
// We now have a FlatBuffer that can be stored on disk or sent over a network.
|
||||
|
||||
// ...Code to store to disk or send over a network goes here...
|
||||
|
||||
// Instead, we are going to access it right away, as if we just received it.
|
||||
|
||||
ByteBuffer buf = builder.dataBuffer();
|
||||
|
||||
// Get access to the root:
|
||||
Monster monster = Monster.getRootAsMonster(buf);
|
||||
|
||||
// Note: We did not set the `mana` field explicitly, so we get back the default value.
|
||||
assert monster.mana() == (short)150;
|
||||
assert monster.hp() == (short)300;
|
||||
assert monster.name().equals("Orc");
|
||||
assert monster.color() == Color.Red;
|
||||
assert monster.pos().x() == 1.0f;
|
||||
assert monster.pos().y() == 2.0f;
|
||||
assert monster.pos().z() == 3.0f;
|
||||
|
||||
// Get and test the `inventory` FlatBuffer `vector`.
|
||||
for (int i = 0; i < monster.inventoryLength(); i++) {
|
||||
assert monster.inventory(i) == (byte)i;
|
||||
}
|
||||
|
||||
// Get and test the `weapons` FlatBuffer `vector` of `table`s.
|
||||
String[] expectedWeaponNames = {"Sword", "Axe"};
|
||||
int[] expectedWeaponDamages = {3, 5};
|
||||
for (int i = 0; i < monster.weaponsLength(); i++) {
|
||||
assert monster.weapons(i).name().equals(expectedWeaponNames[i]);
|
||||
assert monster.weapons(i).damage() == expectedWeaponDamages[i];
|
||||
}
|
||||
|
||||
// Get and test the `equipped` FlatBuffer `union`.
|
||||
assert monster.equippedType() == Equipment.Weapon;
|
||||
Weapon equipped = (Weapon)monster.equipped(new Weapon());
|
||||
assert equipped.name().equals("Axe");
|
||||
assert equipped.damage() == 5;
|
||||
|
||||
System.out.println("The FlatBuffer was successfully created and verified!");
|
||||
}
|
||||
}
|
||||
115
samples/SampleBinary.php
Normal file
115
samples/SampleBinary.php
Normal file
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright 2015 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.
|
||||
*/
|
||||
|
||||
// To run, use the `php_sample.sh` script.
|
||||
|
||||
// It is recommended that you use PSR autoload when using FlatBuffers.
|
||||
function __autoload($class_name) {
|
||||
$class = substr($class_name, strrpos($class_name, "\\") + 1);
|
||||
$root_dir = join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)))); // `flatbuffers` root.
|
||||
$paths = array(join(DIRECTORY_SEPARATOR, array($root_dir, "php")),
|
||||
join(DIRECTORY_SEPARATOR, array($root_dir, "samples", "MyGame", "Sample")));
|
||||
foreach ($paths as $path) {
|
||||
$file = join(DIRECTORY_SEPARATOR, array($path, $class . ".php"));
|
||||
if (file_exists($file)) {
|
||||
require($file);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Example how to use FlatBuffers to create and read binary buffers.
|
||||
function main() {
|
||||
$builder = new Google\FlatBuffers\FlatbufferBuilder(0);
|
||||
|
||||
// Create some weapons for our Monster using the `createWeapon()` helper function.
|
||||
$weapon_one = $builder->createString("Sword");
|
||||
$sword = \MyGame\Sample\Weapon::CreateWeapon($builder, $weapon_one, 3);
|
||||
$weapon_two = $builder->createString("Axe");
|
||||
$axe = \MyGame\Sample\Weapon::CreateWeapon($builder, $weapon_two, 5);
|
||||
|
||||
// Serialize the FlatBuffer data.
|
||||
$name = $builder->createString("Orc");
|
||||
|
||||
$treasure = array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
|
||||
$inv = \MyGame\Sample\Monster::CreateInventoryVector($builder, $treasure);
|
||||
|
||||
$weaps = array($sword, $axe);
|
||||
$weapons = \MyGame\Sample\Monster::CreateWeaponsVector($builder, $weaps);
|
||||
|
||||
$pos = \MyGame\Sample\Vec3::CreateVec3($builder, 1.0, 2.0, 3.0);
|
||||
|
||||
\MyGame\Sample\Monster::StartMonster($builder);
|
||||
\MyGame\Sample\Monster::AddPos($builder, $pos);
|
||||
\MyGame\Sample\Monster::AddHp($builder, 300);
|
||||
\MyGame\Sample\Monster::AddName($builder, $name);
|
||||
\MyGame\Sample\Monster::AddInventory($builder, $inv);
|
||||
\MyGame\Sample\Monster::AddColor($builder, \MyGame\Sample\Color::Red);
|
||||
\MyGame\Sample\Monster::AddWeapons($builder, $weapons);
|
||||
\MyGame\Sample\Monster::AddEquippedType($builder, \MyGame\Sample\Equipment::Weapon);
|
||||
\MyGame\Sample\Monster::AddEquipped($builder, $weaps[1]);
|
||||
$orc = \MyGame\Sample\Monster::EndMonster($builder);
|
||||
|
||||
$builder->finish($orc); // You may also call `\MyGame\Sample\Monster::FinishMonsterBuffer($builder, $orc);`.
|
||||
|
||||
// We now have a FlatBuffer that can be stored on disk or sent over a network.
|
||||
|
||||
// ...Code to store to disk or send over a network goes here...
|
||||
|
||||
// Instead, we are going to access it right away, as if we just received it.
|
||||
|
||||
$buf = $builder->dataBuffer();
|
||||
|
||||
// Get access to the root:
|
||||
$monster = \MyGame\Sample\Monster::GetRootAsMonster($buf);
|
||||
|
||||
$success = true; // Tracks if an assert occurred.
|
||||
|
||||
// Note: We did not set the `mana` field explicitly, so we get back the default value.
|
||||
$success &= assert($monster->getMana() == 150);
|
||||
$success &= assert($monster->getHp() == 300);
|
||||
$success &= assert($monster->getName() == "Orc");
|
||||
$success &= assert($monster->getColor() == \MyGame\Sample\Color::Red);
|
||||
$success &= assert($monster->getPos()->getX() == 1.0);
|
||||
$success &= assert($monster->getPos()->getY() == 2.0);
|
||||
$success &= assert($monster->getPos()->getZ() == 3.0);
|
||||
|
||||
// Get and test the `inventory` FlatBuffer `vector`.
|
||||
for ($i = 0; $i < $monster->getInventoryLength(); $i++) {
|
||||
$success &= assert($monster->getInventory($i) == $i);
|
||||
}
|
||||
|
||||
// Get and test the `weapons` FlatBuffer `vector` of `table`s.
|
||||
$expected_weapon_names = array("Sword", "Axe");
|
||||
$expected_weapon_damages = array(3, 5);
|
||||
for ($i = 0; $i < $monster->getWeaponsLength(); $i++) {
|
||||
$success &= assert($monster->getWeapons($i)->getName() == $expected_weapon_names[$i]);
|
||||
$success &= assert($monster->getWeapons($i)->getDamage() == $expected_weapon_damages[$i]);
|
||||
}
|
||||
|
||||
// Get and test the `equipped` FlatBuffer `union`.
|
||||
$success &= assert($monster->getEquippedType() == \MyGame\Sample\Equipment::Weapon);
|
||||
$success &= assert($monster->getEquipped(new \MyGame\Sample\Weapon())->getName() == "Axe");
|
||||
$success &= assert($monster->getEquipped(new \MyGame\Sample\Weapon())->getDamage() == 5);
|
||||
|
||||
if ($success) {
|
||||
print("The FlatBuffer was successfully created and verified!\n");
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
?>
|
||||
48
samples/android/AndroidManifest.xml
Executable file
48
samples/android/AndroidManifest.xml
Executable file
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2015 Google, Inc.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
-->
|
||||
<!-- BEGIN_INCLUDE(manifest) -->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.samples.FlatBufferSample"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0">
|
||||
|
||||
<uses-feature android:glEsVersion="0x00020000"></uses-feature>
|
||||
<!-- This is the platform API where NativeActivity was introduced. -->
|
||||
<uses-sdk android:minSdkVersion="9" />
|
||||
|
||||
<!-- This .apk has no Java code itself, so set hasCode to false. -->
|
||||
<application android:label="@string/app_name" android:hasCode="false">
|
||||
|
||||
<!-- Our activity is the built-in NativeActivity framework class.
|
||||
This will take care of integrating with our NDK code. -->
|
||||
<activity android:name="android.app.NativeActivity"
|
||||
android:label="@string/app_name"
|
||||
android:configChanges="orientation|keyboardHidden"
|
||||
android:screenOrientation="landscape">
|
||||
<!-- Tell NativeActivity the name of or .so -->
|
||||
<meta-data android:name="android.app.lib_name"
|
||||
android:value="FlatBufferSample" />
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
<!-- END_INCLUDE(manifest) -->
|
||||
510
samples/android/build_apk.sh
Executable file
510
samples/android/build_apk.sh
Executable file
@@ -0,0 +1,510 @@
|
||||
#!/bin/bash -eu
|
||||
# Copyright (c) 2013 Google, Inc.
|
||||
#
|
||||
# This software is provided 'as-is', without any express or implied
|
||||
# warranty. In no event will the authors be held liable for any damages
|
||||
# arising from the use of this software.
|
||||
# Permission is granted to anyone to use this software for any purpose,
|
||||
# including commercial applications, and to alter it and redistribute it
|
||||
# freely, subject to the following restrictions:
|
||||
# 1. The origin of this software must not be misrepresented; you must not
|
||||
# claim that you wrote the original software. If you use this software
|
||||
# in a product, an acknowledgment in the product documentation would be
|
||||
# appreciated but is not required.
|
||||
# 2. Altered source versions must be plainly marked as such, and must not be
|
||||
# misrepresented as being the original software.
|
||||
# 3. This notice may not be removed or altered from any source distribution.
|
||||
#
|
||||
# Build, deploy, debug / execute a native Android package based upon
|
||||
# NativeActivity.
|
||||
|
||||
declare -r script_directory=$(dirname $0)
|
||||
declare -r android_root=${script_directory}/../../../../../../
|
||||
declare -r script_name=$(basename $0)
|
||||
declare -r android_manifest=AndroidManifest.xml
|
||||
declare -r os_name=$(uname -s)
|
||||
|
||||
# Minimum Android target version supported by this project.
|
||||
: ${BUILDAPK_ANDROID_TARGET_MINVERSION:=10}
|
||||
# Directory containing the Android SDK
|
||||
# (http://developer.android.com/sdk/index.html).
|
||||
: ${ANDROID_SDK_HOME:=}
|
||||
# Directory containing the Android NDK
|
||||
# (http://developer.android.com/tools/sdk/ndk/index.html).
|
||||
: ${NDK_HOME:=}
|
||||
|
||||
# Display script help and exit.
|
||||
usage() {
|
||||
echo "
|
||||
Build the Android package in the current directory and deploy it to a
|
||||
connected device.
|
||||
|
||||
Usage: ${script_name} \\
|
||||
[ADB_DEVICE=serial_number] [BUILD=0] [DEPLOY=0] [RUN_DEBUGGER=1] \
|
||||
[LAUNCH=0] [SWIG_BIN=swig_binary_directory] [SWIG_LIB=swig_include_directory] [ndk-build arguments ...]
|
||||
|
||||
ADB_DEVICE=serial_number:
|
||||
serial_number specifies the device to deploy the built apk to if multiple
|
||||
Android devices are connected to the host.
|
||||
BUILD=0:
|
||||
Disables the build of the package.
|
||||
DEPLOY=0:
|
||||
Disables the deployment of the built apk to the Android device.
|
||||
RUN_DEBUGGER=1:
|
||||
Launches the application in gdb after it has been deployed. To debug in
|
||||
gdb, NDK_DEBUG=1 must also be specified on the command line to build a
|
||||
debug apk.
|
||||
LAUNCH=0:
|
||||
Disable the launch of the apk on the Android device.
|
||||
SWIG_BIN=swig_binary_directory:
|
||||
The directory where the SWIG binary lives. No need to set this if SWIG is
|
||||
installed and point to from your PATH variable.
|
||||
SWIG_LIB=swig_include_directory:
|
||||
The directory where SWIG shared include files are, usually obtainable from
|
||||
commandline with \"swig -swiglib\". No need to set this if SWIG is installed
|
||||
and point to from your PATH variable.
|
||||
ndk-build arguments...:
|
||||
Additional arguments for ndk-build. See ndk-build -h for more information.
|
||||
" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Get the number of CPU cores present on the host.
|
||||
get_number_of_cores() {
|
||||
case ${os_name} in
|
||||
Darwin)
|
||||
sysctl hw.ncpu | awk '{ print $2 }'
|
||||
;;
|
||||
CYGWIN*|Linux)
|
||||
awk '/^processor/ { n=$3 } END { print n + 1 }' /proc/cpuinfo
|
||||
;;
|
||||
*)
|
||||
echo 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Get the package name from an AndroidManifest.xml file.
|
||||
get_package_name_from_manifest() {
|
||||
xmllint --xpath 'string(/manifest/@package)' "${1}"
|
||||
}
|
||||
|
||||
# Get the library name from an AndroidManifest.xml file.
|
||||
get_library_name_from_manifest() {
|
||||
echo "\
|
||||
setns android=http://schemas.android.com/apk/res/android
|
||||
xpath string(/manifest/application/activity\
|
||||
[@android:name=\"android.app.NativeActivity\"]/meta-data\
|
||||
[@android:name=\"android.app.lib_name\"]/@android:value)" |
|
||||
xmllint --shell "${1}" | awk '/Object is a string/ { print $NF }'
|
||||
}
|
||||
|
||||
# Get the number of Android devices connected to the system.
|
||||
get_number_of_devices_connected() {
|
||||
adb devices -l | \
|
||||
awk '/^..*$/ { if (p) { print $0 } }
|
||||
/List of devices attached/ { p = 1 }' | \
|
||||
wc -l
|
||||
return ${PIPESTATUS[0]}
|
||||
}
|
||||
|
||||
# Kill a process and its' children. This is provided for cygwin which
|
||||
# doesn't ship with pkill.
|
||||
kill_process_group() {
|
||||
local parent_pid="${1}"
|
||||
local child_pid=
|
||||
for child_pid in $(ps -f | \
|
||||
awk '{ if ($3 == '"${parent_pid}"') { print $2 } }'); do
|
||||
kill_process_group "${child_pid}"
|
||||
done
|
||||
kill "${parent_pid}" 2>/dev/null
|
||||
}
|
||||
|
||||
# Find and run "adb".
|
||||
adb() {
|
||||
local adb_path=
|
||||
for path in "$(which adb 2>/dev/null)" \
|
||||
"${ANDROID_SDK_HOME}/sdk/platform-tools/adb" \
|
||||
"${android_root}/prebuilts/sdk/platform-tools/adb"; do
|
||||
if [[ -e "${path}" ]]; then
|
||||
adb_path="${path}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [[ "${adb_path}" == "" ]]; then
|
||||
echo -e "Unable to find adb." \
|
||||
"\nAdd the Android ADT sdk/platform-tools directory to the" \
|
||||
"PATH." >&2
|
||||
exit 1
|
||||
fi
|
||||
"${adb_path}" "$@"
|
||||
}
|
||||
|
||||
# Find and run "android".
|
||||
android() {
|
||||
local android_executable=android
|
||||
if echo "${os_name}" | grep -q CYGWIN; then
|
||||
android_executable=android.bat
|
||||
fi
|
||||
local android_path=
|
||||
for path in "$(which ${android_executable})" \
|
||||
"${ANDROID_SDK_HOME}/sdk/tools/${android_executable}" \
|
||||
"${android_root}/prebuilts/sdk/tools/${android_executable}"; do
|
||||
if [[ -e "${path}" ]]; then
|
||||
android_path="${path}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [[ "${android_path}" == "" ]]; then
|
||||
echo -e "Unable to find android tool." \
|
||||
"\nAdd the Android ADT sdk/tools directory to the PATH." >&2
|
||||
exit 1
|
||||
fi
|
||||
# Make sure ant is installed.
|
||||
if [[ "$(which ant)" == "" ]]; then
|
||||
echo -e "Unable to find ant." \
|
||||
"\nPlease install ant and add to the PATH." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
"${android_path}" "$@"
|
||||
}
|
||||
|
||||
# Find and run "ndk-build"
|
||||
ndkbuild() {
|
||||
local ndkbuild_path=
|
||||
for path in "$(which ndk-build 2>/dev/null)" \
|
||||
"${NDK_HOME}/ndk-build" \
|
||||
"${android_root}/prebuilts/ndk/current/ndk-build"; do
|
||||
if [[ -e "${path}" ]]; then
|
||||
ndkbuild_path="${path}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [[ "${ndkbuild_path}" == "" ]]; then
|
||||
echo -e "Unable to find ndk-build." \
|
||||
"\nAdd the Android NDK directory to the PATH." >&2
|
||||
exit 1
|
||||
fi
|
||||
"${ndkbuild_path}" "$@"
|
||||
}
|
||||
|
||||
# Get file modification time of $1 in seconds since the epoch.
|
||||
stat_mtime() {
|
||||
local filename="${1}"
|
||||
case ${os_name} in
|
||||
Darwin) stat -f%m "${filename}" 2>/dev/null || echo 0 ;;
|
||||
*) stat -c%Y "${filename}" 2>/dev/null || echo 0 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Build the native (C/C++) build targets in the current directory.
|
||||
build_native_targets() {
|
||||
# Save the list of output modules in the install directory so that it's
|
||||
# possible to restore their timestamps after the build is complete. This
|
||||
# works around a bug in ndk/build/core/setup-app.mk which results in the
|
||||
# unconditional execution of the clean-installed-binaries rule.
|
||||
restore_libraries="$(find libs -type f 2>/dev/null | \
|
||||
sed -E 's@^libs/(.*)@\1@')"
|
||||
|
||||
# Build native code.
|
||||
ndkbuild -j$(get_number_of_cores) "$@"
|
||||
|
||||
# Restore installed libraries.
|
||||
# Obviously this is a nasty hack (along with ${restore_libraries} above) as
|
||||
# it assumes it knows where the NDK will be placing output files.
|
||||
(
|
||||
IFS=$'\n'
|
||||
for libpath in ${restore_libraries}; do
|
||||
source_library="obj/local/${libpath}"
|
||||
target_library="libs/${libpath}"
|
||||
if [[ -e "${source_library}" ]]; then
|
||||
cp -a "${source_library}" "${target_library}"
|
||||
fi
|
||||
done
|
||||
)
|
||||
}
|
||||
|
||||
# Select the oldest installed android build target that is at least as new as
|
||||
# BUILDAPK_ANDROID_TARGET_MINVERSION. If a suitable build target isn't found,
|
||||
# this function prints an error message and exits with an error.
|
||||
select_android_build_target() {
|
||||
local -r android_targets_installed=$( \
|
||||
android list targets | \
|
||||
awk -F'"' '/^id:.*android/ { print $2 }')
|
||||
local android_build_target=
|
||||
for android_target in $(echo "${android_targets_installed}" | \
|
||||
awk -F- '{ print $2 }' | sort -n); do
|
||||
local isNumber='^[0-9]+$'
|
||||
# skip preview API releases e.g. 'android-L'
|
||||
if [[ $android_target =~ $isNumber ]]; then
|
||||
if [[ $((android_target)) -ge \
|
||||
$((BUILDAPK_ANDROID_TARGET_MINVERSION)) ]]; then
|
||||
android_build_target="android-${android_target}"
|
||||
break
|
||||
fi
|
||||
# else
|
||||
# The API version is a letter, so skip it.
|
||||
fi
|
||||
done
|
||||
if [[ "${android_build_target}" == "" ]]; then
|
||||
echo -e \
|
||||
"Found installed Android targets:" \
|
||||
"$(echo ${android_targets_installed} | sed 's/ /\n /g;s/^/\n /;')" \
|
||||
"\nAndroid SDK platform" \
|
||||
"android-$((BUILDAPK_ANDROID_TARGET_MINVERSION))" \
|
||||
"must be installed to build this project." \
|
||||
"\nUse the \"android\" application to install API" \
|
||||
"$((BUILDAPK_ANDROID_TARGET_MINVERSION)) or newer." >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "${android_build_target}"
|
||||
}
|
||||
|
||||
# Sign unsigned apk $1 and write the result to $2 with key store file $3 and
|
||||
# password $4.
|
||||
# If a key store file $3 and password $4 aren't specified, a temporary
|
||||
# (60 day) key is generated and used to sign the package.
|
||||
sign_apk() {
|
||||
local unsigned_apk="${1}"
|
||||
local signed_apk="${2}"
|
||||
if [[ $(stat_mtime "${unsigned_apk}") -gt \
|
||||
$(stat_mtime "${signed_apk}") ]]; then
|
||||
local -r key_alias=$(basename ${signed_apk} .apk)
|
||||
local keystore="${3}"
|
||||
local key_password="${4}"
|
||||
[[ "${keystore}" == "" ]] && keystore="${unsigned_apk}.keystore"
|
||||
[[ "${key_password}" == "" ]] && \
|
||||
key_password="${key_alias}123456"
|
||||
if [[ ! -e ${keystore} ]]; then
|
||||
keytool -genkey -v -dname "cn=, ou=${key_alias}, o=fpl" \
|
||||
-storepass ${key_password} \
|
||||
-keypass ${key_password} -keystore ${keystore} \
|
||||
-alias ${key_alias} -keyalg RSA -keysize 2048 -validity 60
|
||||
fi
|
||||
cp "${unsigned_apk}" "${signed_apk}"
|
||||
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 \
|
||||
-keystore ${keystore} -storepass ${key_password} \
|
||||
-keypass ${key_password} "${signed_apk}" ${key_alias}
|
||||
fi
|
||||
}
|
||||
|
||||
# Build the apk $1 for package filename $2 in the current directory using the
|
||||
# ant build target $3.
|
||||
build_apk() {
|
||||
local -r output_apk="${1}"
|
||||
local -r package_filename="${2}"
|
||||
local -r ant_target="${3}"
|
||||
# Get the list of installed android targets and select the oldest target
|
||||
# that is at least as new as BUILDAPK_ANDROID_TARGET_MINVERSION.
|
||||
local -r android_build_target=$(select_android_build_target)
|
||||
[[ "${android_build_target}" == "" ]] && exit 1
|
||||
echo "Building ${output_apk} for target ${android_build_target}" >&2
|
||||
|
||||
# Create / update build.xml and local.properties files.
|
||||
if [[ $(stat_mtime "${android_manifest}") -gt \
|
||||
$(stat_mtime build.xml) ]]; then
|
||||
android update project --target "${android_build_target}" \
|
||||
-n ${package_filename} --path .
|
||||
fi
|
||||
|
||||
# Use ant to build the apk.
|
||||
ant -quiet ${ant_target}
|
||||
|
||||
# Sign release apks with a temporary key as these packages will not be
|
||||
# redistributed.
|
||||
local unsigned_apk="bin/${package_filename}-${ant_target}-unsigned.apk"
|
||||
if [[ "${ant_target}" == "release" ]]; then
|
||||
sign_apk "${unsigned_apk}" "${output_apk}" "" ""
|
||||
fi
|
||||
}
|
||||
|
||||
# Uninstall package $1 and install apk $2 on device $3 where $3 is "-s device"
|
||||
# or an empty string. If $3 is an empty string adb will fail when multiple
|
||||
# devices are connected to the host system.
|
||||
install_apk() {
|
||||
local -r uninstall_package_name="${1}"
|
||||
local -r install_apk="${2}"
|
||||
local -r adb_device="${3}"
|
||||
# Uninstall the package if it's already installed.
|
||||
adb ${adb_device} uninstall "${uninstall_package_name}" 1>&2 > /dev/null || \
|
||||
true # no error check
|
||||
|
||||
# Install the apk.
|
||||
# NOTE: The following works around adb not returning an error code when
|
||||
# it fails to install an apk.
|
||||
echo "Install ${install_apk}" >&2
|
||||
local -r adb_install_result=$(adb ${adb_device} install "${install_apk}")
|
||||
echo "${adb_install_result}"
|
||||
if echo "${adb_install_result}" | grep -qF 'Failure ['; then
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Launch previously installed package $1 on device $2.
|
||||
# If $2 is an empty string adb will fail when multiple devices are connected
|
||||
# to the host system.
|
||||
launch_package() {
|
||||
(
|
||||
# Determine the SDK version of Android on the device.
|
||||
local -r android_sdk_version=$(
|
||||
adb ${adb_device} shell cat system/build.prop | \
|
||||
awk -F= '/ro.build.version.sdk/ {
|
||||
v=$2; sub(/[ \r\n]/, "", v); print v
|
||||
}')
|
||||
|
||||
# Clear logs from previous runs.
|
||||
# Note that logcat does not just 'tail' the logs, it dumps the entire log
|
||||
# history.
|
||||
adb ${adb_device} logcat -c
|
||||
|
||||
local finished_msg='Displayed '"${package_name}"
|
||||
local timeout_msg='Activity destroy timeout.*'"${package_name}"
|
||||
# Maximum time to wait before stopping log monitoring. 0 = infinity.
|
||||
local launch_timeout=0
|
||||
# If this is a Gingerbread device, kill log monitoring after 10 seconds.
|
||||
if [[ $((android_sdk_version)) -le 10 ]]; then
|
||||
launch_timeout=10
|
||||
fi
|
||||
# Display logcat in the background.
|
||||
# Stop displaying the log when the app launch / execution completes or the
|
||||
# logcat
|
||||
(
|
||||
adb ${adb_device} logcat | \
|
||||
awk "
|
||||
{
|
||||
print \$0
|
||||
}
|
||||
|
||||
/ActivityManager.*: ${finished_msg}/ {
|
||||
exit 0
|
||||
}
|
||||
|
||||
/ActivityManager.*: ${timeout_msg}/ {
|
||||
exit 0
|
||||
}" &
|
||||
adb_logcat_pid=$!;
|
||||
if [[ $((launch_timeout)) -gt 0 ]]; then
|
||||
sleep $((launch_timeout));
|
||||
kill ${adb_logcat_pid};
|
||||
else
|
||||
wait ${adb_logcat_pid};
|
||||
fi
|
||||
) &
|
||||
logcat_pid=$!
|
||||
# Kill adb logcat if this shell exits.
|
||||
trap "kill_process_group ${logcat_pid}" SIGINT SIGTERM EXIT
|
||||
|
||||
# If the SDK is newer than 10, "am" supports stopping an activity.
|
||||
adb_stop_activity=
|
||||
if [[ $((android_sdk_version)) -gt 10 ]]; then
|
||||
adb_stop_activity=-S
|
||||
fi
|
||||
|
||||
# Launch the activity and wait for it to complete.
|
||||
adb ${adb_device} shell am start ${adb_stop_activity} -n \
|
||||
${package_name}/android.app.NativeActivity
|
||||
|
||||
wait "${logcat_pid}"
|
||||
)
|
||||
}
|
||||
|
||||
# See usage().
|
||||
main() {
|
||||
# Parse arguments for this script.
|
||||
local adb_device=
|
||||
local ant_target=release
|
||||
local disable_deploy=0
|
||||
local disable_build=0
|
||||
local run_debugger=0
|
||||
local launch=1
|
||||
local build_package=1
|
||||
for opt; do
|
||||
case ${opt} in
|
||||
# NDK_DEBUG=0 tells ndk-build to build this as debuggable but to not
|
||||
# modify the underlying code whereas NDK_DEBUG=1 also builds as debuggable
|
||||
# but does modify the code
|
||||
NDK_DEBUG=1) ant_target=debug ;;
|
||||
NDK_DEBUG=0) ant_target=debug ;;
|
||||
ADB_DEVICE*) adb_device="$(\
|
||||
echo "${opt}" | sed -E 's/^ADB_DEVICE=([^ ]+)$/-s \1/;t;s/.*//')" ;;
|
||||
BUILD=0) disable_build=1 ;;
|
||||
DEPLOY=0) disable_deploy=1 ;;
|
||||
RUN_DEBUGGER=1) run_debugger=1 ;;
|
||||
LAUNCH=0) launch=0 ;;
|
||||
clean) build_package=0 disable_deploy=1 launch=0 ;;
|
||||
-h|--help|help) usage ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# If a target device hasn't been specified and multiple devices are connected
|
||||
# to the host machine, display an error.
|
||||
local -r devices_connected=$(get_number_of_devices_connected)
|
||||
if [[ "${adb_device}" == "" && $((devices_connected)) -gt 1 && \
|
||||
($((disable_deploy)) -eq 0 || $((launch)) -ne 0 || \
|
||||
$((run_debugger)) -ne 0) ]]; then
|
||||
if [[ $((disable_deploy)) -ne 0 ]]; then
|
||||
echo "Deployment enabled, disable using DEPLOY=0" >&2
|
||||
fi
|
||||
if [[ $((launch)) -ne 0 ]]; then
|
||||
echo "Launch enabled." >&2
|
||||
fi
|
||||
if [[ $((disable_deploy)) -eq 0 ]]; then
|
||||
echo "Deployment enabled." >&2
|
||||
fi
|
||||
if [[ $((run_debugger)) -ne 0 ]]; then
|
||||
echo "Debugger launch enabled." >&2
|
||||
fi
|
||||
echo "
|
||||
Multiple Android devices are connected to this host. Either disable deployment
|
||||
and execution of the built .apk using:
|
||||
\"${script_name} DEPLOY=0 LAUNCH=0\"
|
||||
|
||||
or specify a device to deploy to using:
|
||||
\"${script_name} ADB_DEVICE=\${device_serial}\".
|
||||
|
||||
The Android devices connected to this machine are:
|
||||
$(adb devices -l)
|
||||
" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $((disable_build)) -eq 0 ]]; then
|
||||
# Build the native target.
|
||||
build_native_targets "$@"
|
||||
fi
|
||||
|
||||
# Get the package name from the manifest.
|
||||
local -r package_name=$(get_package_name_from_manifest "${android_manifest}")
|
||||
if [[ "${package_name}" == "" ]]; then
|
||||
echo -e "No package name specified in ${android_manifest},"\
|
||||
"skipping apk build, deploy"
|
||||
"\nand launch steps." >&2
|
||||
exit 0
|
||||
fi
|
||||
local -r package_basename=${package_name/*./}
|
||||
local package_filename=$(get_library_name_from_manifest ${android_manifest})
|
||||
[[ "${package_filename}" == "" ]] && package_filename="${package_basename}"
|
||||
|
||||
# Output apk name.
|
||||
local -r output_apk="bin/${package_filename}-${ant_target}.apk"
|
||||
|
||||
if [[ $((disable_build)) -eq 0 && $((build_package)) -eq 1 ]]; then
|
||||
# Build the apk.
|
||||
build_apk "${output_apk}" "${package_filename}" "${ant_target}"
|
||||
fi
|
||||
|
||||
# Deploy to the device.
|
||||
if [[ $((disable_deploy)) -eq 0 ]]; then
|
||||
install_apk "${package_name}" "${output_apk}" "${adb_device}"
|
||||
fi
|
||||
|
||||
if [[ "${ant_target}" == "debug" && $((run_debugger)) -eq 1 ]]; then
|
||||
# Start debugging.
|
||||
ndk-gdb ${adb_device} --start
|
||||
elif [[ $((launch)) -eq 1 ]]; then
|
||||
launch_package "${package_name}" "${adb_device}"
|
||||
fi
|
||||
}
|
||||
|
||||
main "$@"
|
||||
@@ -23,7 +23,7 @@ include $(CLEAR_VARS)
|
||||
# Include the FlatBuffer utility function to generate header files from schemas.
|
||||
include $(FLATBUFFERS_ROOT_DIR)/android/jni/include.mk
|
||||
|
||||
LOCAL_MODULE := sample_android_project
|
||||
LOCAL_MODULE := FlatBufferSample
|
||||
|
||||
# Set up some useful variables to identify schema and output directories and
|
||||
# schema files.
|
||||
|
||||
@@ -12,9 +12,10 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <android/log.h>
|
||||
|
||||
#include "android_native_app_glue.h"
|
||||
#include "animal_generated.h"
|
||||
#include "flatbuffers/flatbuffers.h"
|
||||
#include "animal_generated.h" // Includes "flatbuffers/flatbuffers.h".
|
||||
|
||||
void android_main(android_app *app) {
|
||||
app_dummy();
|
||||
@@ -24,5 +25,19 @@ void android_main(android_app *app) {
|
||||
auto sound = builder.CreateString("Bark");
|
||||
auto animal_buffer = sample::CreateAnimal(builder, name, sound);
|
||||
builder.Finish(animal_buffer);
|
||||
}
|
||||
|
||||
// We now have a FlatBuffer that can be stored on disk or sent over a network.
|
||||
|
||||
// ...Code to store on disk or send over a network goes here...
|
||||
|
||||
// Instead, we're going to access it immediately, as if we just recieved this.
|
||||
|
||||
auto animal = sample::GetAnimal(builder.GetBufferPointer());
|
||||
|
||||
assert(animal->name()->str() == "Dog");
|
||||
assert(animal->sound()->str() == "Bark");
|
||||
(void)animal; // To silence "Unused Variable" warnings.
|
||||
|
||||
__android_log_print(ANDROID_LOG_INFO, "FlatBufferSample",
|
||||
"FlatBuffer successfully created and verified.");
|
||||
}
|
||||
|
||||
20
samples/android/res/values/strings.xml
Executable file
20
samples/android/res/values/strings.xml
Executable file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2015 Google, Inc.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
-->
|
||||
<resources>
|
||||
<string name="app_name">FlatBufferSample</string>
|
||||
</resources>
|
||||
35
samples/android_sample.sh
Executable file
35
samples/android_sample.sh
Executable file
@@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
# Copyright 2015 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.
|
||||
|
||||
# Note: This script requires the Android NDK and Android SDK to be installed.
|
||||
# It also requires an Android device to be connected for installing and
|
||||
# running the applicaton.
|
||||
|
||||
sampledir=$(readlink -fn `dirname $0`)
|
||||
currentdir=$(readlink -fn `pwd`)
|
||||
|
||||
if [[ "$sampledir" != "$currentdir" ]]; then
|
||||
echo Error: This script must be run from inside the $sampledir directory.
|
||||
echo You executed it from the $currentdir directory.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Execute `build_apk.sh` to build and run the android app.
|
||||
cd android
|
||||
./build_apk.sh
|
||||
|
||||
# Cleanup the temporary files.
|
||||
rm build.xml local.properties proguard-project.txt project.properties
|
||||
rm -rf bin libs obj
|
||||
49
samples/csharp_sample.sh
Executable file
49
samples/csharp_sample.sh
Executable file
@@ -0,0 +1,49 @@
|
||||
#!/bin/bash
|
||||
# Copyright 2015 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.
|
||||
|
||||
# Note: This script runs on Mac and Linux. It requires `mono` to be installed
|
||||
# and `flatc` to be built (using `cmake` in the root directory).
|
||||
|
||||
sampledir=$(cd $(dirname $BASH_SOURCE) && pwd)
|
||||
rootidr=$(cd $sampledir/.. && pwd)
|
||||
currentdir=$(pwd)
|
||||
|
||||
if [[ "$sampledir" != "$currentdir" ]]; then
|
||||
echo Error: This script must be run from inside the $sampledir directory.
|
||||
echo You executed it from the $currentdir directory.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Run `flatc`. Note: This requires you to compile using `cmake` from the
|
||||
# root `/flatbuffers` directory.
|
||||
if [ -e ../flatc ]; then
|
||||
../flatc --csharp --gen-mutable monster.fbs
|
||||
elif [ -e ../Debug/flatc ]; then
|
||||
../Debug/flatc --csharp --gen-mutable monster.fbs
|
||||
else
|
||||
echo 'flatc' could not be found. Make sure to build FlatBuffers from the \
|
||||
$rootdir directory.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo Compiling and running the C# sample.
|
||||
|
||||
# Compile and execute the sample.
|
||||
mcs SampleBinary.cs MyGame/Sample/*.cs ../net/FlatBuffers/*.cs
|
||||
mono SampleBinary.exe
|
||||
|
||||
# Cleanup temporary files.
|
||||
rm SampleBinary.exe
|
||||
rm -rf MyGame/
|
||||
62
samples/go_sample.sh
Executable file
62
samples/go_sample.sh
Executable file
@@ -0,0 +1,62 @@
|
||||
#!/bin/bash
|
||||
# Copyright 2015 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.
|
||||
|
||||
# Note: This script runs on Mac and Linux. It requires `go` to be installed
|
||||
# and 'flatc' to be built (using `cmake` in the root directory).
|
||||
|
||||
sampledir=$(cd $(dirname $BASH_SOURCE) && pwd)
|
||||
rootdir=$(cd $sampledir/.. && pwd)
|
||||
currentdir=$(pwd)
|
||||
|
||||
if [[ "$sampledir" != "$currentdir" ]]; then
|
||||
echo Error: This script must be run from inside the $sampledir directory.
|
||||
echo You executed it from the $currentdir directory.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Run `flatc`. Note: This requires you to compile using `cmake` from the
|
||||
# root `/flatbuffers` directory.
|
||||
if [ -e ../flatc ]; then
|
||||
../flatc --go monster.fbs
|
||||
elif [ -e ../Debug/flatc ]; then
|
||||
../Debug/flatc --go monster.fbs
|
||||
else
|
||||
echo 'flatc' could not be found. Make sure to build FlatBuffers from the \
|
||||
$rootdir directory.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo Compiling and running the Go sample.
|
||||
|
||||
# Go requires a particular layout of files in order to link the necessary
|
||||
# packages. Copy these files to the respective directores to compile the
|
||||
# sample.
|
||||
mkdir -p ${sampledir}/go_gen/src/MyGame/Sample
|
||||
mkdir -p ${sampledir}/go_gen/src/github.com/google/flatbuffers/go
|
||||
cp MyGame/Sample/*.go ${sampledir}/go_gen/src/MyGame/Sample/
|
||||
cp ${sampledir}/../go/* ${sampledir}/go_gen/src/github.com/google/flatbuffers/go
|
||||
|
||||
# Export the `GOPATH`, so that `go` will know which directories to search for
|
||||
# the libraries.
|
||||
export GOPATH=${sampledir}/go_gen/
|
||||
|
||||
# Compile and execute the sample.
|
||||
go build -o go_sample sample_binary.go
|
||||
./go_sample
|
||||
|
||||
# Clean up the temporary files.
|
||||
rm -rf MyGame/
|
||||
rm -rf ${sampledir}/go_gen/
|
||||
rm go_sample
|
||||
50
samples/java_sample.sh
Executable file
50
samples/java_sample.sh
Executable file
@@ -0,0 +1,50 @@
|
||||
#!/bin/bash
|
||||
# Copyright 2015 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.
|
||||
|
||||
# Note: This script runs on Mac and Linux. It requires `java` to be installed
|
||||
# and `flatc` to be built (using `cmake` in the root directory).
|
||||
|
||||
sampledir=$(cd $(dirname $BASH_SOURCE) && pwd)
|
||||
rootdir=$(cd $sampledir/.. && pwd)
|
||||
currentdir=$(pwd)
|
||||
|
||||
if [[ "$sampledir" != "$currentdir" ]]; then
|
||||
echo Error: This script must be run from inside the $sampledir directory.
|
||||
echo You executed it from the $currentdir directory.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Run `flatc`. Note: This requires you to compile using `cmake` from the
|
||||
# root `/flatbuffers` directory.
|
||||
if [ -e ../flatc ]; then
|
||||
../flatc --java --gen-mutable monster.fbs
|
||||
elif [ -e ../Debug/flatc ]; then
|
||||
../Debug/flatc --java --gen-mutable monster.fbs
|
||||
else
|
||||
echo 'flatc' could not be found. Make sure to build FlatBuffers from the \
|
||||
$rootdir directory.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo Compiling and running the Java sample.
|
||||
|
||||
# Compile and execute the sample.
|
||||
javac -classpath ${sampledir}/../java:${sampledir} SampleBinary.java
|
||||
java -classpath ${sampledir}/../java:${sampledir} SampleBinary
|
||||
|
||||
# Cleanup temporary files.
|
||||
rm -rf MyGame/
|
||||
rm ${sampledir}/../java/com/google/flatbuffers/*.class
|
||||
rm *.class
|
||||
47
samples/javascript_sample.sh
Executable file
47
samples/javascript_sample.sh
Executable file
@@ -0,0 +1,47 @@
|
||||
#!/bin/bash
|
||||
# Copyright 2015 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.
|
||||
|
||||
# Note: This script runs on Mac and Linux. It requires `Node.js` to be installed
|
||||
# and `flatc` to be built (using `cmake` in the root directory).
|
||||
|
||||
sampledir=$(cd $(dirname $BASH_SOURCE) && pwd)
|
||||
rootdir=$(cd $sampledir/.. && pwd)
|
||||
currentdir=$(pwd)
|
||||
|
||||
if [[ "$sampledir" != "$currentdir" ]]; then
|
||||
echo Error: This script must be run from inside the $sampledir directory.
|
||||
echo You executed it from the $currentdir directory.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Run `flatc`. Note: This requires you to compile using `cmake` from the
|
||||
# root `/flatbuffers` directory.
|
||||
if [ -e ../flatc ]; then
|
||||
../flatc --js monster.fbs
|
||||
elif [ -e ../Debug/flatc ]; then
|
||||
../Debug/flatc --js monster.fbs
|
||||
else
|
||||
echo 'flatc' could not be found. Make sure to build FlatBuffers from the \
|
||||
$rootdir directory.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo Running the JavaScript sample.
|
||||
|
||||
# Execute the sample.
|
||||
node samplebinary.js
|
||||
|
||||
# Cleanup temporary files.
|
||||
rm monster_generated.js
|
||||
@@ -1,10 +1,10 @@
|
||||
// example IDL file
|
||||
// Example IDL file for our monster's schema.
|
||||
|
||||
namespace MyGame.Sample;
|
||||
|
||||
enum Color:byte { Red = 0, Green, Blue = 2 }
|
||||
|
||||
union Any { Monster } // add more elements..
|
||||
union Equipment { Weapon } // Optionally add more tables.
|
||||
|
||||
struct Vec3 {
|
||||
x:float;
|
||||
@@ -20,6 +20,13 @@ table Monster {
|
||||
friendly:bool = false (deprecated);
|
||||
inventory:[ubyte];
|
||||
color:Color = Blue;
|
||||
weapons:[Weapon];
|
||||
equipped:Equipment;
|
||||
}
|
||||
|
||||
table Weapon {
|
||||
name:string;
|
||||
damage:short;
|
||||
}
|
||||
|
||||
root_type Monster;
|
||||
|
||||
@@ -1,153 +0,0 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
#ifndef FLATBUFFERS_GENERATED_MONSTER_MYGAME_SAMPLE_H_
|
||||
#define FLATBUFFERS_GENERATED_MONSTER_MYGAME_SAMPLE_H_
|
||||
|
||||
#include "flatbuffers/flatbuffers.h"
|
||||
|
||||
|
||||
namespace MyGame {
|
||||
namespace Sample {
|
||||
|
||||
struct Vec3;
|
||||
struct Monster;
|
||||
|
||||
enum Color {
|
||||
Color_Red = 0,
|
||||
Color_Green = 1,
|
||||
Color_Blue = 2,
|
||||
Color_MIN = Color_Red,
|
||||
Color_MAX = Color_Blue
|
||||
};
|
||||
|
||||
inline const char **EnumNamesColor() {
|
||||
static const char *names[] = { "Red", "Green", "Blue", nullptr };
|
||||
return names;
|
||||
}
|
||||
|
||||
inline const char *EnumNameColor(Color e) { return EnumNamesColor()[static_cast<int>(e)]; }
|
||||
|
||||
enum Any {
|
||||
Any_NONE = 0,
|
||||
Any_Monster = 1,
|
||||
Any_MIN = Any_NONE,
|
||||
Any_MAX = Any_Monster
|
||||
};
|
||||
|
||||
inline const char **EnumNamesAny() {
|
||||
static const char *names[] = { "NONE", "Monster", nullptr };
|
||||
return names;
|
||||
}
|
||||
|
||||
inline const char *EnumNameAny(Any e) { return EnumNamesAny()[static_cast<int>(e)]; }
|
||||
|
||||
inline bool VerifyAny(flatbuffers::Verifier &verifier, const void *union_obj, Any type);
|
||||
|
||||
MANUALLY_ALIGNED_STRUCT(4) Vec3 FLATBUFFERS_FINAL_CLASS {
|
||||
private:
|
||||
float x_;
|
||||
float y_;
|
||||
float z_;
|
||||
|
||||
public:
|
||||
Vec3(float _x, float _y, float _z)
|
||||
: x_(flatbuffers::EndianScalar(_x)), y_(flatbuffers::EndianScalar(_y)), z_(flatbuffers::EndianScalar(_z)) { }
|
||||
|
||||
float x() const { return flatbuffers::EndianScalar(x_); }
|
||||
void mutate_x(float _x) { flatbuffers::WriteScalar(&x_, _x); }
|
||||
float y() const { return flatbuffers::EndianScalar(y_); }
|
||||
void mutate_y(float _y) { flatbuffers::WriteScalar(&y_, _y); }
|
||||
float z() const { return flatbuffers::EndianScalar(z_); }
|
||||
void mutate_z(float _z) { flatbuffers::WriteScalar(&z_, _z); }
|
||||
};
|
||||
STRUCT_END(Vec3, 12);
|
||||
|
||||
struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
enum {
|
||||
VT_POS = 4,
|
||||
VT_MANA = 6,
|
||||
VT_HP = 8,
|
||||
VT_NAME = 10,
|
||||
VT_INVENTORY = 14,
|
||||
VT_COLOR = 16
|
||||
};
|
||||
const Vec3 *pos() const { return GetStruct<const Vec3 *>(VT_POS); }
|
||||
Vec3 *mutable_pos() { return GetStruct<Vec3 *>(VT_POS); }
|
||||
int16_t mana() const { return GetField<int16_t>(VT_MANA, 150); }
|
||||
bool mutate_mana(int16_t _mana) { return SetField(VT_MANA, _mana); }
|
||||
int16_t hp() const { return GetField<int16_t>(VT_HP, 100); }
|
||||
bool mutate_hp(int16_t _hp) { return SetField(VT_HP, _hp); }
|
||||
const flatbuffers::String *name() const { return GetPointer<const flatbuffers::String *>(VT_NAME); }
|
||||
flatbuffers::String *mutable_name() { return GetPointer<flatbuffers::String *>(VT_NAME); }
|
||||
const flatbuffers::Vector<uint8_t> *inventory() const { return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_INVENTORY); }
|
||||
flatbuffers::Vector<uint8_t> *mutable_inventory() { return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_INVENTORY); }
|
||||
Color color() const { return static_cast<Color>(GetField<int8_t>(VT_COLOR, 2)); }
|
||||
bool mutate_color(Color _color) { return SetField(VT_COLOR, static_cast<int8_t>(_color)); }
|
||||
bool Verify(flatbuffers::Verifier &verifier) const {
|
||||
return VerifyTableStart(verifier) &&
|
||||
VerifyField<Vec3>(verifier, VT_POS) &&
|
||||
VerifyField<int16_t>(verifier, VT_MANA) &&
|
||||
VerifyField<int16_t>(verifier, VT_HP) &&
|
||||
VerifyField<flatbuffers::uoffset_t>(verifier, VT_NAME) &&
|
||||
verifier.Verify(name()) &&
|
||||
VerifyField<flatbuffers::uoffset_t>(verifier, VT_INVENTORY) &&
|
||||
verifier.Verify(inventory()) &&
|
||||
VerifyField<int8_t>(verifier, VT_COLOR) &&
|
||||
verifier.EndTable();
|
||||
}
|
||||
};
|
||||
|
||||
struct MonsterBuilder {
|
||||
flatbuffers::FlatBufferBuilder &fbb_;
|
||||
flatbuffers::uoffset_t start_;
|
||||
void add_pos(const Vec3 *pos) { fbb_.AddStruct(Monster::VT_POS, pos); }
|
||||
void add_mana(int16_t mana) { fbb_.AddElement<int16_t>(Monster::VT_MANA, mana, 150); }
|
||||
void add_hp(int16_t hp) { fbb_.AddElement<int16_t>(Monster::VT_HP, hp, 100); }
|
||||
void add_name(flatbuffers::Offset<flatbuffers::String> name) { fbb_.AddOffset(Monster::VT_NAME, name); }
|
||||
void add_inventory(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> inventory) { fbb_.AddOffset(Monster::VT_INVENTORY, inventory); }
|
||||
void add_color(Color color) { fbb_.AddElement<int8_t>(Monster::VT_COLOR, static_cast<int8_t>(color), 2); }
|
||||
MonsterBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); }
|
||||
MonsterBuilder &operator=(const MonsterBuilder &);
|
||||
flatbuffers::Offset<Monster> Finish() {
|
||||
auto o = flatbuffers::Offset<Monster>(fbb_.EndTable(start_, 7));
|
||||
return o;
|
||||
}
|
||||
};
|
||||
|
||||
inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
const Vec3 *pos = 0,
|
||||
int16_t mana = 150,
|
||||
int16_t hp = 100,
|
||||
flatbuffers::Offset<flatbuffers::String> name = 0,
|
||||
flatbuffers::Offset<flatbuffers::Vector<uint8_t>> inventory = 0,
|
||||
Color color = Color_Blue) {
|
||||
MonsterBuilder builder_(_fbb);
|
||||
builder_.add_inventory(inventory);
|
||||
builder_.add_name(name);
|
||||
builder_.add_pos(pos);
|
||||
builder_.add_hp(hp);
|
||||
builder_.add_mana(mana);
|
||||
builder_.add_color(color);
|
||||
return builder_.Finish();
|
||||
}
|
||||
|
||||
inline bool VerifyAny(flatbuffers::Verifier &verifier, const void *union_obj, Any type) {
|
||||
switch (type) {
|
||||
case Any_NONE: return true;
|
||||
case Any_Monster: return verifier.VerifyTable(reinterpret_cast<const Monster *>(union_obj));
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline const MyGame::Sample::Monster *GetMonster(const void *buf) { return flatbuffers::GetRoot<MyGame::Sample::Monster>(buf); }
|
||||
|
||||
inline Monster *GetMutableMonster(void *buf) { return flatbuffers::GetMutableRoot<Monster>(buf); }
|
||||
|
||||
inline bool VerifyMonsterBuffer(flatbuffers::Verifier &verifier) { return verifier.VerifyBuffer<MyGame::Sample::Monster>(); }
|
||||
|
||||
inline void FinishMonsterBuffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<MyGame::Sample::Monster> root) { fbb.Finish(root); }
|
||||
|
||||
} // namespace Sample
|
||||
} // namespace MyGame
|
||||
|
||||
#endif // FLATBUFFERS_GENERATED_MONSTER_MYGAME_SAMPLE_H_
|
||||
@@ -4,6 +4,6 @@
|
||||
y: 2,
|
||||
z: 3
|
||||
},
|
||||
hp: 80,
|
||||
name: "MyMonster"
|
||||
hp: 300,
|
||||
name: "Orc"
|
||||
}
|
||||
|
||||
47
samples/php_sample.sh
Executable file
47
samples/php_sample.sh
Executable file
@@ -0,0 +1,47 @@
|
||||
#!/bin/bash
|
||||
# Copyright 2015 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.
|
||||
|
||||
# Note: This script runs on Mac and Linux. It requires `php` to be installed
|
||||
# and `flatc` to be built (using `cmake` in the root directory).
|
||||
|
||||
sampledir=$(cd $(dirname $BASH_SOURCE) && pwd)
|
||||
rootdir=$(cd $sampledir/.. && pwd)
|
||||
currentdir=$(pwd)
|
||||
|
||||
if [[ "$sampledir" != "$currentdir" ]]; then
|
||||
echo Error: This script must be run from inside the $sampledir directory.
|
||||
echo You executed it from the $currentdir directory.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Run `flatc`. Note: This requires you to compile using `cmake` from the
|
||||
# root `/flatbuffers` directory.
|
||||
if [ -e ../flatc ]; then
|
||||
../flatc --php monster.fbs
|
||||
elif [ -e ../Debug/flatc ]; then
|
||||
../Debug/flatc --php monster.fbs
|
||||
else
|
||||
echo 'flatc' could not be found. Make sure to build FlatBuffers from the \
|
||||
$rootdir directory.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo Running the PHP sample.
|
||||
|
||||
# Execute the sample.
|
||||
php SampleBinary.php
|
||||
|
||||
# Clean up temporary files.
|
||||
rm -rf MyGame/
|
||||
47
samples/python_sample.sh
Executable file
47
samples/python_sample.sh
Executable file
@@ -0,0 +1,47 @@
|
||||
#!/bin/bash
|
||||
# Copyright 2015 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.
|
||||
|
||||
# Note: This script runs on Mac and Linux. It requires `python` to be installed
|
||||
# and `flatc` to be built (using `cmake` in the root directory).
|
||||
|
||||
sampledir=$(cd $(dirname $BASH_SOURCE) && pwd)
|
||||
rootdir=$(cd $sampledir/.. && pwd)
|
||||
currentdir=$(pwd)
|
||||
|
||||
if [[ "$sampledir" != "$currentdir" ]]; then
|
||||
echo Error: This script must be run from inside the $sampledir directory.
|
||||
echo You executed it from the $currentdir directory.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Run `flatc`. Note: This requires you to compile using `cmake` from the
|
||||
# root `/flatbuffers` directory.
|
||||
if [ -e ../flatc ]; then
|
||||
../flatc --python monster.fbs
|
||||
elif [ -e ../Debug/flatc ]; then
|
||||
../Debug/flatc --python monster.fbs
|
||||
else
|
||||
echo 'flatc' could not be found. Make sure to build FlatBuffers from the \
|
||||
$rootdir directory.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo Running the Python sample.
|
||||
|
||||
# Execute the sample.
|
||||
python sample_binary.py
|
||||
|
||||
# Clean up the temporary files.
|
||||
rm -rf MyGame
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All rights reserved.
|
||||
* Copyright 2015 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.
|
||||
@@ -14,9 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "flatbuffers/flatbuffers.h"
|
||||
|
||||
#include "monster_generated.h"
|
||||
#include "monster_generated.h" // Already includes "flatbuffers/flatbuffers.h".
|
||||
|
||||
using namespace MyGame::Sample;
|
||||
|
||||
@@ -26,7 +24,25 @@ int main(int /*argc*/, const char * /*argv*/[]) {
|
||||
// Build up a serialized buffer algorithmically:
|
||||
flatbuffers::FlatBufferBuilder builder;
|
||||
|
||||
auto vec = Vec3(1, 2, 3);
|
||||
// First, lets serialize some weapons for the Monster: A 'sword' and an 'axe'.
|
||||
auto weapon_one_name = builder.CreateString("Sword");
|
||||
short weapon_one_damage = 3;
|
||||
|
||||
auto weapon_two_name = builder.CreateString("Axe");
|
||||
short weapon_two_damage = 5;
|
||||
|
||||
// Use the `CreateWeapon` shortcut to create Weapons with all fields set.
|
||||
auto sword = CreateWeapon(builder, weapon_one_name, weapon_one_damage);
|
||||
auto axe = CreateWeapon(builder, weapon_two_name, weapon_two_damage);
|
||||
|
||||
// Create a FlatBuffer's `vector` from the `std::vector`.
|
||||
std::vector<flatbuffers::Offset<Weapon>> weapons_vector;
|
||||
weapons_vector.push_back(sword);
|
||||
weapons_vector.push_back(axe);
|
||||
auto weapons = builder.CreateVector(weapons_vector);
|
||||
|
||||
// Second, serialize the rest of the objects needed by the Monster.
|
||||
auto position = Vec3(1.0f, 2.0f, 3.0f);
|
||||
|
||||
auto name = builder.CreateString("MyMonster");
|
||||
|
||||
@@ -34,31 +50,53 @@ int main(int /*argc*/, const char * /*argv*/[]) {
|
||||
auto inventory = builder.CreateVector(inv_data, 10);
|
||||
|
||||
// Shortcut for creating monster with all fields set:
|
||||
auto mloc = CreateMonster(builder, &vec, 150, 80, name, inventory,
|
||||
Color_Blue);
|
||||
auto orc = CreateMonster(builder, &position, 150, 80, name, inventory,
|
||||
Color_Red, weapons, Equipment_Weapon, axe.Union());
|
||||
|
||||
builder.Finish(mloc);
|
||||
// We now have a FlatBuffer we can store or send somewhere.
|
||||
builder.Finish(orc); // Serialize the root of the object.
|
||||
|
||||
// We now have a FlatBuffer we can store on disk or send over a network.
|
||||
|
||||
// ** file/network code goes here :) **
|
||||
// access builder.GetBufferPointer() for builder.GetSize() bytes
|
||||
|
||||
// Instead, we're going to access it straight away.
|
||||
// Instead, we're going to access it right away (as if we just received it).
|
||||
|
||||
// Get access to the root:
|
||||
auto monster = GetMonster(builder.GetBufferPointer());
|
||||
|
||||
// Get and test some scalar types from the FlatBuffer.
|
||||
assert(monster->hp() == 80);
|
||||
assert(monster->mana() == 150); // default
|
||||
assert(monster->name()->str() == "MyMonster");
|
||||
|
||||
// Get and test a field of the FlatBuffer's `struct`.
|
||||
auto pos = monster->pos();
|
||||
assert(pos);
|
||||
assert(pos->z() == 3);
|
||||
assert(pos->z() == 3.0f);
|
||||
(void)pos;
|
||||
|
||||
// Get a test an element from the `inventory` FlatBuffer's `vector`.
|
||||
auto inv = monster->inventory();
|
||||
assert(inv);
|
||||
assert(inv->Get(9) == 9);
|
||||
(void)inv;
|
||||
|
||||
// Get and test the `weapons` FlatBuffers's `vector`.
|
||||
std::string expected_weapon_names[] = {"Sword", "Axe"};
|
||||
short expected_weapon_damages[] = {3, 5};
|
||||
auto weps = monster->weapons();
|
||||
for (unsigned int i = 0; i < weps->size(); i++) {
|
||||
assert(weps->Get(i)->name()->str() == expected_weapon_names[i]);
|
||||
assert(weps->Get(i)->damage() == expected_weapon_damages[i]);
|
||||
}
|
||||
|
||||
// Get and test the `Equipment` union (`equipped` field).
|
||||
assert(monster->equipped_type() == Equipment_Weapon);
|
||||
auto equipped = static_cast<const Weapon*>(monster->equipped());
|
||||
assert(equipped->name()->str() == "Axe");
|
||||
assert(equipped->damage() == 5);
|
||||
|
||||
printf("The FlatBuffer was successfully created and verified!\n");
|
||||
}
|
||||
|
||||
|
||||
165
samples/sample_binary.go
Normal file
165
samples/sample_binary.go
Normal file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright 2015 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.
|
||||
*/
|
||||
|
||||
// To run, use the `go_sample.sh` script.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
flatbuffers "github.com/google/flatbuffers/go"
|
||||
"fmt"
|
||||
"strconv"
|
||||
sample "MyGame/Sample"
|
||||
)
|
||||
|
||||
// Example how to use Flatbuffers to create and read binary buffers.
|
||||
func main() {
|
||||
builder := flatbuffers.NewBuilder(0)
|
||||
|
||||
// Create some weapons for our Monster ("Sword" and "Axe").
|
||||
weaponOne := builder.CreateString("Sword")
|
||||
weaponTwo := builder.CreateString("Axe")
|
||||
|
||||
sample.WeaponStart(builder)
|
||||
sample.WeaponAddName(builder, weaponOne)
|
||||
sample.WeaponAddDamage(builder, 3)
|
||||
sword := sample.WeaponEnd(builder)
|
||||
|
||||
sample.WeaponStart(builder)
|
||||
sample.WeaponAddName(builder, weaponTwo)
|
||||
sample.WeaponAddDamage(builder, 5)
|
||||
axe := sample.WeaponEnd(builder)
|
||||
|
||||
// Serialize the FlatBuffer data.
|
||||
name := builder.CreateString("Orc")
|
||||
|
||||
sample.MonsterStartInventoryVector(builder, 10)
|
||||
// Note: Since we prepend the bytes, this loop iterates in reverse.
|
||||
for i := 9; i >= 0; i-- {
|
||||
builder.PrependByte(byte(i))
|
||||
}
|
||||
inv := builder.EndVector(10)
|
||||
|
||||
sample.MonsterStartWeaponsVector(builder, 2)
|
||||
// Note: Since we prepend the weapons, prepend in reverse order.
|
||||
builder.PrependUOffsetT(axe)
|
||||
builder.PrependUOffsetT(sword)
|
||||
weapons := builder.EndVector(2)
|
||||
|
||||
pos := sample.CreateVec3(builder, 1.0, 2.0, 3.0)
|
||||
|
||||
sample.MonsterStart(builder)
|
||||
sample.MonsterAddPos(builder, pos)
|
||||
sample.MonsterAddHp(builder, 300)
|
||||
sample.MonsterAddName(builder, name)
|
||||
sample.MonsterAddInventory(builder, inv)
|
||||
sample.MonsterAddColor(builder, sample.ColorRed)
|
||||
sample.MonsterAddWeapons(builder, weapons)
|
||||
sample.MonsterAddEquippedType(builder, sample.EquipmentWeapon)
|
||||
sample.MonsterAddEquipped(builder, axe)
|
||||
orc := sample.MonsterEnd(builder)
|
||||
|
||||
builder.Finish(orc)
|
||||
|
||||
// We now have a FlatBuffer that we could store on disk or send over a network.
|
||||
|
||||
// ...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).
|
||||
|
||||
buf := builder.FinishedBytes()
|
||||
|
||||
// Note: We use `0` for the offset here, since we got the data using the
|
||||
// `builder.FinishedBytes()` method. This simulates the data you would store/receive in your
|
||||
// FlatBuffer. If you wanted to read from the `builder.Bytes` directly, you would need to
|
||||
// pass in the offset of `builder.Head()`, as the builder actually constructs the buffer
|
||||
// backwards.
|
||||
monster := sample.GetRootAsMonster(buf, 0)
|
||||
|
||||
// Note: We did not set the `mana` field explicitly, so we get the
|
||||
// default value.
|
||||
assert(monster.Mana() == 150, "`monster.Mana()`", strconv.Itoa(int(monster.Mana())), "150")
|
||||
assert(monster.Hp() == 300, "`monster.Hp()`", strconv.Itoa(int(monster.Hp())), "300")
|
||||
assert(string(monster.Name()) == "Orc", "`string(monster.Name())`", string(monster.Name()),
|
||||
"\"Orc\"")
|
||||
assert(monster.Color() == sample.ColorRed, "`monster.Color()`",
|
||||
strconv.Itoa(int(monster.Color())), strconv.Itoa(int(sample.ColorRed)))
|
||||
|
||||
// Note: Whenever you access a new object, like in `Pos()`, a new temporary accessor object
|
||||
// gets created. If your code is very performance sensitive, you can pass in a pointer to an
|
||||
// existing `Vec3` instead of `nil`. This allows you to reuse it across many calls to reduce
|
||||
// the amount of object allocation/garbage collection.
|
||||
assert(monster.Pos(nil).X() == 1.0, "`monster.Pos(nil).X()`",
|
||||
strconv.FormatFloat(float64(monster.Pos(nil).X()), 'f', 1, 32), "1.0")
|
||||
assert(monster.Pos(nil).Y() == 2.0, "`monster.Pos(nil).Y()`",
|
||||
strconv.FormatFloat(float64(monster.Pos(nil).Y()), 'f', 1, 32), "2.0")
|
||||
assert(monster.Pos(nil).Z() == 3.0, "`monster.Pos(nil).Z()`",
|
||||
strconv.FormatFloat(float64(monster.Pos(nil).Z()), 'f', 1, 32), "3.0")
|
||||
|
||||
// For vectors, like `Inventory`, they have a method suffixed with 'Length' that can be used
|
||||
// to query the length of the vector. You can index the vector by passing an index value
|
||||
// into the accessor.
|
||||
for i := 0; i < monster.InventoryLength(); i++ {
|
||||
assert(monster.Inventory(i) == byte(i), "`monster.Inventory(i)`",
|
||||
strconv.Itoa(int(monster.Inventory(i))), strconv.Itoa(int(byte(i))))
|
||||
}
|
||||
|
||||
expectedWeaponNames := []string{"Sword", "Axe"}
|
||||
expectedWeaponDamages := []int{3, 5}
|
||||
weapon := new(sample.Weapon) // We need a `sample.Weapon` to pass into `monster.Weapons()`
|
||||
// to capture the output of that function.
|
||||
for i := 0; i < monster.WeaponsLength(); i++ {
|
||||
if monster.Weapons(weapon, i) {
|
||||
assert(string(weapon.Name()) == expectedWeaponNames[i], "`weapon.Name()`",
|
||||
string(weapon.Name()), expectedWeaponNames[i])
|
||||
assert(int(weapon.Damage()) == expectedWeaponDamages[i],
|
||||
"`weapon.Damage()`", strconv.Itoa(int(weapon.Damage())),
|
||||
strconv.Itoa(expectedWeaponDamages[i]))
|
||||
}
|
||||
}
|
||||
|
||||
// For FlatBuffer `union`s, you can get the type of the union, as well as the union
|
||||
// data itself.
|
||||
assert(monster.EquippedType() == sample.EquipmentWeapon, "`monster.EquippedType()`",
|
||||
strconv.Itoa(int(monster.EquippedType())), strconv.Itoa(int(sample.EquipmentWeapon)))
|
||||
|
||||
unionTable := new(flatbuffers.Table)
|
||||
if monster.Equipped(unionTable) {
|
||||
// An example of how you can appropriately convert the table depending on the
|
||||
// FlatBuffer `union` type. You could add `else if` and `else` clauses to handle
|
||||
// other FlatBuffer `union` types for this field. (Similarly, this could be
|
||||
// done in a switch statement.)
|
||||
if monster.EquippedType() == sample.EquipmentWeapon {
|
||||
unionWeapon := new(sample.Weapon)
|
||||
unionWeapon.Init(unionTable.Bytes, unionTable.Pos)
|
||||
|
||||
assert(string(unionWeapon.Name()) == "Axe", "`unionWeapon.Name()`",
|
||||
string(unionWeapon.Name()), "Axe")
|
||||
assert(int(unionWeapon.Damage()) == 5, "`unionWeapon.Damage()`",
|
||||
strconv.Itoa(int(unionWeapon.Damage())), strconv.Itoa(5))
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("The FlatBuffer was successfully created and verified!\n")
|
||||
}
|
||||
|
||||
// A helper function to print out if an assertion failed.
|
||||
func assert(assertPassed bool, codeExecuted string, actualValue string, expectedValue string) {
|
||||
if assertPassed == false {
|
||||
panic("Assert failed! " + codeExecuted + " (" + actualValue +
|
||||
") was not equal to " + expectedValue + ".")
|
||||
}
|
||||
}
|
||||
137
samples/sample_binary.py
Normal file
137
samples/sample_binary.py
Normal file
@@ -0,0 +1,137 @@
|
||||
#!/usr/bin/python
|
||||
# Copyright 2015 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.
|
||||
|
||||
# To run this file, use `python_sample.sh`.
|
||||
|
||||
# Append paths to the `flatbuffers` and `MyGame` modules. This is necessary
|
||||
# to facilitate executing this script in the `samples` folder, and to root
|
||||
# folder (where it gets placed when using `cmake`).
|
||||
import os
|
||||
import sys
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__), '../python'))
|
||||
|
||||
import flatbuffers
|
||||
import MyGame.Sample.Color
|
||||
import MyGame.Sample.Equipment
|
||||
import MyGame.Sample.Monster
|
||||
import MyGame.Sample.Vec3
|
||||
import MyGame.Sample.Weapon
|
||||
|
||||
# Example of how to use FlatBuffers to create and read binary buffers.
|
||||
|
||||
def main():
|
||||
builder = flatbuffers.Builder(0)
|
||||
|
||||
# Create some weapons for our Monster ('Sword' and 'Axe').
|
||||
weapon_one = builder.CreateString('Sword')
|
||||
weapon_two = builder.CreateString('Axe')
|
||||
|
||||
MyGame.Sample.Weapon.WeaponStart(builder)
|
||||
MyGame.Sample.Weapon.WeaponAddName(builder, weapon_one)
|
||||
MyGame.Sample.Weapon.WeaponAddDamage(builder, 3)
|
||||
sword = MyGame.Sample.Weapon.WeaponEnd(builder)
|
||||
|
||||
MyGame.Sample.Weapon.WeaponStart(builder)
|
||||
MyGame.Sample.Weapon.WeaponAddName(builder, weapon_two)
|
||||
MyGame.Sample.Weapon.WeaponAddDamage(builder, 5)
|
||||
axe = MyGame.Sample.Weapon.WeaponEnd(builder)
|
||||
|
||||
# Serialize the FlatBuffer data.
|
||||
name = builder.CreateString('Orc')
|
||||
|
||||
MyGame.Sample.Monster.MonsterStartInventoryVector(builder, 10)
|
||||
# Note: Since we prepend the bytes, this loop iterates in reverse order.
|
||||
for i in reversed(range(0, 10)):
|
||||
builder.PrependByte(i)
|
||||
inv = builder.EndVector(10)
|
||||
|
||||
MyGame.Sample.Monster.MonsterStartWeaponsVector(builder, 2)
|
||||
# Note: Since we prepend the data, prepend the weapons in reverse order.
|
||||
builder.PrependUOffsetTRelative(axe)
|
||||
builder.PrependUOffsetTRelative(sword)
|
||||
weapons = builder.EndVector(2)
|
||||
|
||||
pos = MyGame.Sample.Vec3.CreateVec3(builder, 1.0, 2.0, 3.0)
|
||||
|
||||
MyGame.Sample.Monster.MonsterStart(builder)
|
||||
MyGame.Sample.Monster.MonsterAddPos(builder, pos)
|
||||
MyGame.Sample.Monster.MonsterAddHp(builder, 300)
|
||||
MyGame.Sample.Monster.MonsterAddName(builder, name)
|
||||
MyGame.Sample.Monster.MonsterAddInventory(builder, inv)
|
||||
MyGame.Sample.Monster.MonsterAddColor(builder,
|
||||
MyGame.Sample.Color.Color().Red)
|
||||
MyGame.Sample.Monster.MonsterAddWeapons(builder, weapons)
|
||||
MyGame.Sample.Monster.MonsterAddEquippedType(
|
||||
builder, MyGame.Sample.Equipment.Equipment().Weapon)
|
||||
MyGame.Sample.Monster.MonsterAddEquipped(builder, axe)
|
||||
orc = MyGame.Sample.Monster.MonsterEnd(builder)
|
||||
|
||||
builder.Finish(orc)
|
||||
|
||||
# We now have a FlatBuffer that we could store on disk or send over a network.
|
||||
|
||||
# ...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).
|
||||
|
||||
buf = builder.Output()
|
||||
|
||||
# Note: We use `0` for the offset here, since we got the data using the
|
||||
# `builder.Output()` method. This simulates the data you would store/receive
|
||||
# in your FlatBuffer. If you wanted to read from the `builder.Bytes` directly,
|
||||
# you would need to pass in the offset of `builder.Head()`, as the builder
|
||||
# actually constructs the buffer backwards.
|
||||
monster = MyGame.Sample.Monster.Monster.GetRootAsMonster(buf, 0)
|
||||
|
||||
# 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.Color().Red
|
||||
assert monster.Pos().X() == 1.0
|
||||
assert monster.Pos().Y() == 2.0
|
||||
assert monster.Pos().Z() == 3.0
|
||||
|
||||
# Get and test the `inventory` FlatBuffer `vector`.
|
||||
for i in xrange(monster.InventoryLength()):
|
||||
assert monster.Inventory(i) == i
|
||||
|
||||
# Get and test the `weapons` FlatBuffer `vector` of `table`s.
|
||||
expected_weapon_names = ['Sword', 'Axe']
|
||||
expected_weapon_damages = [3, 5]
|
||||
for i in xrange(monster.WeaponsLength()):
|
||||
assert monster.Weapons(i).Name() == expected_weapon_names[i]
|
||||
assert monster.Weapons(i).Damage() == expected_weapon_damages[i]
|
||||
|
||||
# Get and test the `equipped` FlatBuffer `union`.
|
||||
assert monster.EquippedType() == MyGame.Sample.Equipment.Equipment().Weapon
|
||||
|
||||
# An example of how you can appropriately convert the table depending on the
|
||||
# FlatBuffer `union` type. You could add `elif` and `else` clauses to handle
|
||||
# the other FlatBuffer `union` types for this field.
|
||||
if monster.EquippedType() == MyGame.Sample.Equipment.Equipment().Weapon:
|
||||
# `monster.Equipped()` returns a `flatbuffers.Table`, which can be used
|
||||
# to initialize a `MyGame.Sample.Weapon.Weapon()`, in this case.
|
||||
union_weapon = MyGame.Sample.Weapon.Weapon()
|
||||
union_weapon.Init(monster.Equipped().Bytes, monster.Equipped().Pos)
|
||||
|
||||
assert union_weapon.Name() == "Axe"
|
||||
assert union_weapon.Damage() == 5
|
||||
|
||||
print 'The FlatBuffer was successfully created and verified!'
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -14,11 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "flatbuffers/flatbuffers.h"
|
||||
#include "flatbuffers/idl.h"
|
||||
#include "flatbuffers/util.h"
|
||||
|
||||
#include "monster_generated.h"
|
||||
#include "monster_generated.h" // Already includes "flatbuffers/flatbuffers.h".
|
||||
|
||||
using namespace MyGame::Sample;
|
||||
|
||||
@@ -52,4 +51,6 @@ int main(int /*argc*/, const char * /*argv*/[]) {
|
||||
if (jsongen != jsonfile) {
|
||||
printf("%s----------------\n%s", jsongen.c_str(), jsonfile.c_str());
|
||||
}
|
||||
|
||||
printf("The FlatBuffer has been parsed from JSON successfully.\n");
|
||||
}
|
||||
|
||||
106
samples/samplebinary.js
Normal file
106
samples/samplebinary.js
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright 2015 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.
|
||||
*/
|
||||
|
||||
// To run, use the `javascript_sample.sh` script.
|
||||
|
||||
var assert = require('assert');
|
||||
var flatbuffers = require('../js/flatbuffers').flatbuffers;
|
||||
var MyGame = require('./monster_generated').MyGame;
|
||||
|
||||
// Example how to use FlatBuffers to create and read binary buffers.
|
||||
function main() {
|
||||
var builder = new flatbuffers.Builder(0);
|
||||
|
||||
// Create some weapons for our Monster ('Sword' and 'Axe').
|
||||
var weaponOne = builder.createString('Sword');
|
||||
var weaponTwo = builder.createString('Axe');
|
||||
|
||||
MyGame.Sample.Weapon.startWeapon(builder);
|
||||
MyGame.Sample.Weapon.addName(builder, weaponOne);
|
||||
MyGame.Sample.Weapon.addDamage(builder, 3);
|
||||
var sword = MyGame.Sample.Weapon.endWeapon(builder);
|
||||
|
||||
MyGame.Sample.Weapon.startWeapon(builder);
|
||||
MyGame.Sample.Weapon.addName(builder, weaponTwo);
|
||||
MyGame.Sample.Weapon.addDamage(builder, 5);
|
||||
var axe = MyGame.Sample.Weapon.endWeapon(builder);
|
||||
|
||||
// Serialize the FlatBuffer data.
|
||||
var name = builder.createString('Orc');
|
||||
|
||||
var treasure = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||
var inv = MyGame.Sample.Monster.createInventoryVector(builder, treasure);
|
||||
|
||||
var weaps = [sword, axe];
|
||||
var weapons = MyGame.Sample.Monster.createWeaponsVector(builder, weaps);
|
||||
|
||||
var pos = MyGame.Sample.Vec3.createVec3(builder, 1.0, 2.0, 3.0);
|
||||
|
||||
MyGame.Sample.Monster.startMonster(builder);
|
||||
MyGame.Sample.Monster.addPos(builder, pos);
|
||||
MyGame.Sample.Monster.addHp(builder, 300);
|
||||
MyGame.Sample.Monster.addColor(builder, MyGame.Sample.Color.Red)
|
||||
MyGame.Sample.Monster.addName(builder, name);
|
||||
MyGame.Sample.Monster.addInventory(builder, inv);
|
||||
MyGame.Sample.Monster.addWeapons(builder, weapons);
|
||||
MyGame.Sample.Monster.addEquippedType(builder, MyGame.Sample.Equipment.Weapon);
|
||||
MyGame.Sample.Monster.addEquipped(builder, weaps[1]);
|
||||
var orc = MyGame.Sample.Monster.endMonster(builder);
|
||||
|
||||
builder.finish(orc); // You may also call 'MyGame.Example.Monster.finishMonsterBuffer(builder, orc);'.
|
||||
|
||||
// We now have a FlatBuffer that can be stored on disk or sent over a network.
|
||||
|
||||
// ...Code to store to disk or send over a network goes here...
|
||||
|
||||
// Instead, we are going to access it right away, as if we just received it.
|
||||
|
||||
var buf = builder.dataBuffer();
|
||||
|
||||
// Get access to the root:
|
||||
var monster = MyGame.Sample.Monster.getRootAsMonster(buf);
|
||||
|
||||
// Note: We did not set the `mana` field explicitly, so we get back the default value.
|
||||
assert.equal(monster.mana(), 150);
|
||||
assert.equal(monster.hp(), 300);
|
||||
assert.equal(monster.name(), 'Orc');
|
||||
assert.equal(monster.color(), MyGame.Sample.Color.Red);
|
||||
assert.equal(monster.pos().x(), 1.0);
|
||||
assert.equal(monster.pos().y(), 2.0);
|
||||
assert.equal(monster.pos().z(), 3.0);
|
||||
|
||||
// Get and test the `inventory` FlatBuffer `vector`.
|
||||
for (var i = 0; i < monster.inventoryLength(); i++) {
|
||||
assert.equal(monster.inventory(i), i);
|
||||
}
|
||||
|
||||
// Get and test the `weapons` FlatBuffer `vector` of `table`s.
|
||||
var expectedWeaponNames = ['Sword', 'Axe'];
|
||||
var expectedWeaponDamages = [3, 5];
|
||||
for (var i = 0; i < monster.weaponsLength(); i++) {
|
||||
assert.equal(monster.weapons(i).name(), expectedWeaponNames[i]);
|
||||
assert.equal(monster.weapons(i).damage(), expectedWeaponDamages[i]);
|
||||
}
|
||||
|
||||
// Get and test the `equipped` FlatBuffer `union`.
|
||||
assert.equal(monster.equippedType(), MyGame.Sample.Equipment.Weapon);
|
||||
assert.equal(monster.equipped(new MyGame.Sample.Weapon()).name(), 'Axe');
|
||||
assert.equal(monster.equipped(new MyGame.Sample.Weapon()).damage(), 5);
|
||||
|
||||
console.log('The FlatBuffer was successfully created and verified!');
|
||||
}
|
||||
|
||||
main();
|
||||
Reference in New Issue
Block a user