[moon] home

Erlkönig: Z (ζωιον) - zme

A view of the program zme
[parent webpage]

[webserver base]

[search erlkonig webpages]

[import certificates]


Recent News

There is a big rewrite in progress right now in order to allow several key things:

  • Support for ZEvent-based input into texture-mapped shmem X servers.
  • Port caching of Zobjects, ZTextures, GL display list and texture ids.
  • ZEvent queue pending notification by pthread_cond_signal or poll/fd.

These are implemented:

  • Support for ZEvents for all interactions with Zones.
  • Zone caching of Zys IDs and the corresponding Zys addresses.
  • Derivation of Agent, Zone, and Net from the base ZEventee class.
  • Refactoring of multiconnection management as a component of ZCommNode.

X Support under the Z Project

[X server in an OpenGL texture]

In this picture, an X server (Xvdtex) has been mapped onto a square, which is the current (yellow-highlighted) manipulated object. Note (difficult in this still image) that the swissclock app and xclock are fully active and updated in this mapped texture. A test grid, enclosing sky, simple landscape, and the ubiquitous sheep are also visible.


  • The current work-pending stack is (top of stack first):
    1. Make new/delete's [de]allocators threadsafe, if not.
    2. Make class ZCommNode::Connection destructors threadsafe.
    3. Rework ZCommNode to allow linked input -and- output nodes.
    4. Finish class ZAgentSpaceball as input for ZAgentPort.
    5. Recast the old Port class into the ZAgentPort paradigm.
    6. Reinstate rendering using ZAgentPort and a Zone.
  • The idea of implementing devices as ZEvent-based communication nodes (class ZCommNode) looks promising, but is requiring rework to directly support non-leaf nodes.
  • In particular, the destructors for the multiply communication-linked nodes aren't yet accounting for thread issues.
  • This rework should simplify the later building of the Net class, the planned proxy to allow access between nodes in different programs or on different hosts.
  • A prototype regression test for ZCommNode has been written, which is highlighting nicely the evil events when the destructors all go off at the end of main().
  • The ZEvent class hierarchy has had some dead code removed, mostly conveniece constructors.


  • Work has started on the ZAgentPort class, to replace the Port class from the prior, Zone-less paradigm.
  • Device support, including X and spaceball input, will probably be implemented with a thread each, converting XEvents and SpaceballEvents to ZEvents and then simply queuing them into the ZAgentPort ZEvent handlers.


  • More of the ZEvents have been implemented on the Zone side of the connections. No access rights as of yet.
  • I've implemented an n-tree container template class with node ID's (allowing access without pointers), a cache for ID/node-address translation, iterators, and a regression test module.
  • The Zone class now uses Ntree<Zys> container for the Zys hierarchy.
  • Various other modules are still going through integration.
  • In C++, a local function can be declared inside of a static struct { function-definition } local; and then accessed via local.function(args) from the containing function and so on as usual. Could someone please explain to me why straightforward local functions, as gcc has supported for years, are illegal in C++? - I'm repeatedly faced with the likelihood that this language is just a sad, painful joke upon computer science.


  • Initial benchmarking of the ZEventZonePing{,Reply} zevents shows a round trip time of ~0.0020 seconds between ZAgentTest and Zone threads. It's expected that the majority of this time is actually overhead from the stderr diagnostic output.
  • ZCommNode currently contains multiconnection handling, with child class ZCommTask managing the threadMain creation and a ZEvent-driven main loop. ZAgent is now derived from ZCommTask (as is Zone), and spawns two threads upon instantiation.
  • End code is expected to derive from ZAgent, keep its state in added, customized class variables, and drive itself by overriding the many ZEvent virtual methods.


  • Refactoring of the Zone and Agent classes has produced a new class between them and the parent ZEventee class which collects the multiconnection handling together, and may also acquire the main loop functionality seen in the spawned threads of Zones and Agents, advancing the two towards perhaps being distinguished by thread task and ZEvent method overrides alone.
  • ZEvents have been passed successfully between Zone and Agent using the model with one { thread and zevent queue } per ZEventee.


  • The Zone, Agent, and Net classes, all of which are targets for ZEvents, are now expected to be derived from the base class ZEventee, providing the ability to overload methods for each of the ZEvent types. The ZEventee class provides automatic management of the mutexes and sundry connected to the ZEvent input queue, and an alternate mechanism for using poll(2) or select(2) with a file descriptor to receive notification of queue events is also expected.
  • The ZEventee, as coded, has a mutual interaction with ZEvent class heirarchy to allow ZEventee methods to be overloaded based on the polymorphic ZEvent type despite all ZEvents being passed around by as (ZEvent *). Basically, the ZEventee calls its zevent.apply(*this), which in the ZEvent_whatever calls zeventee.process(*this), thereby providing a full type to the ZEventee on which to overload.
    How this is supposed to be better than having a switch in each ZEventee derivation was initially a mystery, since the switch wouldn't require such supreme convolutions to allow two classes to refer to each other's methods (rather than just to the other class type, which is trivial) and it could be argued that the vtbl is basically just a switch anyway. However, since the ZEvent heirarchy isn't flat, but actually a tree of event types, it's possible that the virtual methods will allow a finer grained set of fallbacks in the face of new or ignored event types than the rather crude `default:' clause of a switch.
  • The three identified subclasses of ZEventee are seen as having the following roles:
    Maintains the Zys hierarchy, applies incoming ZEvents to it accounting for user ids and access rights, tracks information on currently connected Agents
    Basically the same concept as an app or X client code. Sends ZEvents to modify the Zone and for the most part receives ZEvents wrapped around the human agent's device input (keyboard, mouse, spaceball, etc.). Note however, that unlike X, input events generally originate not in the Zone (as would correspond to the X server), but rather in the end-agent app code (as seen in zme) or underlying libraries. This keeps the Zone itself free of any hardware tie-ins. Also unlike X, multiple Agents may easily coexist within a single program (HUDs, clocks, etc.), each implementing its functionality in a separate thread and sending ZEvents to a common Zone target.
    Routes ZEvents from the local Zone and Agent destined to entities connected nonlocally (that is, outside of client process). Also handles incoming ZEvents and routes them to Zone and sometimes Agents. Since the local Zone is generally responsible for caching the results of interconnected Zone traffic, its generally preferable to route most traffic through the Zone, and allow it to notify Agents as necessary. This does not apply to very simple Agent programs which do not have a local Zone thread.


Now that the Zone class finally has a design to go with its loosely-defined role, implementation of the next incarnation of zme has started. This upcoming version has the following differences from the current one:

  • Zone I/O has finally been nailed down to purely ZEvents and some variations on mutexes. A Zone instance splits off a thread whose primary purpose in life is to wait for input on a shared queue, process the ZEvents appearing there, and update the Zone's Zystem hierarchy as appropriate.
  • This redesign purges all graphics code from the Zone. It will be trivial to create a standalone Zone without any X or OpenGL code or libraries.
  • The viewing Port thread will be able to use a reader/writer lock in conjunction with the Zone to allow direct rendering of the Zone's content.
  • Many of the various caches needed have now been identified, and the object and texture caches are expected to become threaded to allow incremental parallel loading over HTTP.
  • Zys identifiers within the Zone are to become opaque, thus allowing the Zone to change without invalidating pointers in the Port and Agent (read "Z Client").
  • Groundwork for multiple Agent, Ports, and Zones within one process is in place.
  • Inter-Zone communication is to be handled by a separate Net thread. This division is partially due to the difficulty in trying to get a thread to block on both file descriptors AND mutexes. Hence, the Net thread loop will be entirely based on poll(), as are the Agent and Port threads for similar reasons.
  • The Zone itself will do no file descriptor I/O, and so has an internal blocking model that is entirely pthread/mutex based.

(some indeterminate date)

zme, a third-generation rewrite of the object hierarchy manipulator, is much more efficient than its zland predecessors. Where an idle zland would utilize 80-100% of the CPU, the newer zme originally used negligible CPU time (0.1%) while redisplaying during sustained runs with early Zys chains.

Screenshots from Early Incarnations

[floating sheep groups] In the screenshot a hierarchy of objects can be seen, including the test grid, terrain, enclosing sky object, and various sheep. The yellow-bracketed sheep in the rightmost group (the lower of the two medium-size ones) is the current manipulation focus. It's coordinates are in terms of the frame of reference of the red-bracketed sheep nearest the terrain which is acting as its hierarchic base (or parent object). The other three green-bracketed sheep in the rightmost group are the immediately next level of objects contained by the focus object.

In this case, the focus sheep has just been rotated (rolled) to its left, carrying all of its three sub-sheep with it. Note that in performing this operation, the subsheep have not been directly modified at all.

[floating sheep groups with textures] In the image to the right, the first with functional texture mapping, the fact the one sheep on the right is nearly inverted is easily seen. That sheep is actually part of the triad below, and follows that group's movements.

[floating textured sheep from a distance] In this image, where the viewer has pulled back quite some distance from the sheep, the land is currently highlighted for manipulation - it has been enlarged to the point of extending outside of the sky volume.

[floating sheep groups being edited] Here a group of sheep can be seen, individually texture-mapped with a fractal, a color wash, and a complex gold pattern. The white sheep have been inserted dynamically. In this particular run, the sheep.zop object description was edited to correct a mismapping of the texture coördinates, and then the updated sheep description was loaded on-the-fly into the running program (by hitting "=" on an affected sheep). The yellow-highlighted white sheep is the current modification focus.

The Initial Proof-of-Concept

An early branching hierarchy

Here the outer half of the grid has been twisted as a unit due to all of it having been contained in the transform of the highlighted blue cross object.

The First Zys chain

Here the first Zys chain can be see branching up and right from the origin of the testgrid.

encrypt lang [de jp fr] diff backlinks (sec) validate printable
Walk without rhythm and you won't attract the worm.
[ Your browser's CSS support is broken. Upgrade! ]
alexsiodhe, christopher north-keys, christopher alex north-keys