123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- //!## An object to multiplex the callbacks of multiple attributes.
- #ifndef _ATTRHANDLER_H
- #define _ATTRHANDLER_H
- // This class is meant to be subclassed. The methods you must provide
- // are given as pure virtuals. See ExampleAttrib for more details, and
- // an example subclass that you can copy for your own use.
- #include "attrcb.h"
- #include "attribs.h"
- #include <bfc/map.h>
- //
- // Forward References
- class WAComponentClient;
- class Attribute;
- //
- // Class Definition
- template <class TCallback>
- class AttrHandler {
- protected:
- // Heh, oops. Can't have one AttrCallback handle lots of different attribs, anymore. I fix.
- class AttrHandlerChild : public AttrCallback {
- public:
- AttrHandlerChild(AttrHandler *_parent) : AttrCallback() {
- ASSERT(_parent != NULL);
- recursion = 0;
- callback = NULL;
- parent = _parent;
- }
- // Here is where we split out the different value types
- virtual void onValueChange(Attribute *attr) {
- if (!recursion) {
- // protect our programmers from stack overflow, please.
- recursion = 1;
- if ((callback != NULL) && (parent != NULL)) {
- int id;
- // find the id from the map (friendly)
- int success = parent->attribmap.getItem(attr,&id);
- if (success) {
- // and send it to the proper handling function (poorman's RTTI)
- switch (attr->getAttributeType()) {
- case AttributeType::INT:
- callback->onIntChange(id,*static_cast<_int *>(attr));
- break;
- case AttributeType::BOOL:
- callback->onBoolChange(id, *static_cast<_bool *>(attr));
- break;
- case AttributeType::FLOAT:
- callback->onFloatChange(id, *static_cast<_float *>(attr));
- break;
- case AttributeType::STRING:
- callback->onStringChange(id, *static_cast<_string *>(attr));
- break;
- }
- }
- }
- recursion = 0;
- }
- }
- virtual void bindCallbackObj(TCallback *callbackobj) {
- // Be advised, this may be null. That's okay, we test for it above.
- callback = callbackobj;
- }
- private:
- int recursion;
- TCallback *callback;
- AttrHandler *parent;
- };
- public:
- AttrHandler() {
- component = NULL;
- callback = NULL;
- }
- // Call this method to bind your component (in your component's constructor)
- virtual void bindComponent(WAComponentClient *parentcomponent) {
- component = parentcomponent;
- }
- // Call this method to bind your callback object (usually your window in its constructor)
- virtual void bindCallbackObj(TCallback *callbackobj) {
- // Bind ourselves.
- callback = callbackobj;
- // Then go through and rebind any children.
- int i, num = attrchildren.getNumItems();
- for (i = 0; i < num; i++) {
- AttrHandlerChild *child = attrchildren.enumItem(i);
- child->bindCallbackObj(callback);
- }
- }
- // Call this method to register each attribute.
- virtual void registerAttribute(Attribute *attr, int id) {
- ASSERTPR(component != NULL, "BIND YOUR COMPONENT before registering Attributes to a Handler.");
- // register the attrib with a child object as its callback
- AttrHandlerChild *child = new AttrHandlerChild(this);
- attrchildren.addItem(child);
- component->registerAttribute(attr, child);
- // and save its id mapping
- attribmap.addItem(attr, id);
- }
- #if 0
- // Your callback object (probably your primary window class) must implement
- // its own versions of these methods here. They will be called by the
- // switch statement below.
- virtual void onIntChange(int id, int *attr);
- virtual void onBoolChange(int id, bool *attr);
- virtual void onFloatChange(int id, double *attr);
- virtual void onStringChange(int id, const char *attr);
- #endif
-
- private:
- friend AttrHandlerChild;
- TCallback *callback;
- WAComponentClient *component;
- Map< Attribute *, int > attribmap;
- PtrList<AttrHandlerChild> attrchildren;
- };
- #endif // _ATTRHANDLER_H
|