Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

203 lines
5.4 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #ifndef CALLQUEUE_H
  7. #define CALLQUEUE_H
  8. #include "tier0/tslist.h"
  9. #include "functors.h"
  10. #if defined( _WIN32 )
  11. #pragma once
  12. #endif
  13. //-----------------------------------------------------
  14. // Avert thy eyes! Imagine rather:
  15. //
  16. // void QueueCall( <function>, [args1, [arg2,]...]
  17. // void QueueCall( <object>, <function>, [args1, [arg2,]...]
  18. // void QueueRefCall( <object>, <<function>, [args1, [arg2,]...]
  19. //-----------------------------------------------------
  20. #define DEFINE_CALLQUEUE_NONMEMBER_QUEUE_CALL(N) \
  21. template <typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N FUNC_TEMPLATE_ARG_PARAMS_##N> \
  22. void QueueCall(FUNCTION_RETTYPE (*pfnProxied)( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) FUNC_ARG_FORMAL_PARAMS_##N ) \
  23. { \
  24. QueueFunctorInternal( CreateFunctor( pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N ) ); \
  25. }
  26. //-------------------------------------
  27. #define DEFINE_CALLQUEUE_MEMBER_QUEUE_CALL(N) \
  28. template <typename OBJECT_TYPE_PTR, typename FUNCTION_CLASS, typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N FUNC_TEMPLATE_ARG_PARAMS_##N> \
  29. void QueueCall(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) FUNC_ARG_FORMAL_PARAMS_##N ) \
  30. { \
  31. QueueFunctorInternal( CreateFunctor( pObject, pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N ) ); \
  32. }
  33. //-------------------------------------
  34. #define DEFINE_CALLQUEUE_CONST_MEMBER_QUEUE_CALL(N) \
  35. template <typename OBJECT_TYPE_PTR, typename FUNCTION_CLASS, typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N FUNC_TEMPLATE_ARG_PARAMS_##N> \
  36. void QueueCall(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) const FUNC_ARG_FORMAL_PARAMS_##N ) \
  37. { \
  38. QueueFunctorInternal( CreateFunctor( pObject, pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N ) ); \
  39. }
  40. //-------------------------------------
  41. #define DEFINE_CALLQUEUE_REF_COUNTING_MEMBER_QUEUE_CALL(N) \
  42. template <typename OBJECT_TYPE_PTR, typename FUNCTION_CLASS, typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N FUNC_TEMPLATE_ARG_PARAMS_##N> \
  43. void QueueRefCall(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) FUNC_ARG_FORMAL_PARAMS_##N ) \
  44. { \
  45. QueueFunctorInternal( CreateRefCountingFunctor( pObject, pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N ) ); \
  46. }
  47. //-------------------------------------
  48. #define DEFINE_CALLQUEUE_REF_COUNTING_CONST_MEMBER_QUEUE_CALL(N) \
  49. template <typename OBJECT_TYPE_PTR, typename FUNCTION_CLASS, typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N FUNC_TEMPLATE_ARG_PARAMS_##N> \
  50. void QueueRefCall(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) const FUNC_ARG_FORMAL_PARAMS_##N ) \
  51. { \
  52. QueueFunctorInternal( CreateRefCountingFunctor( pObject, pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N ) ); \
  53. \
  54. }
  55. #define FUNC_GENERATE_QUEUE_METHODS() \
  56. FUNC_GENERATE_ALL( DEFINE_CALLQUEUE_NONMEMBER_QUEUE_CALL ); \
  57. FUNC_GENERATE_ALL( DEFINE_CALLQUEUE_MEMBER_QUEUE_CALL ); \
  58. FUNC_GENERATE_ALL( DEFINE_CALLQUEUE_CONST_MEMBER_QUEUE_CALL );\
  59. FUNC_GENERATE_ALL( DEFINE_CALLQUEUE_REF_COUNTING_MEMBER_QUEUE_CALL ); \
  60. FUNC_GENERATE_ALL( DEFINE_CALLQUEUE_REF_COUNTING_CONST_MEMBER_QUEUE_CALL )
  61. //-----------------------------------------------------
  62. template <typename QUEUE_TYPE = CTSQueue<CFunctor *> >
  63. class CCallQueueT
  64. {
  65. public:
  66. CCallQueueT()
  67. : m_bNoQueue( false )
  68. {
  69. #ifdef _DEBUG
  70. m_nCurSerialNumber = 0;
  71. m_nBreakSerialNumber = (unsigned)-1;
  72. #endif
  73. }
  74. void DisableQueue( bool bDisable )
  75. {
  76. if ( m_bNoQueue == bDisable )
  77. {
  78. return;
  79. }
  80. if ( !m_bNoQueue )
  81. CallQueued();
  82. m_bNoQueue = bDisable;
  83. }
  84. bool IsDisabled() const
  85. {
  86. return m_bNoQueue;
  87. }
  88. int Count()
  89. {
  90. return m_queue.Count();
  91. }
  92. void CallQueued()
  93. {
  94. if ( !m_queue.Count() )
  95. {
  96. return;
  97. }
  98. m_queue.PushItem( NULL );
  99. CFunctor *pFunctor;
  100. while ( m_queue.PopItem( &pFunctor ) && pFunctor != NULL )
  101. {
  102. #ifdef _DEBUG
  103. if ( pFunctor->m_nUserID == m_nBreakSerialNumber)
  104. {
  105. m_nBreakSerialNumber = (unsigned)-1;
  106. }
  107. #endif
  108. (*pFunctor)();
  109. pFunctor->Release();
  110. }
  111. }
  112. void QueueFunctor( CFunctor *pFunctor )
  113. {
  114. Assert( pFunctor );
  115. QueueFunctorInternal( RetAddRef( pFunctor ) );
  116. }
  117. void Flush()
  118. {
  119. m_queue.PushItem( NULL );
  120. CFunctor *pFunctor;
  121. while ( m_queue.PopItem( &pFunctor ) && pFunctor != NULL )
  122. {
  123. pFunctor->Release();
  124. }
  125. }
  126. FUNC_GENERATE_QUEUE_METHODS();
  127. private:
  128. void QueueFunctorInternal( CFunctor *pFunctor )
  129. {
  130. if ( !m_bNoQueue )
  131. {
  132. #ifdef _DEBUG
  133. pFunctor->m_nUserID = m_nCurSerialNumber++;
  134. #endif
  135. m_queue.PushItem( pFunctor );
  136. }
  137. else
  138. {
  139. (*pFunctor)();
  140. pFunctor->Release();
  141. }
  142. }
  143. QUEUE_TYPE m_queue;
  144. bool m_bNoQueue;
  145. unsigned m_nCurSerialNumber;
  146. unsigned m_nBreakSerialNumber;
  147. };
  148. class CCallQueue : public CCallQueueT<>
  149. {
  150. };
  151. //-----------------------------------------------------
  152. // Optional interface that can be bound to concrete CCallQueue
  153. //-----------------------------------------------------
  154. class ICallQueue
  155. {
  156. public:
  157. void QueueFunctor( CFunctor *pFunctor )
  158. {
  159. QueueFunctorInternal( RetAddRef( pFunctor ) );
  160. }
  161. FUNC_GENERATE_QUEUE_METHODS();
  162. private:
  163. virtual void QueueFunctorInternal( CFunctor *pFunctor ) = 0;
  164. };
  165. #endif // CALLQUEUE_H