Development flow for Mentat FFI
Android SDK
Android Mentat SDK is one of two first-party consumers (the other one being iOS Mentat SDK).
Binaries produced by cargo build ... are symlinked from within the SDK, and a number of target-specific libmentat_ffi.so binaries are bundled together and distributed with the SDK.
There is a build script at <mentat_root>/scripts/android_build.sh which knows how to cross-compile mentat_ffi for various Android targets.
./<mentat_root>/scripts/android_build.sh- compiles for all supported targets./<mentat_root>/scripts/android_build.sh x86- compiles forx86./<mentat_root>/scripts/android_build.sh x86 arm- compiles forx86,arm
General development flow while working on the Android SDK is:
- (pre) compile for all targets, if you’ve never done so
- make changes to mentat_ffi and/or mentat
- re-compile mentat_ffi binaries using ./android_build.sh x86. During development it’s faster to compile just for the target which matches your emulator, e.g. x86
- make corresponding changes in the Android SDK, try them out from within the bundled sample project
- since binaries are symlinked, no manual copy step is necessary for the Android SDK to pick up the changes
iOS SDK
TODO, contribute via issue #732.
Panics and threads
No panic unwinds into C. Most extern "C" functions catch panics: a panic
is reported through the ExternError out parameter where the function has
one (the message starts with mentat panicked:), and the function returns
a null pointer, 0, 0.0 or nothing.
The getters that return a plain number and have no ExternError abort the
process on a panic, as before: 0 is a valid long, boolean, double, timestamp
and entid, so returning it would hide the error (a misspelled attribute name
would quietly become entid 0). They are
typed_value_into_{long,entid,boolean,double,timestamp},
value_at_index_into_{long,entid,boolean,double,timestamp},
store_entid_for_attribute (panics on an attribute not in the schema),
tx_report_get_entid, tx_report_get_tx_instant, changelist_entry_at and
typed_value_value_type. Check the value type, the index or the attribute
before calling them.
A Store handle, and every handle made from it (InProgress, the builders,
QueryBuilder, result sets, iterators), must not be used from two threads at
once. The SQLite connection and the store’s caches are not synchronised. If
threads share a store, serialise every call on it with your own lock, or open
one Store per thread on the same file. Transaction observer callbacks run on
a thread owned by Mentat and must not call back into the same Store.