Information contained herein is provisional, likely to be outdated, and probably not very good. (But hopefully it's not entirely useless, as an attempt at explaining the general design of Atlas and its components.)


(If someone can think of a better name, please let me know.)

The AtlasObject library simplifies the storage and communication of arbitrary data structures. They can be serialised to/from XML, and can be accessed by C++ and JS code. (The JS interface is not yet implemented, but it will be done eventually...).

The main interface to the AtlasObject system is the AtObj, which is a reference-counted pointer to an immutable tree node. Each node contains a string, and a group of pointers to child nodes that are keyed by strings.

The children are stored in something functionally equivalent to a std::multimap (actually they are stored in a std::multimap, but that's just an implementation detail), so a node can have multiple children with the same key. This is hopefully capable of storing any acyclic data structure, as long as you don't mind all the data being strings.

Efficiency is not a primary concern; this is intended for use in the user interface of the editor, and not in performance-critical parts of the engine. However, copying an AtObj takes constant time (since it does a function call and a pointer dereference and not much else) regardless of how much data is underneath it, and also takes constant space (sizeof(void*), usually 4 bytes) - this makes it convenient to implement an undo/redo feature by simply storing a copy of the AtObj representing the data. Since AtObjs point to immutable data, the 'undo' copy will never be altered.

Updating an AtObj is slightly more expensive, taking time proportional to the number of children the node has. Since the node is immutable, it must be copied, and the AtObj is then re-pointed to the newly allocated node. It's slightly awkward to update a deeply-nested object, but I've not yet found that problem occurring.

Access to children is about as simple as possible:

  AtObj child = parent["key"];

If there are multiple children with the same key, and you want to access anything other than the first, you would use:

  for (AtIter child = parent["key"]; child.defined(); ++child)
    // Now just use 'child' like a normal AtObj

Other usages should be reasonably obvious. If I tried to demonstrate them here, the examples would be horribly broken in a short while after all the code has changed, so I won't bother...


To allow as much code reuse (and therefore laziness) as possible, non-trivial controls are implemented as classes that extend the standard wxWidgets ones. For example, EditableListCtrl extends wxListCtrl, then adds the ability to double-click cells to edit them (choosing the editing method depending on the column), and maintains some blank lines at the end (so users can keep adding to the bottom of the list), and uses AtObjs to store all the displayed data (for easy undoing). That's extended by DraggableListCtrl, which allows rows to be dragged around to rearrange them; and that's extended by things like ActorEditorListCtrl, which specifies the contents of each column, does a little bit of conversion when importing/exporting data, and changes the colours of rows. (If row-colouring was used elsewhere, that code should probably be moved into a ColourableListCtrl.)

There are also standard windows and dialogs, to handle things like import/export/undo/redo buttons and menus.

Individual components, such as ActorEditor, extend the common components to customise them and glue them together.

Compilation, etc

I've been using a slightly-pre-2.5.4 version (from a CVS snapshot) of wxWidgets, and would like to keep up to date when newer versions are released.

The AtlasUI part is compiled in Unicode mode, but it'd be nice to keep it compiling in non-Unicode too. (I've already failed to do that, but there's no point making it worse unnecessarily). Use _T("...") for strings that should switch between Unicode/ASCII. Use _("...") instead for all strings that are visible to users, since that will make it far easier to localise the tools for non-English languages if we ever feel like doing so.

Last modified 12 years ago Last modified on Feb 23, 2008, 4:19:00 AM