VisClass: 5.4 Working with Visible Object Trees: Sending Messages Through the Tree

Up: GEOS SDK TechDocs | Up | Prev: 5.3 Getting Visible Tree Information | Next: 5.5 Visible Object Window Operations

Often an object will need to contact its parent or children but will not know their precise optrs. Other times, you may need to send a message to a particular object in the tree but don't know where in the tree the object is. GEOS provides several ways to dispatch messages to parents and children and even to objects of a given class.

Contacting Parents and Children Directly

 @visParent,  @visChildren, MSG_VIS_CALL_PARENT, MSG_VIS_SEND_TO_PARENT, MSG_VIS_SEND_TO_CHILDREN

To send a given message to an object's parent (to check valid bounds, to check the parent's state, etc.), you can use the macro @visParent . To do this, substitute the macro in place of the destination object's name, as follows:

kids = @call @visParent::MSG_VIS_COUNT_CHILDREN();

The above call is more efficient than using two message calls for the same thing, as follows:

myParent = @call self::MSG_VIS_FIND_PARENT();
kids = @call myParent::MSG_VIS_COUNT_CHILDREN();

Note that either @call or @send may be used with the @visParent macro.

A similar macro, @visChildren , is offered for sending messages to a composite's children. Note, however, that you can only use the @send keyword to send messages with this macro; there is no way for a single call to collect return values from many different objects. So, if you need to pass pointers to your children, you will have to get each child's optr in turn and dispatch the message to it individually. (Recall that pointers should not be passed with @send because they may be invalidated by the time the message is handled.) The format for using the @visChildren macro is as follows:

@send @visChildren::MSG_VIS_INVALIDATE();

This usage is much more efficient than counting the composite's children and using a loop to get the child's optr and send the child the message.

In addition to providing the above macros, VisClass lets you pass recorded events to a visible object's parent or children. This can be useful, for example, if you need to send a message to another object's parent; you might otherwise first have to find the optr of the object's parent and then send the message directly. Instead, you can use the VisClass messages MSG_VIS_CALL_PARENT and MSG_VIS_SEND_TO_PARENT to pass recorded (encapsulated) events to the recipient's parent.

To send a recorded event to a visible object's children use the message MSG_VIS_SEND_TO_CHILDREN . The recorded event will not be allowed to return anything for the same reason the @visChildren macro can not.

MSG_VIS_CALL_PARENT

void	MSG_VIS_CALL_PARENT(
        EventHandle event);

This message delivers the passed recorded event to the parent of the recipient object. It acts as a call, executing immediately even across threads.

Source: Unrestricted.

Destination: Any visible object.

Parameters: event The event handle of the prerecorded event to be delivered.

Return: Nothing.

Interception: Unlikely.

Tips: In Goc, an object should not send this message to itself; instead, it should use the @visParent macro described above.

MSG_VIS_SEND_TO_PARENT

void	MSG_VIS_SEND_TO_PARENT(
        EventHandle event);

This message delivers the passed recorded event to the parent of the recipient object. It acts as a send, allowing the caller to continue execution without waiting for the event to be handled.

Source: Unrestricted.

Destination: Any visible object.

Parameters: event The event handle of the recorded event to be delivered.

Return: Nothing.

Interception: Unlikely.

Tips: In Goc, an object should not send this message to itself; instead, it should use the @visParent macro described above.

MSG_VIS_SEND_TO_CHILDREN

void	MSG_VIS_SEND_TO_CHILDREN(
        EventHandle event);

This message delivers the passed recorded event to each of the recipient's children. It acts as a message send and can not return values; there is no way for a single message to call several objects and return values from each with a single call.

Source: Unrestricted.

Destination: Any visible composite object.

Parameters: event The event handle of the recorded event to be delivered.

Return: Nothing.

Structures: In Goc, an object should not send this message to itself; instead, it should use the @visChildren macro described above.

Warnings: Do not pass pointers in the recorded event's parameters because the message may not be handled before the pointers are invalidated.

Sending Classed Events Up the Tree

MSG_VIS_VUP_FIND_OBJECT_OF_CLASS, MSG_VIS_VUP_CALL_OBJECT_OF_CLASS, MSG_VIS_VUP_SEND_TO_OBJECT_OF_CLASS, MSG_VIS_VUP_TEST_FOR_OBJECT_OF_CLASS

VisClass has several messages that automatically travel up the visible object tree until they get to an object that meets the proper criteria; they then deliver themselves to that object. This is accomplished by the default handler in VisClass recognizing whether the given object meets the criteria; if it does not, the handler passes the message up to the object's parent.

To find an object of a given class in the tree, use the message MSG_VIS_VUP_FIND_OBJECT_OF_CLASS . This message travels up the tree starting at the recipient until it reaches the first object of that class. So if you are looking for an object of VisCompClass , at the most the message will be passed up a single level.

If you need to send a message to an object of a given class in the visible tree, you can either find it and send it the message or send the message directly with the visible upward messages MSG_VIS_VUP_CALL_OBJECT_OF_CLASS and MSG_VIS_VUP_SEND_TO_OBJECT_OF_CLASS . These messages search up the tree in the same was as MSG_VIS_VUP_FIND_OBJECT_OF_CLASS , and they then deliver the passed event to the resulting object.

To see simply whether an object of a given class exists in the visible tree, use MSG_VIS_VUP_TEST_FOR_OBJECT_OF_CLASS . This is useful if you are going to use MSG_VIS_VUP_CALL_OBJECT_OF_CLASS (or its counterpart). If no object of the given class exists, you can skip sending the recorded message.

To send classed messages to an object in the tree that is of a specific class, you can use TravelOption with certain MetaClass messages. VisClass defines a travel option TO_VIS_PARENT, which sends the message to the first object up the tree that is of the specified class.

MSG_VIS_VUP_FIND_OBJECT_OF_CLASS

optr	MSG_VIS_VUP_FIND_OBJECT_OF_CLASS(
        ClassStruct *class);

This message searches up the visible object tree until it encounters an object of the specified class. It then returns the optr of that object.

Source: Unrestricted.

Destination: Any visible object--typically sent by a visible object to itself to find an object of the given class above it in the visible object tree.

Parameters: class A pointer to the ClassStruct structure of the class to be searched for.

Return: The optr of the object of the passed class. If multiple objects of this class exist in the tree, the first encountered will be returned. If no objects of this class are in the tree, a NullOptr will be returned.

Interception: Unlikely--only objects that masquerade as objects of a different class would subclass this message. This practice is highly discouraged.

MSG_VIS_VUP_TEST_FOR_OBJECT_OF_CLASS

Boolean	MSG_VIS_VUP_TEST_FOR_OBJECT_OF_CLASS(
        ClassStruct *class);

This message searches up the visible tree and determines whether an object of the given class is in the tree.

Source: Unrestricted.

Destination: Any visible object--typically sent before MSG_VIS_VUP_CALL_OBJECT_OF_CLASS or MSG_VIS_VUP_SEND_TO_OBJECT_OF_CLASS to ensure that a recipient for the message exists.

Parameters: class A pointer to the ClassStruct structure of the class to be searched for.

Return: True if the class is found; false if it is not.

Interception: Unlikely.

MSG_VIS_VUP_CALL_OBJECT_OF_CLASS

void	MSG_VIS_VUP_CALL_OBJECT_OF_CLASS(
        EventHandle event);

This message searches up the visible tree until it encounters an object of the proper class for the recorded event. The class is specified within the passed event . When the first such object is found, it will be called with the classed event as if an @call had been used with the event directly.

Source: Unrestricted.

Destination: Any visible object--The passed event will be delivered to the first object of the appropriate class, not necessarily to the recipient of the MSG_VIS_VUP_CALL_OBJECT_OF_CLASS .

Parameters: event The event handle of a recorded event.

Return: The classed event delivered by this message may return values as determined by the event. This message returns nothing.

Interception: Unlikely.

MSG_VIS_VUP_SEND_TO_OBJECT_OF_CLASS

void	MSG_VIS_VUP_SEND_TO_OBJECT_OF_CLASS(
        EventHandle event);

This message searches up the visible tree until it encounters an object of the proper class for the recorded event. The class is specified within the passed event . When the first such object is found, the message will be delivered to that object as if an @send had been used with the event directly.

Source: Unrestricted.

Destination: Any visible object--The passed event will be delivered to the first object of the appropriate class, not necessarily to the object that received the MSG_VIS_VUP_SEND_TO_OBJECT_OF_CLASS .

Parameters: event The event handle of a recorded event.

Return: Nothing. The recorded event may not return anything.

Interception: Unlikely.

Warnings: The recorded event should not pass pointers among its parameters.

Visible Upward Queries

MSG_VIS_VUP_QUERY

You can create your own messages that get passed up the visible tree by creating aliases of MSG_VIS_VUP_QUERY . MSG_VIS_VUP_QUERY , by itself, does nothing useful; it simply gets passed up the visible tree without ever being handled.

You can create your own visible queries to return different types of values from objects higher up in the object tree. Take, for example, a music-teaching application which uses note objects as distant children of a sheet music object. If the note objects needed to know what key they were supposed to be in, they would query up the tree with a special upward query message. If we assume the sheet music object kept this information, it would want to respond to the query message with the appropriate value. Thus, the sheet music class would have a line similar to the following:

@alias(MSG_VIS_VUP_QUERY)
        MusicKeyType MSG_VIS_VUP_QUERY_MUSIC_KEY();

This line creates an alias for the general-purpose upward query. The sheet music object should have a handler for MSG_VIS_VUP_QUERY_MUSIC_KEY in which it figures out and returns the appropriate key. This type of upward query can be invaluable in many different situations.

MSG_VIS_VUP_QUERY

void	MSG_VIS_VUP_QUERY();

This message simply queries up the tree until it is handled. It is extensible so visible objects can implement their own upward queries without adding handlers to every class in between it and the query handler.

It is extremely rare that any object would send or handle MSG_VIS_VUP_QUERY on its own; many classes, however, may alias this message and create their own versions of the upward query.

Source: Unrestricted--see note above.

Destination: Any visible object--see note above. Typically sent by a visible object either to itself or directly to its visible parent.

Parameters: None--an alias of this message may have parameters.

Return: Nothing--an alias of this message may have return values.

Interception: MSG_VIS_VUP_QUERY itself should not be intercepted. Its aliases, however, should be intercepted by the appropriate classes that will handle them.

Sending Messages to Window Groups

MSG_VIS_VUP_CALL_WIN_GROUP, MSG_VIS_VUP_SEND_TO_WIN_GROUP

VisClass offers two specific messages for contacting window group objects in a visible tree. These are similar to MSG_VIS_VUP_CALL_OBJECT_OF_CLASS and MSG_VIS_VUP_SEND_TO_OBJECT_OF_CLASS , except they find the window group of the recipient and deliver the event to the window object. These two messages are detailed below.

MSG_VIS_VUP_CALL_WIN_GROUP

void	MSG_VIS_VUP_CALL_WIN_GROUP(
        EventHandle event);

This message searches up the visible object tree until it encounters a window group object. When the first window group is found, it will be called with the classed event as if an @call had been used.

Source: Unrestricted--typically sent by a visible object to itself to deliver the event to its window.

Destination: Any visible object--the passed event will be delivered to a window object, not necessarily to the object that receives the MSG_VIS_VUP_CALL_WIN_GROUP .

Parameters: event The event handle of a recorded event to be delivered to the window object.

Return: The passed event may return its own values, but MSG_VIS_VUP_CALL_WIN_GROUP returns nothing.

Interception: Unlikely.

See Also: MSG_VIS_VUP_CALL_OBJECT_OF_CLASS.

MSG_VIS_VUP_SEND_TO_WIN_GROUP

void	MSG_VIS_VUP_SEND_TO_WIN_GROUP(
        EventHandle event);

This message searches up the visible object tree until it encounters a window group object. When the first window group is found, the passed event will be delivered to that object as if an @send had been used directly.

Source: Unrestricted--typically sent by a visible object to itself to deliver the event to its window.

Destination: Any visible object--the passed event will be delivered to a window object, not necessarily to the object that receives the MSG_VIS_VUP_CALL_WIN_GROUP .

Parameters: event The event handle of a recorded event to be delivered to the window object.

Return: Nothing. The recorded event may not return values.

Interception: Unlikely.

Warnings: The recorded event may not pass pointers among its parameters.

See Also: MSG_VIS_VUP_SEND_TO_OBJECT_OF_CLASS.


Up: GEOS SDK TechDocs | Up | Prev: 5.3 Getting Visible Tree Information | Next: 5.5 Visible Object Window Operations