home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 275 / DPCS0111DVD.ISO / Toolkit / Audio-Visual / VirtualDub / Source / VirtualDub-1.9.10-src.7z / src / h / vd2 / system / event.h < prev    next >
Encoding:
C/C++ Source or Header  |  2009-09-14  |  6.3 KB  |  202 lines

  1. //    VirtualDub - Video processing and capture application
  2. //    System library component
  3. //    Copyright (C) 1998-2006 Avery Lee, All Rights Reserved.
  4. //
  5. //    Beginning with 1.6.0, the VirtualDub system library is licensed
  6. //    differently than the remainder of VirtualDub.  This particular file is
  7. //    thus licensed as follows (the "zlib" license):
  8. //
  9. //    This software is provided 'as-is', without any express or implied
  10. //    warranty.  In no event will the authors be held liable for any
  11. //    damages arising from the use of this software.
  12. //
  13. //    Permission is granted to anyone to use this software for any purpose,
  14. //    including commercial applications, and to alter it and redistribute it
  15. //    freely, subject to the following restrictions:
  16. //
  17. //    1.    The origin of this software must not be misrepresented; you must
  18. //        not claim that you wrote the original software. If you use this
  19. //        software in a product, an acknowledgment in the product
  20. //        documentation would be appreciated but is not required.
  21. //    2.    Altered source versions must be plainly marked as such, and must
  22. //        not be misrepresented as being the original software.
  23. //    3.    This notice may not be removed or altered from any source
  24. //        distribution.
  25.  
  26. #ifndef f_VD2_SYSTEM_EVENT_H
  27. #define f_VD2_SYSTEM_EVENT_H
  28.  
  29. struct VDDelegateNode {
  30.     VDDelegateNode *mpNext, *mpPrev;
  31. };
  32.  
  33. class VDDelegate;
  34.  
  35. class VDEventBase {
  36. protected:
  37.     VDEventBase();
  38.     ~VDEventBase();
  39.  
  40.     void Add(VDDelegate&);
  41.     void Remove(VDDelegate&);
  42.     void Raise(void *src, const void *info);
  43.  
  44.     VDDelegateNode mAnchor;
  45. };
  46.  
  47. // Because Visual C++ uses different pointer-to-member representations for
  48. // different inheritance regimes, we have to include a whole lot of stupid
  49. // logic to detect and switch code paths based on the inheritance used.
  50. // We detect the inheritance by the size of the member function pointer.
  51. //
  52. // Some have managed to make faster and more compact delegates by hacking
  53. // into the PMT representation and pre-folding the this pointer adjustment.
  54. // I'm avoiding this for now because (a) it's even less portable than what
  55. // we have here, and (b) that fails if the object undergoes a change in
  56. // virtual table status while the delegate is alive (which is possible
  57. // during construction/destruction).
  58. //
  59. // Note: We can't handle virtual inheritance here because on X64, MSVC uses
  60. // 16 bytes for both multiple and virtual inheritance cases.
  61.  
  62. #ifdef _MSC_VER
  63.     class __single_inheritance VDDelegateHolderS;
  64.     class __multiple_inheritance VDDelegateHolderM;
  65. #else
  66.     class VDDelegateHolderS;
  67. #endif
  68.  
  69. template<class Source, class ArgType>
  70. class VDDelegateBinding {
  71. public:
  72.     VDDelegate *mpBoundDelegate;
  73. };
  74.  
  75. template<class T, class Source, class ArgType>
  76. struct VDDelegateAdapterS {
  77.     typedef void (T::*T_Fn)(Source *, const ArgType&);
  78.     typedef void (T::*T_Fn2)(Source *, ArgType);
  79.  
  80.     static void Init(VDDelegate& dst, T_Fn fn) {
  81.         dst.mpCallback = Fn;
  82.         dst.mpFnS = reinterpret_cast<void(VDDelegateHolderS::*)()>(fn);
  83.     }
  84.  
  85.     static void Init(VDDelegate& dst, T_Fn2 fn) {
  86.         dst.mpCallback = Fn2;
  87.         dst.mpFnS = reinterpret_cast<void(VDDelegateHolderS::*)()>(fn);
  88.     }
  89.  
  90.     static void Fn(void *src, const void *info, VDDelegate& del) {
  91.         return (((T *)del.mpObj)->*reinterpret_cast<T_Fn>(del.mpFnS))(static_cast<Source *>(src), *static_cast<const ArgType *>(info));
  92.     }
  93.  
  94.     static void Fn2(void *src, const void *info, VDDelegate& del) {
  95.         return (((T *)del.mpObj)->*reinterpret_cast<T_Fn2>(del.mpFnS))(static_cast<Source *>(src), *static_cast<const ArgType *>(info));
  96.     }
  97. };
  98.  
  99. template<int size>
  100. class VDDelegateAdapter {
  101. public:
  102.     template<class T, class Source, class ArgType>
  103.     struct AdapterLookup {
  104.         typedef VDDelegateAdapterS<T, Source, ArgType> result;
  105.     };
  106. };
  107.  
  108. #ifdef _MSC_VER
  109. template<class T, class Source, class ArgType>
  110. struct VDDelegateAdapterM {
  111.     typedef void (T::*T_Fn)(Source *, const ArgType&);
  112.     typedef void (T::*T_Fn2)(Source *, ArgType);
  113.  
  114.     static void Init(VDDelegate& dst, T_Fn fn) {
  115.         dst.mpCallback = Fn;
  116.         dst.mpFnM = reinterpret_cast<void(VDDelegateHolderM::*)()>(fn);
  117.     }
  118.  
  119.     static void Init(VDDelegate& dst, T_Fn2 fn) {
  120.         dst.mpCallback = Fn2;
  121.         dst.mpFnM = reinterpret_cast<void(VDDelegateHolderM::*)()>(fn2);
  122.     }
  123.  
  124.     static void Fn(void *src, const void *info, VDDelegate& del) {
  125.         return (((T *)del.mpObj)->*reinterpret_cast<T_Fn>(del.mpFnM))(static_cast<Source *>(src), *static_cast<const ArgType *>(info));
  126.     }
  127.  
  128.     static void Fn2(void *src, const void *info, VDDelegate& del) {
  129.         return (((T *)del.mpObj)->*reinterpret_cast<T_Fn2>(del.mpFnM))(static_cast<Source *>(src), *static_cast<const ArgType *>(info));
  130.     }
  131. };
  132.  
  133.  
  134. template<>
  135. class VDDelegateAdapter<sizeof(void (VDDelegateHolderM::*)())> {
  136. public:
  137.     template<class T, class Source, class ArgType>
  138.     struct AdapterLookup {
  139.         typedef VDDelegateAdapterM<T, Source, ArgType> result;
  140.     };
  141. };
  142. #endif
  143.  
  144. class VDDelegate : public VDDelegateNode {
  145.     friend class VDEventBase;
  146. public:
  147.     VDDelegate();
  148.     ~VDDelegate();
  149.  
  150.     template<class T, class Source, class ArgType>
  151.     VDDelegateBinding<Source, ArgType> operator()(T *obj, void (T::*fn)(Source *, const ArgType&)) {
  152.         mpObj = obj;
  153.  
  154.         VDDelegateAdapter<sizeof fn>::AdapterLookup<T, Source, ArgType>::result::Init(*this, fn);
  155.  
  156.         VDDelegateBinding<Source, ArgType> binding = {this};
  157.         return binding;
  158.     }
  159.  
  160.     template<class T, class Source, class ArgType>
  161.     VDDelegateBinding<Source, ArgType> Bind(T *obj, void (T::*fn)(Source *, ArgType)) {
  162.         mpObj = obj;
  163.  
  164.         VDDelegateAdapter<sizeof fn>::AdapterLookup<T, Source, ArgType>::result::Init(*this, fn);
  165.  
  166.         VDDelegateBinding<Source, ArgType> binding = {this};
  167.         return binding;
  168.     }
  169.  
  170. public:
  171.     void (*mpCallback)(void *src, const void *info, VDDelegate&);
  172.     void *mpObj;
  173.  
  174. #ifdef _MSC_VER
  175.     union {
  176.         void (VDDelegateHolderS::*mpFnS)();
  177.         void (VDDelegateHolderM::*mpFnM)();
  178.     };
  179. #else
  180.     class VDDelegateHolderS;
  181.     void (VDDelegateHolderS::*mpFnS)();
  182. #endif
  183. };
  184.  
  185. template<class Source, class ArgType>
  186. class VDEvent : public VDEventBase {
  187. public:
  188.     void operator+=(const VDDelegateBinding<Source, ArgType>& binding) {
  189.         Add(*binding.mpBoundDelegate);
  190.     }
  191.  
  192.     void operator-=(const VDDelegateBinding<Source, ArgType>& binding) {
  193.         Remove(*binding.mpBoundDelegate);
  194.     }
  195.  
  196.     void Raise(Source *src, const ArgType& args) {
  197.         VDEventBase::Raise(src, &args);
  198.     }
  199. };
  200.  
  201. #endif
  202.