aboutsummaryrefslogtreecommitdiff
path: root/Src/Wasabi/bfc/depend.h
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Wasabi/bfc/depend.h')
-rw-r--r--Src/Wasabi/bfc/depend.h152
1 files changed, 152 insertions, 0 deletions
diff --git a/Src/Wasabi/bfc/depend.h b/Src/Wasabi/bfc/depend.h
new file mode 100644
index 00000000..1dc1a7ea
--- /dev/null
+++ b/Src/Wasabi/bfc/depend.h
@@ -0,0 +1,152 @@
+#ifndef _DEPEND_H
+#define _DEPEND_H
+
+#include <bfc/platform/platform.h>
+#include <bfc/common.h>
+#include <bfc/ptrlist.h>
+
+// 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 <api/dependency/api_dependentviewer.h>
+
+// 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 <ifc_dependent> DependentList;
+ DependentList * viewed_items;
+protected:
+ RECVS_DISPATCH;
+};
+
+template <class VT>
+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<VT*>(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<VT*>(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<VT*>(item), event, param, ptr, ptrlen);
+ }
+};
+
+// ------------------------------------------------------------
+
+#include <api/dependency/api_dependent.h>
+
+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<api_dependentviewer> ViewerList;
+ ViewerList *viewers;
+ GUID class_guid;
+protected:
+ RECVS_DISPATCH;
+};
+
+
+// use like MyClass *myobj = dynamic_guid_cast<MyClass>(some_dependent_ptr);
+// MyClass::getClassGuid() must be defined
+// MyClass::dependent_getInterface() must be defined too
+template <class T>
+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<T*>(dp->dependent_getInterface(g)) : NULL;
+ }
+private:
+ ifc_dependent *dp;
+ const GUID *g;
+};
+
+#endif