Locating Objects in the Object Tree

From MorphOS Library

Revision as of 20:23, 4 January 2011 by Krashan (talk | contribs) (copy and paste bug fix)

After the complete object tree is created, there is no direct access to any object except the main Application object. A way to access other objects is needed. There are a few ways to do this:

  • Storing pointers to objects in global variables. This is the simplest way and may work well in simple projects. The disadvantage is it breaks object oriented design principles (like data encapsulation) and creates a mess when number of global variables reaches 50, 100 or more.
  • Store pointers in fields of some subclass instance data (for example Application one). A good idea, but a bit tedious to implement. Object's instance data area does not exist until the object is fully created and the Application object is created as the last one. Then pointers to subobjects have to be stored in some temporary variables. This technique also requires that a parent object of the cached one is an instance of a custom (subclassed) class and the parent creates its subobjects inside the constructor, which is not always true.
  • Use MUIA_UserData attribute and MUIM_FindUData() method to find objects dynamically. This is the best solution when objects are accessed rarely (for example once, just to set notifications). For frequently accessed objects (let's say several times a second) it may be combined with caching objects' pointers in an instance data of some subclassed object.

The last approach works as follows: every object to be searched has the MUIA_UserData attribute set to some predefined unique value. Then at any time the object may be found by this value using MUIM_FindUData() method on a direct or indirect parent object, for example on the master Application one.

#define OBJ_SOME_BUTTON 36

/* Somewhere in the initial tags for the button */
MUIA_UserData, OBJ_SOME_BUTTON,
/* ... */

/* Let's get the pointer to the button now */

Object *some_button;

some_button = (Object*)DoMethod(App, MUIM_FindUData, OBJ_SOME_BUTTON);

This operation is so common, that it is usually encapsulated in a macro:

#define findobj(id, parent) (Object*)DoMethod(parent, MUIM_FindUData, id)

some_button = findobj(OBJ_SOME_BUTTON, App);

The macro may be of course used directly in other functions, like in this example changing the button label:

set(findobj(OBJ_SOME_BUTTON, App), MUIA_Text_Contents, "Press Me");

Note that the findobj() macro is not defined in the system MUI headers, so it should be defined in the application code.