Graph3d Library Design Overview

Graph3d consists of a Java and a native code part. Each of those two is itself split into several layers: the Java graph3d package is the topmost, API-user-visible frame, which wraps and hides all intrinsics.

As it should always be true in the author's opinion for a library design, the major goal was to make the graph3d package consistent and easy-to-use from the API user's point of view. This means: there should be as less as possible ways to abuse the API and cause runtime errors or JVM crashes, of course. A Java package user expects never to be confronted with crashes - every exceptional condition must be signaled by exception objects. This means: the library interface must be foolproof enough to forbid 'dangerous' abuse.

How can this be achieved? It's not that hard.

The graph3d package tries to fulfill these rules. The interface provides just the viewport class graph3d.GraphView, and the Function interfaces for immediate interaction with the renderer. The remaining classes serve as interface to the built-in stack-based interpreter.

The keep-it-simple-rule implies as a consequence, that it would be wise to do as much as possible on the Java side, where everything is supervised by the JVM security mechanisms, and do performance-critical stuff only in native code. graph3d tries to fit this rule by implementing a peer layer on the Java side, which contains API-user invisible Java code, that, for instance, takes care of library entry point threadsafeness by providing an all-synchronized library context singleton, and a set of wrapper classes, which take care of native instance reference caching. The issue of AWT lock restriction to the accessability of java.awt.Canvas handles and it's boundness to the AWT event queue is handled here as well - the wrapper classes take care of canvas handle passing to library entry points, where required, and queues each invokation of AWT critical sections into the event thread.

Overview Of The Library Design

The native code part of graph3d first of all consists of the 'legacy' libraries, libgraph.so and librt_stack.so, which provide graph3d's functionality. These two don't know anything of Java, and are considered to be black boxes.

To achieve the Java binding, the Graph3d class is subclassed and extended by a GLXContext and knowledge of required context switches - each method which modifies the GL state, set's the GLXContext of it's instance in the derived class, before it passes the call to the parent class' implementation of itself.

The next-outward layer is the wrapper code, which contains the JNI method definitions, and facilities to deal with and ease AWT locking. The strategy choosen here is, to raise Java exceptions for each JAWT lock error to the calling code, indicating library 'abuse' here.