General Change Notification: 4.3 Application Local GCN Lists: Handling Application Notification

Up: GEOS SDK TechDocs | Up | Prev: 4.2 Registering for Notification | Next: 4.4 Removal from Application Lists
MSG_META_NOTIFY, MSG_META_NOTIFY_WITH_DATA_BLOCK, MSG_META_GCN_LIST_SEND

When a change occurs in the application that needs to send out notification, you must set up the notification message and send it to the interested list. You may attach a data block to this notification for use by the objects on the notification list. To send out these notifications, you should use MSG_META_NOTIFY or MSG_META_NOTIFY_WITH_DATA_BLOCK (when passing data).

In the simplest case without the need to pass data, you should encapsulate MSG_META_NOTIFY with the particular Notification ID (notification type and Manufacturer ID) that should be notified. You should then send MSG_GEN_PROCESS_SEND_TO_APP_GCN_LIST to your application object with this event and the particular GCN list interested in this change. (Note that you will have to keep track of which lists are interested in which notification types.) Make sure that you perform a send (not a call) when using this message as the message may cross threads.

Code Display 9-5 Using MSG_META_NOTIFY

@method MyProcessClass, MSG_SEND_CUSTOM_NOTIFICATION {
    MessageHandle event;
/* First encapsulate the MSG_META_NOTIFY with the type of list and manufacturer ID
 * interested in the change. Since this message is being recorded for no class in
 * particular, use NullClass.*/
    event = @record (optr) NullClass::MSG_META_NOTIFY(
	MANUFACTURER_ID_yourCompanyName,
	yourCompanyName_NT_CUSTOM_TYPE_ONE);
/* Then send this MSG_META_NOTIFY using MSG_META_GCN_LIST_SEND. You must make sure
 * to pass the particular GCN list interested in the changes encapsulated in the
 * above message. */
    @send MyProcess::MSG_GEN_PROCESS_SEND_TO_APP_GCN_LIST (
	(word) 0, 			/* GCNListSendFlags */
	event,			/* Handle to MSG_NOTIFY event above. */
	0,			/* No data passed, so no data block. */
	/* Pass the list interested in NT_CUSTOM_TYPE_ONE notification types. */
	yourCompanyName_GAGCNLT_APP_CUSTOM_LIST_ONE,
	/* Pass your manufacturer ID. */
	MANUFACTURER_ID_yourCompanyName);
}

If instead you need to pass a data block along with the notification, you should use MSG_META_NOTIFY_WITH_DATA_BLOCK . You should set up the structure to pass beforehand. You must also make sure to add a reference count to the data block equal to the number of lists (not objects) you wish to send the notification. To do this, call MemInitRefCount() with the data block and the total number of lists you are sending the notification to. (In most cases, you will only send notification to one list, although, of course, that list may have several objects.)

Code Display 9-6 MSG_META_NOTIFY_WITH_DATA_BLOCK

@method MyProcessClass, MSG_SEND_CUSTOM_NOTIFICATION {
    typedef struct {
	int number;
	char letterToLookFor;
    } MyDataStructure;
    MemHandle myDataBlock;
    MyDataStructure *myDataPtr;
    MessageHandle event;
/* Allocate and lock down a block for the data structure. This will be passed
 * along with the notification. NOTE: data blocks must be sharable! */
    myDataBlock = MemAlloc(sizeof(MyDataStructure), (HF_DYNAMIC | HF_SHARABLE),
			 HAF_STANDARD);
    myDataPtr = MemLock(myDataBlock);
/* Load up the structure with pertinent information. */
    myDataPtr->count = 200;
    myDataPtr->letterToLookFor = `z';
/* Unlock it and set its reference count to 1 as we are only sending this to one
 * list. */
    MemUnlock(myDataBlock);
    MemInitRefCount(myDataBlock, (word) 1);
/* Now encapsulate a MSG_META_NOTIFY_WITH_DATA_BLOCK message. Since it is being
 * recorded for no particular class, use NullClass as its class type. */
    event = @record (optr) NullClass::MSG_META_NOTIFY_WITH_DATA_BLOCK(
			MANUFACTURER_ID_yourCompanyName,				/* Manufacturer ID */
			NT_CUSTOM_TYPE_ONE,				/* List type. */
			myDataBlock);				/* handle of data block */
/* Finally, send the message off to our process. The GCNListSendFlags depend on
 * the situation. */
    @send MyProcess::MSG_GEN_PROCESS_SEND_TO_APP_GCN_LIST(
			(word) 0,			/* GCNListSendFlags */
			event,			/* Handle to message */
			myDataBlock,			/* Handle of data block */
	/* Pass the type of list interested in NT_CUSTOM_TYPE_ONE notification. */
			GAGCNLT_APP_CUSTOM_LIST_ONE,
			MANUFACTURER_ID_yourCompanyName);
/* All done! myDataBlock will be MemFree()'d automatically. */
}

The object or process originally requesting notification of the change will want to provide a handler for the MSG_META_NOTIFY or MSG_META_NOTIFY_WITH_DATA_BLOCK . If additional data about the change is passed in a data block, the process should access that information with MemLock() and MemUnlock() . You should always call the process's superclass in your message handler, to make sure that the global heap block will be automatically freed by MetaClass . Therefore, do not free a notification data block manually in a notification handler.

Code Display 9-7 Intercepting an Application Notification Change

/* Code to implement when MyObjectClass receives MSG_META_NOTIFY with a certain
 * notification type. */
@method MyObjectClass, MSG_META_NOTIFY {
    MyDataStructure myData;				/* Stores the passed data block. */
/* Lock the data structure. */
    myData = MemLock(data);
/* Check the notification type and implement the changes you wish to occur in
 * response to the previous event. */
    if ((notificationType == yourCompanyName_NT_CUSTOM_TYPE_ONE) & 
	(manufID == MANUFACTURER_ID_yourCompanyName)){
	/* Code to implement for your object. */
    }
    MemUnlock(data);
    @callsuper;				/* Important! Frees data block. */
}

Up: GEOS SDK TechDocs | Up | Prev: 4.2 Registering for Notification | Next: 4.4 Removal from Application Lists