With the Dice Services migration complete and the Services/Crucible API protocol working nicely, it’s time to get back to work on the wargame desktop application, named Table (short for Game Table).

Without going into a technical rant that I’ve been bothering my close friends and family with for the past 3-4 days, I hit a roadblock with the current prototype. The current prototype was based on JRubyFX; it was a Ruby language implementation that was using the JRuby interpreter with Java’s JavaFX GUI (Graphical User Interface) library.  Using this set of technologies, I was able to make some progress.

Demo Video: https://www.youtube.com/watch?v=QXSgEffytaI&t=18s

In spite of the progress, the inefficiencies with this approach were getting more difficult to overcome the deeper into the project I got.  The biggest problem was learning how to use the JavaFX library.  As it is a Java technology, all the documentation was in Java.  That’s fine; I can read Java.  The ultimate problem was two-fold:

  • The JRuby implementation of JavaFX didn’t look like the documentation
    • Names were changed and the translations didn’t seem consistent
  • There were very few helpful JRubyFX examples on the Internet; I was on my own

Anytime I was implementing a new methodology, such as adding a dialog window to query the user for a username / password combination, I was taking hours just trying to figure out the appropriate code to write.

I needed an alternative.

Without going into detail, and delving into rant territory, after trying a few approaches and scouring the Internet over the past couple of weeks, I’ve decided to write what the entire software industry has failed to write in the past 22 years: a usable cross-platform GUI library that doesn’t suck.

Epoxy will be an XGUI binding layer between Ruby desktop applications and underlying native GUI controls.  It will automatically detect which OS platform you’re running on (macOS, Windows, some Linux variant) and bind itself to the underlying platform-specific libraries by dynamically creating the Binding at runtime through the use of a BindingAgent.

I’m not in new territory here.  There is a Ruby gem called RubyCocoa that bound itself to the macOS CoreFoundation and AppKit framework libraries and I’m using it for smoke and sanity testing.  However, RubyCocoa hasn’t been updated in four years and I’ve already had to write a small patch fix for it to make it run without Ruby interpreter warnings.  It is also not quite Ruby-like.  Its syntax and naming convention is great if you’re an Objective-C / Cocoa framework person trying to transition to Ruby.  But I’m not.  I want a Ruby-esque library with Ruby-esque naming conventions that hides the underlying implementation details.  I want Epoxy::Application.run to work, not Cocoa::NSApplication.run_shared.  The differences may seem trivial, but they’re not.

The good news, so far, is that this approach seems to be working.  I’ve built a mutable Epoxy class which can detect the underlying platform (macOS) and dynamically load the RubyCocoa binding into its namespace.  The next bit is to begin the process of replacing RubyCocoa’s Cocoa namespace with the Epoxy::Binding namespace.