#ifndef _DEPEND_H #define _DEPEND_H #include #include #include // a pair of classes to implement data dependency. a viewer can register // a list of things it wants to know about // WARNING: this file is still under development. check back for changes // in subsequent SDK releases. over time it is going to become more generic class ifc_dependent; #include // inherit from this one class /*NOVTABLE */DependentViewerI : public api_dependentviewer { protected: /** @param classguid If set, incoming events are restricted to those in that GUID namespace. Can be NULL. */ DependentViewerI(); DependentViewerI(const DependentViewerI &dep); virtual ~DependentViewerI(); // copy DependentViewerI &operator =(const DependentViewerI &dep); // derived classes call this on themselves when they want to view a new item // everything else gets handled automagically void viewer_addViewItem(ifc_dependent *item); void viewer_delViewItem(ifc_dependent *item); void viewer_delAllItems(); void viewer_delAllOfClass(const GUID *guid); //only works if dependent has implemented dependent_getInterface() for the GUID // call this whenever you need to know what you're looking at ifc_dependent *viewer_enumViewItem(int which); int viewer_getNumItems(); // returns TRUE if item is in our list int viewer_haveItem(ifc_dependent *item); // convenience callback methods // item you were looking at is gone: WARNING: pointer no longer valid! virtual int viewer_onItemDeleted(ifc_dependent *item) { return 1; } // item you are looking at issuing an event virtual int viewer_onEvent(ifc_dependent *item, const GUID *classguid, int event, intptr_t param, void *ptr, size_t ptrlen) { return 1; } private: // don't override this; override the individual convenience callbacks virtual int dependentViewer_callback(ifc_dependent *item, const GUID *classguid, int cb, intptr_t param1 = 0, intptr_t param2 = 0, void *ptr = NULL, size_t ptrlen = 0); typedef PtrList DependentList; DependentList * viewed_items; protected: RECVS_DISPATCH; }; template class NOVTABLE DependentViewerT : private DependentViewerI { protected: DependentViewerT() { } DependentViewerT(VT *first) { if (first) viewer_addViewItem(first); } public: using DependentViewerI::viewer_addViewItem; using DependentViewerI::viewer_delViewItem; using DependentViewerI::viewer_delAllItems; VT *viewer_enumViewItem(int which) { return static_cast(DependentViewerI::viewer_enumViewItem(which)); } using DependentViewerI::viewer_getNumItems; using DependentViewerI::viewer_haveItem; // spiffy callbacks to override // item you were looking at is gone: WARNING: pointer no longer valid! virtual int viewer_onItemDeleted(VT *item) { return 1; } // item you are looking at issuing an event (filtered by class guid of VT) virtual int viewer_onEvent(VT *item, int event, intptr_t param2, void *ptr, size_t ptrlen) { return 1; } private: virtual int viewer_onItemDeleted(ifc_dependent *item) { return viewer_onItemDeleted(static_cast(item)); } virtual int viewer_onEvent(ifc_dependent *item, const GUID *classguid, int event, intptr_t param, void *ptr, size_t ptrlen) { if (*classguid != *VT::depend_getClassGuid()) return 0; // filter namespace return viewer_onEvent(static_cast(item), event, param, ptr, ptrlen); } }; // ------------------------------------------------------------ #include class NOVTABLE DependentI : public ifc_dependent { protected: DependentI(const GUID *class_guid = NULL); DependentI(const DependentI &dep); virtual ~DependentI(); public: // copy DependentI& operator =(const ifc_dependent &dep); protected: // override this to catch when viewers register and deregister virtual void dependent_onRegViewer(api_dependentviewer *viewer, int add) {} // override this to help people cast you to various classes virtual void *dependent_getInterface(const GUID *classguid) { return NULL; } // call this on yourself to send an event void dependent_sendEvent(const GUID *classguid, int event, intptr_t param = 0, void *ptr = NULL, size_t ptrlen = 0, api_dependentviewer *viewer = NULL); private: virtual void dependent_regViewer(api_dependentviewer *viewer, int add); void sendViewerCallbacks(const GUID *classguid, int msg, intptr_t param1 = 0, intptr_t param2 = 0, void *ptr = NULL, size_t ptrlen = 0, api_dependentviewer *viewer = NULL); typedef PtrList ViewerList; ViewerList *viewers; GUID class_guid; protected: RECVS_DISPATCH; }; // use like MyClass *myobj = dynamic_guid_cast(some_dependent_ptr); // MyClass::getClassGuid() must be defined // MyClass::dependent_getInterface() must be defined too template class dynamic_guid_cast { public: dynamic_guid_cast(ifc_dependent *_dp, const GUID *_g) : dp(_dp), g(_g) { } operator T*() { return (*g == *T::depend_getClassGuid()) ? static_cast(dp->dependent_getInterface(g)) : NULL; } private: ifc_dependent *dp; const GUID *g; }; #endif