callback.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /**
  2. * Tencent is pleased to support the open source community by making Tars available.
  3. *
  4. * Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
  5. *
  6. * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
  7. * in compliance with the License. You may obtain a copy of the License at
  8. *
  9. * https://opensource.org/licenses/BSD-3-Clause
  10. *
  11. * Unless required by applicable law or agreed to in writing, software distributed
  12. * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  13. * CONDITIONS OF ANY KIND, either express or implied. See the License for the
  14. * specific language governing permissions and limitations under the License.
  15. */
  16. #ifndef _TARS_CALL_BACK_H_
  17. #define _TARS_CALL_BACK_H_
  18. #include <memory>
  19. #include "promise/bind_internal.h"
  20. namespace tars {
  21. namespace cb {
  22. // class CallbackBase
  23. class CallbackBase {
  24. public:
  25. bool isNull() const { return m_bindState.get() == nullptr; }
  26. void reset() { m_bindState = nullptr, m_function = nullptr; }
  27. virtual ~CallbackBase() {}
  28. explicit operator bool () const
  29. {
  30. return !isNull();
  31. }
  32. protected:
  33. using InvokeFunctionStorage = void(*)();
  34. bool equals(const CallbackBase& other) const
  35. {
  36. return m_bindState.get() == other.m_bindState.get()
  37. && m_function == other.m_function;
  38. }
  39. explicit CallbackBase(bind::BindStateBase* bindState)
  40. : m_bindState(bindState)
  41. , m_function(nullptr)
  42. {
  43. }
  44. CallbackBase(const CallbackBase& o)
  45. : m_bindState(o.m_bindState)
  46. , m_function(o.m_function)
  47. {
  48. }
  49. CallbackBase(CallbackBase&& o)
  50. : m_bindState(std::move(o.m_bindState))
  51. , m_function(o.m_function)
  52. {
  53. o.m_function = nullptr;
  54. }
  55. // bind state with specific parameter.
  56. std::shared_ptr<bind::BindStateBase> m_bindState;
  57. // pointer to function address.
  58. InvokeFunctionStorage m_function;
  59. };
  60. } // end namespace cb
  61. template <typename T>
  62. class Callback;
  63. template <typename R, typename... Args>
  64. class Callback<R(Args...)> : public cb::CallbackBase {
  65. typedef R(*PolymorphicInvoke)(bind::BindStateBase*, typename bind::ParamTraits<Args>::ForwardType...);
  66. public:
  67. typedef R RunType(Args...);
  68. Callback()
  69. : cb::CallbackBase(nullptr)
  70. {
  71. }
  72. template <typename Runnable, typename BindRunType, typename... BoundArgsType>
  73. Callback(bind::BindState<Runnable, BindRunType, BoundArgsType...>* bindState)
  74. : cb::CallbackBase(bindState)
  75. {
  76. PolymorphicInvoke f = &bind::BindState<Runnable, BindRunType, BoundArgsType...>::InvokerType::run;
  77. m_function = reinterpret_cast<InvokeFunctionStorage>(f);
  78. }
  79. bool equals(const Callback& other) const
  80. {
  81. return CallbackBase::equals(other);
  82. }
  83. R run(typename bind::ParamTraits<Args>::ForwardType... args) const
  84. {
  85. PolymorphicInvoke f = reinterpret_cast<PolymorphicInvoke>(m_function);
  86. return f(m_bindState.get(), bind::ParamForward(args)...);
  87. }
  88. };
  89. // Syntactic sugar to make Callback<void()> easier to declare since it
  90. // will be used in a lot of APIs with delayed execution.
  91. using Closure = Callback<void()>;
  92. } // end namespace tars
  93. #endif