Hi Tcl friends,
I'd like to share some work I've been doing this week with you, the
early stages of what it'll take to make Tcl more useful in the Android
ecosystem.
TL;DR - I've been working on getting the bits in place to embed
native-compiled Tcl into Android .apk files and be able to access the
assets/ folder via a Tclvfs layer....so, embedding a Tcl interp in an
Android program has now become a lot more useful.
The background
==============
Android is a popular smartphone operating system. It's Linux-based, but
the apps that people install from app marketplaces and interact with are
mostly written in Java or html/JS. Since it's Linux-based, we've been
able to run Tcl scripts for a while now, from an Android terminal window
using a cross-compiled tclsh or tclkit. Many thanks to Roy Keene for his
work on kitcreator to make that possible.
What hasn't been as easy, up to now, is packaging and using Tcl within
an Android package file (.apk).
The first part of the solution
==============================
The Java runtime provides a way to load native-compiled code into the
Java VM, the Java Native Interface (JNI). Using JNI, we'd theoretically
be able to use one of Roy Keene's Tclkit dlls to bring a native Tcl
interp into our Java program. It took a little extra patching, and
writing the appropriate Android.mk file for the native-code build
system, but it's now possible to load one of Roy's libtclkit dlls into
the Java VM in via JNI.
It helps to be familiar with the Android native-code build system, but
adding Tcl to an Android app is now as simple as:
* downloading the libtclkit .tgz,
* unpacking it into your jni/ directory,
* and loading the Tcl library into your Java program with the
_System.load("tclkit860")_ command.
URL for the ARM libtclkit:
http://www.rkeene.org/devel/kitcreator/kitbuild/nightly/libtclkit-8.6.0-android-arm-notk-kitdll-xcompile-sdk.tar.gz
Your other native code libraries can now create Tcl interpreters, run
them, and do all the things we normally enjoy doing with Tcl. Just
loading a Tcl interpreter into a Java VM isn't entirely useful, however,
because we can't yet access any data we might've bundled into the .apk,
our interpreter can't load any other scripts within the .apk, and so on.
Here's where Tclvfs can prove useful...
The second part of the solution
===============================
In order to gain access to the assets/ folder of the .apk file, you'd
ordinarily use the AssetManager class. Since we're now trying to run
scripts in the native-code Tcl interpreter, it might seem cumbersome to
make calls back to Java to get ahold of the data in assets/. To simplify
that, I've started to write a Tclvfs package to take care of that
interface, vfs::AssetManager.
vfs::AssetManager makes it possible to treat the .apk's assets/ folder
as any other vfs, which means, it's now possible to store scripts or
entire programs in an .apk file, and access them using the regular Tcl
filesystem access commands.
The fossil for vfs::AssetManager is on my site at:
http://stevehavelka.com/cgi-bin/vfsAssetManager
This code is still a work-in-progress, and is probably still pretty
buggy, but I've been able to run some tests and make working .apk files
based on it. All feedback, patches, etc., are welcome.
Putting these parts together
============================
By including the native-code Tcl interp and vfs::AssetManager in an
.apk, it's now possible to store scripts, data, etc., in an Android .apk
file, in the assets/ folder, and run them just as you would any ordinary
Tcl program.
My goal with all this, up to now, has been to put together a rapid
build/deployment environment for video game work: writing the game
logic in Tcl, bundling the code with my game engine, and publishing to
the app marketplaces. I've put together a simple test program, which I'd
like to invite you to try, if you're curious:
http://stevehavelka.com/test/dl/Plasmatcl.apk
If you unpack this .apk, and look in the assets/ folder, you can see
that the code that drives the plasma effect is just a handful of lines
of Tcl--really simple stuff.
Conclusion
==========
In the next few days/weeks I'm planning to write up a series of blog
posts to explain all this in more detail. I wanted to put the first (and
most useful) bits of code out there early on, in case anyone else wants
to start playing with embedding Tcl in app-store-ready Android programs.
enjoy,
Steve