It is the year 2020: why should I use / learn D?

H. S. Teoh hsteoh at quickfur.ath.cx
Sat Nov 24 02:45:46 UTC 2018


On Sat, Nov 24, 2018 at 01:38:07AM +0000, Laeeth Isharc via Digitalmars-d wrote:
> On Saturday, 24 November 2018 at 00:11:37 UTC, H. S. Teoh wrote:
> > On Fri, Nov 23, 2018 at 03:56:31PM -0800, Walter Bright via
> > Digitalmars-d wrote:
> > > On 11/23/2018 4:59 AM, Chris wrote:
> > > > Then there was the whole issue of ARM. Walter said he had no
> > > > experience with it and kinda didn't care either,
> > > 
> > > Actually, a person in the D community was working for a couple
> > > years on an ARM back end, but he eventually lost interest and it
> > > was abandoned.
> > 
> > LDC is already well able to target ARM -- I've been using it to
> > write Android apps, and while it takes a bit of work to set up, once
> > it's setup it works very well.
> 
> Care to say a bit more about what you are using it for?  Do you write
> the gui in D too? Using jni or dlangui if so?

Right now, it's still an experimental project to test out the waters...
Things are looking good and it might turn into a "real" project soon,
but as of now, it's still experimental.

Basically I have the Java code handle interacting with Android OS (it's
possible to do this via NDK but too troublesome and not necessary at the
moment), basically just a thin wrapper to forward most of the logic to
the D code via JNI. There's an error popup screen purely written in
Java, but it's more a development tool for displaying uncaught D
exceptions than an actual end-user UI.

The bulk of the code is in D, and renders geometric models via OpenGL
ES.  At some point there will be text, and menus, and other UI elements,
but right now, just some animated geometric shapes.  It communicates
with the Java code via JNI.  Presently, the GL context creation is still
handled by the Java code (haven't found a pressing need to manually do
it yet, so why not leverage what the Android Java API already provides).

The geometric models are converted by a D utility running on the host
system (i.e., not on Android) that converts a bunch of models I have
handy into the required format for OpenGL as a bunch of D arrays that I
just embed into the executable.

There's also a bunch of GLSL shaders that are stripped and turned into D
string literals and embedded into the executable as well -- no need to
load resource files at runtime. (This may or may not change as the
project gets bigger, though.)  This is also done by a build-time D
utility, which also auto-generates nice D interfaces for binding shader
inputs.  So instead of manually writing a bunch of glUniformxxx calls
(with the associated high risk of typos that causes crashes at runtime),
I can just write:

	useProgram(...);
	myshader.worldmatrix = FMatrix(...);
	myshader.worldposition = FVec(1, 2, 3, 1);
	...
	glDrawArrays(...);

and it automatically issues the correct glUniformxxx calls for me.

Currently vertex attribute bindings still have to be done manually, but
with just a little more infrastructure in place, and I could
auto-generate those too.  Then I wouldn't have to worry about those
crash-prone fiddly details that the OpenGL API requires ever again.

The D code obtains the app-specific data directory from the Java code
via JNI, and handles its own saving/restoring of UI state via a
home-made made (somewhat hamfisted) serializer.  Eventually it will
probably be replaced by a real serialization system / library, but right
now, it's still in the initial experimental stage so just a crude
homebrew system. But the point is that the D code is well able to handle
Android app lifetime events.

One interesting aspect of this project is that I designed the D code to
be mostly independent of the Android API -- the API is still more or
less structured according to an Android app's lifetime callbacks, but is
agnostic to the actual implementation.  The OpenGL code being also a
subset of desktop OpenGL APIs, I was able to write an X11 driver that
runs the same D backend (without any version blocks!), except on the PC
instead of an Android device.  This has been very useful for ironing out
silly mistakes by allowing development as a local PC program before
deploying to the actual Android device. I suppose I *could* use the
Android simulator for this, but it's slow, needlessly resource-hungry,
and far too klunky to use for fast development. Plus, it opens up the
possibility of deploying this program on PCs too, in addition to
Android.

D's malleability really helped to pull this off -- by templating away
Android-specific types that can be substituted by PC-specific types /
wrappers, I can pretty much just reuse the code as-is without the major
refactoring into a labyrinth of interfaces and other boilerplate that
would have been required in Java to abstract away OS-specific
components.  Like I've already said, I haven't gotten to the point of
autogenerating JNI interfaces to be directly callable from D, but if the
code turns out to need to cross the JNI boundary much more, that's what
I'll do.

I also setup my build system (a custom one based on SCons -- Gradle is
far too heavyweight for my tastes) to compile and run unittests on the
local PC, which will abort if any unittests fail.  So the same source
files are compiled twice -- once with -unittest targeting x86_64 (using
dmd, no less! :-P), and once without -unittest targeting ARM (using LDC
cross-compiler). If the build succeeds at all, I know that all unittests
pass, and the APK can be deployed to the device to be further tested
there.

The entire build takes about 10-11 seconds to build everything from a
clean workspace (includes generating model data, generating shader D
APIs, compiling and running unittests, compiling X11 executables,
compiling Java code, cross-compiling D code, and building and signing an
APK), and about 5-6 seconds on incremental builds, depending on what was
changed.  Not as fast as Atila would like, ;-) but reasonably fast and
with absolutely minimal system requirements -- I literally did all this
with just a text editor, SCons, and SSH. Didn't even fire up Android
Studio once.


tl;dr: Thanks to Joakim's efforts and the LDC team, it is quite possible
to write Android apps in D today. This project of mine still has a Java
component to it, but I'd wager that doing a completely native app with
the NDK would work just as well (Joakim's github repo has simple
examples of this).  I won't lie, though -- setting up LDC to
cross-compile to Android/ARM does require some effort.  But it's not
unduly hard, only has to be done once, and your build system takes care
of it thereafter (assuming you use a reasonable build system, that is).


T

-- 
People walk. Computers run.


More information about the Digitalmars-d mailing list