VkCallbackObject(3x)
VkCallbackObject - An abstract class that supports classes that use C++ member function callbacks
As shipped in IRIX 6.5.7. Unchanged since IRIX 6.5.
NAME VkCallbackObject - An abstract class that supports classes that use C++ member function callbacks HEADER FILE #include <Vk/VkCallbackObject.h> PUBLIC PROTOCOL SUMMARY Destructor virtual void ~VkCallbackObject(void); Access Functions virtual const char* className(void); Callback Support void addCallback(const char *name, VkCallbackFunction func, void *clientData = NULL) void addCallback(const char *name, VkCallbackObject *obj, VkCallbackMethod method, void *clientData = NULL) void removeCallback(char *name, VkCallbackFunction func, void *clientData = NULL) void removeCallback(char *name, VkCallbackObject *obj, VkCallbackMethod method, void *clientData = NULL) void removeAllCallbacks() void removeAllCallbacks(VkCallbackObject *obj) Callback Function Format typedef void (*VkCallbackFunction) ( VkCallbackObject *caller, void *clientData, void *callData); typedef void (*VkCallbackObject::VkCallbackMethod) ( VkCallbackObject *caller, void *clientData, void *callData); Dynamic Loading Support static VkCallbackObject *loadObject(const char *name, const char *className, const char *filename); const VkNameList* getMethods(); const char *getMethodArgType(const char *methodName); void invokeMethod(const char *method, void *arg); void invokeMethod(const char *method, int arg); void invokeMethod(const char *method, Boolean arg); void invokeMethod(const char *method, const char *arg); void invokeMethod(const char *method); PROTECTED PROTOCOL SUMMARY Invoking Callbacks void callCallbacks(const char* const name, void *callData); Constructor VkCallbackObject(void); CONVENIENCE MACROS void VkAddCallbackFunction(const char *name, VkCallbackObject *otherObject, VkCallbackFunction func, void *clientData); VkAddCallbackMethod(const char *name, VkCallbackObject *otherObject, VkCallbackObject *thisObject, VkCallbackMethod func, void *clientData); void VkRemoveCallbackFunction(const char *name, VkCallbackObject *otherObject, VkCallbackFunction func, void *clientData); VkRemoveCallbackMethod(const char *name, VkCallbackObject *otherObject, VkCallbackObject *thisObject, VkCallbackMethod func, void *clientData); CLASS DESCRIPTION The VkCallbackObject class supports registering and calling regular C++ member functions between instances of any class or classes derived from VkCallbackObject. Both the registering class and the class with which the callback is registered must be derived from VkCallbackObject. Note that these member functions should not be static functions. Member functions must have the form: void memberFunctionCallback(VkCallbackObject *obj, void *clientData, void *callData); The first argument provides a pointer to the calling object, which should be cast to the correct type to allow access to members provided by that class. An application should not delete a VkCallbackObject from within code called by one of its callbacks. Doing so may core dump, because the application has no way of knowing what else the library may be doing with the object after calling the callback list. DERIVING SUBCLASSES Classes derived from the VkCallbackObject class can easily support C++ member function callbacks. Derived classes must export a name for any callback it wishes to support. Classes can support any number of callbacks. A callback is simply identified as a string. To prevent name space collisions, the string should be exported by the class as a static member. Other classes can register member functions to be called, using this string. The class can invoke any callbacks registered with this callback list, also using the same string. Example The following simple class supports two callback lists, named "firstCallback" and "secondCallback". ////////////////////////////////////// // Header file for ExampleClass ////////////////////////////////////// #include <Vk/VkCallbackObject.h> class ExampleClass : public VkCallbackObject { public: ExampleClass() : VkCallbackObject() { }; void aMemberFunction(); void anotherMemberFunction(); static const char *const firstCallback; static const char *const secondCallback; }; ////////////////////////////////////// // Source file for ExampleClass ////////////////////////////////////// #include "ExampleClass.h" const char *const ExampleClass::firstCallback = "firstCallback"; const char *const ExampleClass::secondCallback = "secondCallback"; void ExampleClass::aMemberFunction() { callCallbacks(firstCallback, NULL); } void ExampleClass::anotherMemberFunction() { callCallbacks(secondCallback, NULL); } FUNCTION DESCRIPTIONS callCallbacks void callCallbacks(const char* const name, void *callData); The callCallbacks() member function can be called from any class derived from VkCallbackObject to invoke the ViewKit member function callbacks registered with the named list. The first argument specifies the string by which the callback is known, while the second is used to supply an additional data that might be required. Also see addCallback(). addCallback void addCallback(const char *name, VkCallbackObject *otherObject, VkCallbackMethod memberFunction, void *clientData = NULL); void addCallback(const char *name, VkCallbackFunction func, void *clientData = NULL); All classes derived from VkCallbackObject, which includes ViewKit component classes, can support member function callbacks. These callbacks should not be confused with the Xt-style callbacks supported by Motif widgets, although the concept is similar. ViewKit classes that support callbacks export the names of these callbacks as const strings declared as public static members. Any other class derived from VkCallbackObject can register itself to be called when the condition associated with that callback occurs. For example, the VkComponent class, and therefore all derived classes support a deleteCallback that is invoked when the component's destructor is called. This can be useful for reducing dangling pointers when maintaining pointers to other objects. Here, a member of a hypothetical SampleComponent class instantiates another hypothetical component class, ExampleComponent, registering a callback to be called when the ExampleComponent is deleted. SampleComponent::memberFunction() { _ptr = new ExampleComponent(_baseWidget, "sample"); _ptr->addCallback(VkComponent::deleteCallback, this, (VkCallbackMethod) &SampleComponent::ptrDeleted); } The cast is required in C++. The form of all ViewKit member function callbacks is typedef void (VkCallbackOject::*VkCallbackMethod) ( VkCallbackObject *caller, void *clientData, void *callData); The first argument is the object that invoked the callback, the second is the optional client data specified when the callback was registered, and the third is optional data supplied by the calling object. For example, the ptrDeleted() callback method used above would be declared as follows: class SampleComponent : VkComponent { // ... VkComponent *_ptr; void ptrDeleted(VkComponent *, void *, void *); // ... }; The member function might be written as follows: void SampleComponent::ptrDeleted(VkComponent*, void *, void *) { _ptr = NULL; } This eliminates the possibility that the SampleComponent class would try to delete the ExampleComponent object a second time. In general, multiple pointers to the same object should be avoided, but the VkComponent::deleteCallback provides a way to control situations in which this guideline must be violated. removeCallback void removeCallback(char *name, VkCallbackObject *otherObject, VkCallbackMethod memberFunction, void *clientData = NULL); void removeCallback(char *name, VkCallbackFunction func, void *clientData = NULL); Remove a callback previously registered with another object. removeAllCallbacks void removeAllCallbacks(); void removeAllCallbacks(VkCallbackObject *obj); The first form of this function removes all callbacks from an object, regardless of who registered the callbacks. The second form removes only those callbacks that are member functions of the specified component. VkAddCallbackFunction void VkAddCallbackFunction(const char *name, VkCallbackObject *otherObject, VkCallbackFunction func, void *clientData); VkAddCallbackFunction() is a convenience macro that can be used to install a function as a callback. The macro takes the callback name, the object with which the callback is to be registered, the function to be called, and any client data. The macro expands in the appropriate calls to addCallback(). VkAddCallbackMethod VkAddCallbackMethod(const char *name, VkCallbackObject *otherObject, VkCallbackObject *thisObject, VkCallbackMethod func, void *clientData); VkAddCallbackMethod() is a convenience macro that can be used to install a member function as a callback. The macro takes the callback name, the object with which the callback is to be registered, the object to be called, the member function to be called, and any client data. The macro expands in the appropriate calls to addCallback(). The main advantage of using VkAddCallbackMethod() over the direct use of addCallback() is that the required cast is handled automatically. DYNAMIC LOADING ViewKit supports the ability to dynamically load a class from a dynamic shared object (library). To participate in this scheme, a VkCallbackObject subclass must provide a few hooks, using specific conventions. Classes created with RapidApp(TM) are automatically set up for dynamic loading. To prepare a class by hand, you must provide a creation function and an optional Interface Map. The creation function is a static member function that creates an instance of the associated class. The creation function must be named Create<ClassName>, where <ClassName> is the name of the class, and must take one argument, the name of the instance. The class is expected to instantiate an object and return it as a VkCallbackObject*. For example, a class DataModel would have a declaration in its header: static VkCallbackObject *CreateDataModel(const char *name); and then in the source file, implement: VkCallbackObject * DataModel::CreateDataModel(const char *name) { DataModel *obj = new DataModel(name); return obj; } loadObject static VkComponent *loadObject(const char *name, const char *className, const char *filename); If an object has the creation member function described above, you can load it by calling VkCallbackObject::loadObject, with an instance name, name of the class to be instantiated, and the name of a file in which the object is located. For example, a class DataModel, which is found in a shared library named libdm.so, can be loaded as: DataModel *dm = VkCallbackObject::loadObject("datamodel", "DataModel", "libdm.so"); If you know the type of the object to be loaded, as in the above example, and can include its header file, you can interact with the object directly. However, you can also describe operations supported by an object dynamically. This is done by providing another static member function, which must be named Register<ClassName>Interface. This function must return a an array of structures of type VkCallbackObject::InterfaceMap. This structure has three fields: A name that identifies the operation. This is used in RapidApp for identifying a name in the style of X/Motif resources. It could also be used by applications for similar purposes. The name of a member function to be called to perform the operation. The type of the single argument supported by the function. The supported types are, XmRInt, XmRString, XmRBoolean, XmRFloat, VkRNoArg, VkRFileName, and enumerations. Enumerations are described as a string that begins with the keyword "Enumeration:" and continues with the list of values in the enumeration, which is assumed to be zero-based. The type VkRFilename represents a string that is a filename. Programmatically, it will be treated as a string, but the additional information is useful for objects loaded into RapidApp. The symbol VkNoArg indicates that the function takes no arguments. The following member function demonstrates how this information can be provided. void* DataModel::RegisterDataModelInterface() { static VkComponent::InterfaceMap map[] = { { "label", "setLabel", XmRString}, { "readOnly","setReadOnly", XmRBoolean}, { NULL }, // MUST be NULL terminated }; return map; } The functions exported through this dynamic interface must meet the following restrictions: They must be regular, non static, non virtual member functions. They must take a single argument They must have a void return type. getMethods const VkNameList* getMethods(); This member function allows a program to retrieve a list of the dynamic methods supported by an object that has been loaded using VkCallbackObject::loadObject. See VkNameList.3x for details on this class. getMethodType const char *getMethodArgType(const char *methodName); This function allows applications to query the type of the argument for a dynamic method exported by an object loaded by VkCallbackObject::loadObject. invokeMethod void invokeMethod(const char *method, void *arg); void invokeMethod(const char *method, int arg); void invokeMethod(const char *method, Boolean arg); void invokeMethod(const char *method, const char *arg); void invokeMethod(const char *method); This overloaded function allows a dynamic method supported by a class loaded buy VkCallbackObject::loadObject to be invoked. This is more expensive than casting the object to the correct type and invoking member functions directly, but can be useful in cases where the type signature of the object is completely unknown. When the debugging version of the ViewKit library is used, assertions provide a limited form of type checking. Otherwise, it is up to the programmer to be sure the named method actually supports the data type provided. DIRECTLY DERIVED CLASSES VkComponent, VkModel, VkPeriodic SEE ALSO VkComponent ViewKit Programmer's Guide Developer Magic: RapidApp User Guide The X Window System, DEC Press, Bob Sheifler and Jim Gettys The X Window System Toolkit, DEC Press, Paul Asente and Ralph Swick The OSF/Motif Programmers Reference, Prentice Hall, OSF