For the past year or so, I have been working on a 3D printed mechanical desk
clock. The clock is completely my own design, which made it quite a learning
experience. (In fact, this is the second design attempt — there’s an earlier
failed design which I will talk about later.) Now that the clock is essentially
complete (though still could use some improvement), I’d like to share.
This post will be a brief overview on the design of the clock and its final
pictures. Later posts in this series will go
into more detail about its inner workings, and finally information on how to
make one for yourself, if you so desire.
Today is a rather unusual day. We will leave behind the comfort of the UNIX
world; the thoughts of the comparatively well-engineered
groovy; the joy of the comparative minimalism of
Enterprise Java
Beans. Today we take
a trip to Redmond to gaze upon the monstrosity that is Microsoft Exchange,
Microsoft’s PIM (email, calendar, and contacts) server.
Now, we’re not going to talk about actually setting up or running Exchange.
This is something I have no experience with and certainly never will; there are
many employment opportunities available that are less depressing and more
fulfilling, such as decapitating rabbits with
scissors
or installing road signals for bicyclists.
Instead, we’re going to be talking about interfacing with third-party Exchange
servers, including “Office 365”.
RxJava, short for “Reactive Java“, the Java implementation of the
“ReactiveX” specification, is sometimes used
to facilitate asynchronous or concurrent programming in Java, particularly in
code from Netflix, its original implementor. It enjoys some popularity in the
realm of server backend programming, and there appears to be surprisingly
little criticism of it.
“ReactiveX” is an extension of the observer
pattern and perhaps works well
in realms where that pattern is actually used, such as GUIs. But nobody in
their right mind writes GUIs in Java anymore outside a single mobile platform.
RxJava is instead purported to instead be a solution to asynchronous tasks on
the server, something for which the observer model is an extremely poor fit.
RxJava appears to draw people in on the basis of pretty diagrams that make it
look easy to work with and vacuous conceptions of universality. In reality,
outside of a very, very narrow space where it fits well, it brings far more
harm than good.
A bounding box generally refers to an axis-aligned rectangular region of
space used as a first, coarse step of collision detection. Every object is
given a bounding box which covers all space the object could possibly occupy.
If the bounding boxes of two objects overlap, the simulation needs to do a more
precise but expensive collision check; but if they do not overlap, they
certainly do not collide and the pair can be skipped.
Since Hexeline uses an oblique coordinate
system, the same approach results in
bounding rhombi instead of boxes, though that distinction is not particularly
interesting here. What is interesting is how bounding boxes/rhombi can be
handled extremely efficiently with SIMD. I fully expect that this technique has
been discovered by someone else previously, but it’s still worth discussing.
One of the central design principles in my still extremely early space shooter
Hexeline (read: has neither space nor shooting) is that spacecraft will be
defined in terms of a hexagonal grid, rather than cells of varying shape, which
simplifies things for both the software and the player while still allowing
more interesting shapes than a square grid.
A useful property of regular grids is that they are directly addressable;
i.e., you can put the elements of an array and immediately access an element
just by knowing its coordinate. Ideally, it’s also efficient to go from
continuous spatial coordinates to a grid coordinate. This is trivial in a
square grid: depending on how you define your coordinates, you can usually just
divide spatial coordinates by the cell size to get the coordinate of the cell a
point falls within.
In effort to get a similar property for hexagonal grids, I’ve taken the unusual
step of basing a Newtonian physics engine on non-cartesian coordinates. It
turns out this is not as bad as it sounds, and quite a few useful properties
fall out of it.
Note: This post is going to be comparatively math-heavy and assumes some
familiarity with linear algebra.
My first few years of university, I spent a lot of time working on a 2D space
shooter called Abendstern. It ultimately didn’t end up going much of
anywhere, and not for lack of it functioning well as a game. In the hopes of
being able to try this again, I look back on why Abendstern ultimately failed.
Encapsulation, in one form or another, is nearly universal in large-scale
programming across languages. Isolating the code which can access certain state
or data makes it easier to maintain and easier to reason about what impact
changes to that state could have. In object-oriented languages, the unit of
encapsulation is the class, and encapsulation is accomplished by making
instance variables private and exposing a set of well-defined operations on
that state in the public API.
JavaBean properties (a.k.a. “bean properties” or simply “getters and setters”)
arose when the point about making instance variables private was applied
universally without paying attention to the “well-defined operations” point.
Bean properties, particularly within an internal code-base or narrowly deployed
library, are nothing more than inconvenient public variables.
In the two decades of its existence, the Java programming language has gone
through quite a few changes. Even more so, however, have the overall approaches
to design and architecture in the Java ecosystem. I have found that these can
by and large be separated into four generations which typically cut over
relatively abruptly, immediately giving large code-bases of prior generations
an archaic and poorly-designed feel.
Mundane Java has two types of character-type literals: character literals,
enclosed in single-quotes, and string literals, enclosed in double-quotes.
1/* Character literal, enclosed in single-quotes */
2char ch = 'c';
3/* String literal, enclosed in double-quotes */
4String s = "This is a string.";
One of the first things not backwards-compatible with Java that a new Groovy
user may notice is that single-quotes now delimit strings as well.
Suppose that we have a stateless but computationally-intensive piece of code
involving a lot of function calls, which is for some reason written in Groovy.
SlowFib.groovy
1package gl.lin
2
3class SlowFib {
4 static int fib(int n) {
5 n <= 1? n : fib(n-1) + fib(n-2)
6 }
7}
Obviously, the algorithm here is pretty much the worst one possible — it has
exponential run-time, but calculating the Fibonacci sequence can be calculated
in linear time. But imagine for the time being that this is real code. The
important thing is that this code makes lots of function calls. Also
important is how the function is stateless — it accesses no data outside of
its locals, and is non-virtual due to its static
ness (ie, it could be called
with one instruction were this native code).
Now say we want to write a program that maps a sequence of input integers to
the corresponding Fibonacci number. A simple single-threaded implementation is
below.