Data Structures Hierarchy


This is, basically, the center of Module/GUI Communication, however is also used by the Core itself. An object is a container which can contain other objects, as well as arbitary data. An object knows about its parent and shall notify the parent upon events happening within itself. An object shall also relay messages coming from deeper within the object hierarchy upwards. Upon events, either internal or coming from lower levels, an object notifies all of its watchers before passing the event up the hierarchy.


The basic problem regarding HydraNode Core/GUI Communication is that we need to relay arbitary data up to the user interface which we do not know the specifics about. The data is defined and implemented within loaded modules to which the Core Framework has no access. The intent is also to keep the user interface oblivious about the modules data structures specifications, while allowing the structures to be displayed, modified and interacted with.


In order to achieve the afore-mentioned requirements, an Object class implements the following characteristics:

The default constructor of the Object is not allowed. An Object is required to have a parent, thus placing it immediately within the data structures hierarchy upon construction.

The only allowed constructor, as well as the destructor of Object are protected, only accessible from derived classes. This enforces the implementation to use only objects derived from Object in the hierarchy, effectivly forbidding base class construction. It also disallows deleting the Object pointers returned by traversing the hierarchy, since that would give control of the data structures to outside world, which is a threat to the original implementer of the data structure (e.g. the module).


If an object contains other objects which in turn contain data members, the Core/GUI Communication Protocol requires that the data fields names for all of the contained objects are same. This means an object is required to contain only objects of same type, thus with same data members. This requirement is not enforced by the implementation of the base class due to impelemtation complications, however is required to be enforced by derived classes. Objects containing mixed set of objects of different types is not allowed.


The module wishing to make its data structures available to the user interface must first derive the container class from Object, and also the actual data structure to be exported from Object. Modules are required to place their data structures below their entry class. In order to make the implemented structures available to the interface, the implementor should override the virtual functions defined in the base class. A sample implementation can be found in the Core Framework test-suite, at tests/test-object/test-object.cpp.

If the implemented data structure changes, the implementor is recommended to notify the user interface through the notify() member function. This allows the user interface to react to changes in the structure, allowing real-time updates.


The parent/child relationship is strong, e.g. the parent owns the child. Additionally, the child always notifies its parent about its destruction, thus deletion of a child is a safe operation - the child is guaranteed to be removed from its parent. The result of this is that the implementors of specific data structures in modules are no longer required to keep any pointers or manage the lifetime of the contained objects (unless explicitly needed).