Welcome to LibDiceRoller!
This project has two purposes:
- make a handy cross platform dice rolling library that safely and quickly runs on iOS, Android, the Web (Typescript / JavaScript), Linux, MacOS, and Windows
- explore interesting design and communication patterns for portable software architectures
- iOS
- Android
- Web
- Linux
- MacOS
- Windows
This project consists of the following components:
- a rust library that can be conditionally compiled to support the C FFI (foreign function interface), JNI (java native interface). Webassembly support for running on the web is currently in progress.
- platform adapters that allow the rust library to easily run on target platforms. For iOS and Android, this means small projects that wrap LibDiceRoller into a Xcode framework and Android library, respectively.
- a serialized data communication layer between the rust library and the platform adapters. It's currently using protobufs!
All communication between the rust layer and the platform adapters (e.g. iOS, Android, etc) is handled by passing serialized data as protobufs. I chose a serialized data format because it's quite tedious to have to create a new FFI or JNI or other future platform data mapping whenever my data format needs to change - let alone keep them all in sync and up to date! With a serialized data format, I could encode/decode a data model through the same interface (or port/adapter if you're a hexagonal architecture fan) and still have the flexibility to easily change it without needing to update the communication layer directly.
After considering which serialized data formats would work well across multiple platforms, it came down to a decision between JSON, protobufs, or flatbuffers. JSON would be the easiest to implement because JSON support is ubiquitous across every modern target. However, it would also arguably be the most unsafe option for the long term because I'd have no way of knowing at compile time if I was parsing the current format of a given data model.
I experimented with using flatbuffers, and although they did work, swift support was still unstable in the current release as of early September 2020. After trying out protobufs, I was pleasantly surprised to see that they just worked on iOS and Android.
You will need the following:
- MacOS Catalina
- Homebrew
- Xcode 11.7
- Android Studio 4.0.1
Build
make build-ios
Test
make test-ios
Clean
make clean-ios
The Android NDK will need to be installed and setup in order to build LibDiceRoller. You can do set it up with Android Studio, or by downloading it from the Google Android Developer site.
You will also need to let Rust know about it as follows:
- edit the file common/lib-dice-roller/cargo-config.toml and update the NDK paths to match its path on your system.
- put a copy of cargo-config.toml in a place where cargo can read it:
mkdir -p common/lib-dice-roller/.cargo && cp common/lib-dice-roller/cargo-config.toml common/lib-dice-roller/.cargo/config.toml
Feel free to take a look at the Android pipeline if you get stuck or just want to see a working example of how to set it up: .github/workflows/android-pipeline.yml
Build
make build-android
Test
make test-android
Clean
make clean-android
Please share any thoughts, ideas, or suggestions that you have.
MIT License Copyright (c) 2020 Walter Scarborough