Start to support all languages in tutorial

This commit is contained in:
Derek Bailey
2025-01-10 15:10:20 -08:00
parent 34f0728ea2
commit 2cffba28b4
3 changed files with 348 additions and 1 deletions

View File

@@ -108,6 +108,14 @@ markdown_extensions:
slugify: !!python/object/apply:pymdownx.slugs.slugify
kwds:
case: lower
- pymdownx.highlight:
extend_pygments_lang:
# PHP wasn't highlighting correctly. This is a work around found
# https://github.com/squidfunk/mkdocs-material/issues/138#issuecomment-2294025627
- name: php
lang: php
options:
startinline: true
- tables
@@ -131,6 +139,7 @@ nav:
- Go: "languages/go.md"
- Java: "languages/java.md"
- JavasScript: "languages/javascript.md"
- Kotlin: "languages/kotlin.md"
- Lobster: "languages/lobster.md"
- Lua: "languages/lua.md"
- PHP: "languages/php.md"

View File

@@ -0,0 +1,84 @@
Use in Kotlin {#flatbuffers_guide_use_kotlin}
==============
## Before you get started
Before diving into the FlatBuffers usage in Kotlin, it should be noted that
the [Tutorial](../tutorial.md) page has a complete guide to
general FlatBuffers usage in all of the supported languages (including K).
This page is designed to cover the nuances of FlatBuffers usage, specific to Kotlin.
You should also have read the [Building](../building.md)
documentation to build `flatc` and should be familiar with
[Using the schema compiler](../flatc.md) and
[Writing a schema](../schema.md).
## Kotlin and FlatBuffers Java code location
Code generated for Kotlin currently uses the flatbuffers java runtime library. That means that Kotlin generated code can only have Java virtual machine as target architecture (which includes Android). Kotlin Native and Kotlin.js are currently not supported.
The code for the FlatBuffers Java library can be found at
`flatbuffers/java/com/google/flatbuffers`. You can browse the library on the
[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/
java/com/google/flatbuffers).
## Testing FlatBuffers Kotlin
The test code for Java is located in [KotlinTest.java](https://github.com/google
/flatbuffers/blob/master/tests/KotlinTest.kt).
To run the tests, use [KotlinTest.sh](https://github.com/google/
flatbuffers/blob/master/tests/KotlinTest.sh) shell script.
*Note: These scripts require that [Kotlin](https://kotlinlang.org/) is installed.*
## Using the FlatBuffers Kotlin library
*Note: See [Tutorial](../tutorial.md) for a more in-depth
example of how to use FlatBuffers in Kotlin.*
FlatBuffers supports reading and writing binary FlatBuffers in Kotlin.
To use FlatBuffers in your own code, first generate Java classes from your
schema with the `--kotlin` option to `flatc`.
Then you can include both FlatBuffers and the generated code to read
or write a FlatBuffer.
For example, here is how you would read a FlatBuffer binary file in Kotlin:
First, import the library and generated code. Then, you read a FlatBuffer binary
file into a `ByteArray`. You then turn the `ByteArray` into a `ByteBuffer`, which you
pass to the `getRootAsMyRootType` function:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.kt}
import MyGame.Example.*
import com.google.flatbuffers.FlatBufferBuilder
// This snippet ignores exceptions for brevity.
val data = RandomAccessFile(File("monsterdata_test.mon"), "r").use {
val temp = ByteArray(it.length().toInt())
it.readFully(temp)
temp
}
val bb = ByteBuffer.wrap(data)
val monster = Monster.getRootAsMonster(bb)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Now you can access the data from the `Monster monster`:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.kt}
val hp = monster.hp
val pos = monster.pos!!;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
## Differences between Kotlin and Java code
Kotlin generated code was designed to be as close as possible to the java counterpart, as for now, we only support kotlin on java virtual machine. So the differences in implementation and usage are basically the ones introduced by the Kotlin language itself. You can find more in-depth information [here](https://kotlinlang.org/docs/reference/comparison-to-java.html).
The most obvious ones are:
* Fields as accessed as Kotlin [properties](https://kotlinlang.org/docs/reference/properties.html)
* Static methods are accessed in [companion object](https://kotlinlang.org/docs/reference/classes.html#companion-objects)

View File

@@ -35,7 +35,7 @@ data structures, see the [schema](schema.md) documentation for a detail
description. Use the inline code annotations to get a brief synopsis of each
part of the schema.
```c title="monster.fbs" linenums="1"
```proto title="monster.fbs" linenums="1"
// Example IDL file for our monster's schema.
namespace MyGame.Sample; //(1)!
@@ -163,12 +163,103 @@ serializing and deserializing the flatbuffer binary data.
flatc --cpp monster.fbs
```
=== "C"
!!! Note
If you're working in C, you need to use the separate project
[FlatCC](https://github.com/dvidelabs/flatcc) which contains a schema
compiler and runtime library in C for C. See
[flatcc build instructions](https://github.com/dvidelabs/flatcc#building).
Please be aware of the difference between `flatc` and `flatcc` tools.
```sh
cd flatcc
mkdir -p build/tmp/samples/monster
bin/flatcc -a -o build/tmp/samples/monster samples/monster/monster.fbs
# or just
flatcc/samples/monster/build.sh
```
=== "C#"
```sh
flatc --csharp monster.fbs
```
=== "Dart"
```sh
flatc --dart monster.fbs
```
=== "Go"
```sh
flatc --go monster.fbs
```
=== "Java"
```sh
flatc --java monster.fbs
```
=== "JavaScript"
```sh
flatc --js monster.fbs
```
=== "Kotlin"
```sh
flatc --kotlin monster.fbs
```
=== "Lobster"
```sh
flatc --lobster monster.fbs
```
=== "Lua"
```sh
flatc --lua monster.fbs
```
=== "PHP"
```sh
flatc --php monster.fbs
```
=== "Python"
```sh
flatc --python monster.fbs
```
=== "Rust"
```sh
flatc --rust monster.fbs
```
=== "Swift"
```sh
flatc --swift monster.fbs
```
=== "TypeScript"
```sh
flatc --ts monster.fbs
```
You can deserialize flatbuffers in languages that differ from the language that
serialized it. For purpose of this tutorial, we assume one language is used for
both serializing and deserializing.
@@ -192,6 +283,19 @@ generally involves two things:
using namespace MyGame::Sample; // Specified in the schema.
```
=== "C"
```c
#include "monster_builder.h" // Generated by `flatcc`.
// Convenient namespace macro to manage long namespace prefix.
#undef ns
#define ns(x) FLATBUFFERS_WRAP_NAMESPACE(MyGame_Sample, x) // Specified in the schema.
// A helper to simplify creating vectors from C-arrays.
#define c_vec_len(V) (sizeof(V)/sizeof((V)[0]))
```
=== "C#"
```c#
@@ -199,6 +303,156 @@ generally involves two things:
using MyGame.Sample; // The generated files from `flatc`
```
=== "Dart"
```dart
import 'package:flat_buffers/flat_buffers.dart' as fb;
// Generated by `flatc`.
import 'monster_my_game.sample_generated.dart' as myGame;
```
=== "Go"
```go
import (
flatbuffers "github.com/google/flatbuffers/go"
sample "MyGame/Sample"
)
```
=== "Java"
```java
import MyGame.Sample.*; //The `flatc` generated files. (Monster, Vec3, etc.)
import com.google.flatbuffers.FlatBufferBuilder;
```
=== "JavaScript"
```javascript
// The following code is an example - use your desired module flavor by
// transpiling from TS.
var flatbuffers = require('/js/flatbuffers').flatbuffers;
var MyGame = require('./monster_generated').MyGame; // Generated by `flatc`.
//--------------------------------------------------------------------------//
// The following code is for browser-based HTML/JavaScript. Use the above code
// for JavaScript module loaders (e.g. Node.js).
<script src="../js/flatbuffers.js"></script>
<script src="monster_generated.js"></script> // Generated by `flatc`.
```
=== "Kotlin"
```kotlin
import MyGame.Sample.* //The `flatc` generated files. (Monster, Vec3, etc.)
import com.google.flatbuffers.FlatBufferBuilder
```
=== "Lobster"
```lobster
import from "../lobster/" // Where to find flatbuffers.lobster
import monster_generated
```
=== "Lua"
```lua
-- require the flatbuffers module
local flatbuffers = require("flatbuffers")
-- require the generated files from `flatc`.
local color = require("MyGame.Sample.Color")
local equipment = require("MyGame.Sample.Equipment")
local monster = require("MyGame.Sample.Monster")
local vec3 = require("MyGame.Sample.Vec3")
local weapon = require("MyGame.Sample.Weapon")
```
=== "PHP"
```php
// It is recommended that your use PSR autoload when using FlatBuffers in PHP.
// Here is an example from `SampleBinary.php`:
function __autoload($class_name) {
// The last segment of the class name matches the file name.
$class = substr($class_name, strrpos($class_name, "\\") + 1);
// `flatbuffers` root.
$root_dir = join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__))));
// Contains the `*.php` files for the FlatBuffers library and the `flatc`
// generated files.
$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;
}
}
}
```
=== "Python"
```py
import flatbuffers
# Generated by `flatc`.
import MyGame.Sample.Color
import MyGame.Sample.Equipment
import MyGame.Sample.Monster
import MyGame.Sample.Vec3
import MyGame.Sample.Weapon
```
=== "Rust"
```rust
// import the flatbuffers runtime library
extern crate flatbuffers;
// import the generated code
#[allow(dead_code, unused_imports)]
#[path = "./monster_generated.rs"]
mod monster_generated;
pub use monster_generated::my_game::sample::{root_as_monster,
Color, Equipment,
Monster, MonsterArgs,
Vec3,
Weapon, WeaponArgs};
```
=== "Swift"
```swift
/**
// make sure that monster_generated.swift is included in your project
*/
import Flatbuffers
// typealiases for convenience
typealias Monster = MyGame1_Sample_Monster
typealias Weapon = MyGame1_Sample_Weapon
typealias Color = MyGame1_Sample_Color
typealias Vec3 = MyGame1_Sample_Vec3
```
=== "TypeScript"
```ts
// note: import flatbuffers with your desired import method
import { MyGame } from './monster_generated';
```
For some languages the runtime libraries are just code files you compile into
your application. While other languages provide packaged libraries via their
package managers.