depend.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #ifndef _DEPEND_H
  2. #define _DEPEND_H
  3. #include <bfc/platform/platform.h>
  4. #include <bfc/common.h>
  5. #include <bfc/ptrlist.h>
  6. // a pair of classes to implement data dependency. a viewer can register
  7. // a list of things it wants to know about
  8. // WARNING: this file is still under development. check back for changes
  9. // in subsequent SDK releases. over time it is going to become more generic
  10. class ifc_dependent;
  11. #include <api/dependency/api_dependentviewer.h>
  12. // inherit from this one
  13. class /*NOVTABLE */DependentViewerI : public api_dependentviewer
  14. {
  15. protected:
  16. /**
  17. @param classguid If set, incoming events are restricted to those in that GUID namespace. Can be NULL.
  18. */
  19. DependentViewerI();
  20. DependentViewerI(const DependentViewerI &dep);
  21. virtual ~DependentViewerI();
  22. // copy
  23. DependentViewerI &operator =(const DependentViewerI &dep);
  24. // derived classes call this on themselves when they want to view a new item
  25. // everything else gets handled automagically
  26. void viewer_addViewItem(ifc_dependent *item);
  27. void viewer_delViewItem(ifc_dependent *item);
  28. void viewer_delAllItems();
  29. void viewer_delAllOfClass(const GUID *guid); //only works if dependent has implemented dependent_getInterface() for the GUID
  30. // call this whenever you need to know what you're looking at
  31. ifc_dependent *viewer_enumViewItem(int which);
  32. int viewer_getNumItems();
  33. // returns TRUE if item is in our list
  34. int viewer_haveItem(ifc_dependent *item);
  35. // convenience callback methods
  36. // item you were looking at is gone: WARNING: pointer no longer valid!
  37. virtual int viewer_onItemDeleted(ifc_dependent *item) { return 1; }
  38. // item you are looking at issuing an event
  39. virtual int viewer_onEvent(ifc_dependent *item, const GUID *classguid, int event, intptr_t param, void *ptr, size_t ptrlen) { return 1; }
  40. private:
  41. // don't override this; override the individual convenience callbacks
  42. 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);
  43. typedef PtrList <ifc_dependent> DependentList;
  44. DependentList * viewed_items;
  45. protected:
  46. RECVS_DISPATCH;
  47. };
  48. template <class VT>
  49. class NOVTABLE DependentViewerT : private DependentViewerI
  50. {
  51. protected:
  52. DependentViewerT() { }
  53. DependentViewerT(VT *first)
  54. {
  55. if (first) viewer_addViewItem(first);
  56. }
  57. public:
  58. using DependentViewerI::viewer_addViewItem;
  59. using DependentViewerI::viewer_delViewItem;
  60. using DependentViewerI::viewer_delAllItems;
  61. VT *viewer_enumViewItem(int which)
  62. {
  63. return static_cast<VT*>(DependentViewerI::viewer_enumViewItem(which));
  64. }
  65. using DependentViewerI::viewer_getNumItems;
  66. using DependentViewerI::viewer_haveItem;
  67. // spiffy callbacks to override
  68. // item you were looking at is gone: WARNING: pointer no longer valid!
  69. virtual int viewer_onItemDeleted(VT *item) { return 1; }
  70. // item you are looking at issuing an event (filtered by class guid of VT)
  71. virtual int viewer_onEvent(VT *item, int event, intptr_t param2, void *ptr, size_t ptrlen) { return 1; }
  72. private:
  73. virtual int viewer_onItemDeleted(ifc_dependent *item)
  74. {
  75. return viewer_onItemDeleted(static_cast<VT*>(item));
  76. }
  77. virtual int viewer_onEvent(ifc_dependent *item, const GUID *classguid, int event, intptr_t param, void *ptr, size_t ptrlen)
  78. {
  79. if (*classguid != *VT::depend_getClassGuid()) return 0; // filter namespace
  80. return viewer_onEvent(static_cast<VT*>(item), event, param, ptr, ptrlen);
  81. }
  82. };
  83. // ------------------------------------------------------------
  84. #include <api/dependency/api_dependent.h>
  85. class NOVTABLE DependentI : public ifc_dependent
  86. {
  87. protected:
  88. DependentI(const GUID *class_guid = NULL);
  89. DependentI(const DependentI &dep);
  90. virtual ~DependentI();
  91. public:
  92. // copy
  93. DependentI& operator =(const ifc_dependent &dep);
  94. protected:
  95. // override this to catch when viewers register and deregister
  96. virtual void dependent_onRegViewer(api_dependentviewer *viewer, int add) {}
  97. // override this to help people cast you to various classes
  98. virtual void *dependent_getInterface(const GUID *classguid) { return NULL; }
  99. // call this on yourself to send an event
  100. void dependent_sendEvent(const GUID *classguid, int event, intptr_t param = 0, void *ptr = NULL, size_t ptrlen = 0, api_dependentviewer *viewer = NULL);
  101. private:
  102. virtual void dependent_regViewer(api_dependentviewer *viewer, int add);
  103. 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);
  104. typedef PtrList<api_dependentviewer> ViewerList;
  105. ViewerList *viewers;
  106. GUID class_guid;
  107. protected:
  108. RECVS_DISPATCH;
  109. };
  110. // use like MyClass *myobj = dynamic_guid_cast<MyClass>(some_dependent_ptr);
  111. // MyClass::getClassGuid() must be defined
  112. // MyClass::dependent_getInterface() must be defined too
  113. template <class T>
  114. class dynamic_guid_cast
  115. {
  116. public:
  117. dynamic_guid_cast(ifc_dependent *_dp, const GUID *_g) : dp(_dp), g(_g) { }
  118. operator T*()
  119. {
  120. return (*g == *T::depend_getClassGuid()) ? static_cast<T*>(dp->dependent_getInterface(g)) : NULL;
  121. }
  122. private:
  123. ifc_dependent *dp;
  124. const GUID *g;
  125. };
  126. #endif