suguru.dev

バンクーバーで働くエンジニアの備忘録

FlatBuffers導入

概要

FlatBuffersを導入手順についての記事です。

FlatBufferとは

FlatBuffersとはGoogle社が開発しているクロスプラットフォーム対応のシリアライゼーションライブラリです。主にゲームで使われることを目的として開発されています。Protocol Bufferに似ていますが、大きな違いはバイナリデータをパースせずにシリアライズされたデータを使用するため、高速かつメモリを効率的に使うことができます。

Flatbuffersのインストール

はじめにflatbuffersbrewでインストールします。 brewが使えない場合はBuildingのページを参考にインストールすることができます。

brew install flatbuffers

flatcというコマンドが使えるようになれば準備完了です。

FBSファイルの作成

次にFBSファイルを作成します。FBSファイルとはFlatbuffers用のスキーマ定義ファイルです。これによりバイナリファイルの作成および各言語のparserを生成することができます。

Tutorialを参考にFBSファイルを作成します。

// monster.fbs

// Example IDL file for our monster's schema.
namespace MyGame.Sample;
enum Color:byte { Red = 0, Green, Blue = 2 }
union Equipment { Weapon } // Optionally add more tables.
struct Vec3 {
  x:float;
  y:float;
  z:float;
}
table Monster {
  pos:Vec3; // Struct.
  mana:short = 150;
  hp:short = 100;
  name:string;
  friendly:bool = false (deprecated);
  inventory:[ubyte];  // Vector of scalars.
  color:Color = Blue; // Enum.
  weapons:[Weapon];   // Vector of tables.
  equipped:Equipment; // Union.
  path:[Vec3];        // Vector of structs.
}
table Weapon {
  name:string;
  damage:short;
}
root_type Monster;

バイナリファイルの作成

バイナリファイルはJSONまたはJSON5のフォーマットを使用します。今回はJSON5を使用してバイナリファイルを生成します。

// monsterdata.json5

{
  pos: {
    x: 1,
    y: 2,
    z: 3
  },
  hp: 300,
  name: 'Orc'
}

先程生成したFBSファイルを使用してJSONデータをバイナリファイルに変換します。

flatc -b monster.fbs monsterdata.json5

monsterdata.binが生成されればOKです。

JavaScriptで読み込み

今回はJavaScriptファイルをFBSファイルより自動生成し、実際にNode.jsでバイナリファイルを読み込みます。

flatc --js monster.fbs

monster_generated.jsファイルが生成され、これを使用して実際にバイナリファイルを読み込んでみます。

Nodeの実行環境をTutorialを参考に作成し実行し、ログが出れば成功です。

yarn init -y
yarn add flatbuffers
// example.js

const fs = require('fs');
const path = require('path');
const { flatbuffers } = require('flatbuffers');

const { MyGame } = require('./monster_generated');

const filepath = path.resolve(__dirname, 'monsterdata.bin');
const data = new Uint8Array(fs.readFileSync(filepath));

const buf = new flatbuffers.ByteBuffer(data);
const monster = MyGame.Sample.Monster.getRootAsMonster(buf);
console.log(monster.hp()); // 300
console.log(monster.name()); // Orc
node example.js

まとめ

FlabBuffersの導入をしました。まだベンチマークを計測していないですが、C#クライアントではうまく動いてより良い感じです。またdefault valueを使用することでデータ量を減らすこともできるようなので、ぜひ使っていきたいと思います。

Link