CallbackTest_02.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. /* printf example */
  2. #include <stdio.h>
  3. #include <cstdio>
  4. #include <iostream>
  5. #include <functional> // std::function
  6. #include <stdint.h> // uint64_t
  7. #include <unordered_map> // std::unordered_map
  8. #include <utility> // std::move
  9. #include <vector> // std::vector
  10. using namespace std;
  11. #if 1
  12. //
  13. // https://manderc.com/types/functionpointertype/index.php
  14. //
  15. void globalfunction(void * pthis, int i) {
  16. printf("Global globalfunction (%i)\n", i);
  17. }
  18. static void staticglobalfunction(void * pthis,int i) {
  19. printf("Static Global (%i)\n", i);
  20. }
  21. namespace Name_Space {
  22. void namespacefunc(void * pthis, int i) {
  23. printf("Namespace (%i)\n", i);
  24. }
  25. }
  26. #if 0
  27. void (*returnfunction(const char* str))(int) {
  28. printf("Return \"%s\":\n", str);
  29. return &globalfunction;
  30. }
  31. #endif
  32. class ExternClass {
  33. public:
  34. void externClassfunction(void * pthis, int i) {
  35. printf("externClassfunction (%i)\n", i);
  36. }
  37. static void staticExternClassfunction(void * pthis, int i) {
  38. printf("staticExternClassfunction (%i)\n", i);
  39. }
  40. };
  41. class Test {
  42. private:
  43. void (*funcptr1)(void*, int i) = &globalfunction;
  44. unsigned int myTestVar = 10;
  45. public:
  46. void (*funcptr2)(void* pthis, int i) = nullptr;
  47. void (*funcptr3)(void* pthis, int i) = nullptr;
  48. void (*funcptr4)(void* pthis, int i) = nullptr;
  49. void (Test::* funcptr5)(int i);
  50. void classfunction(int i) {
  51. printf("Test Class local classfunction (%i)\n", i);
  52. }
  53. void callglobal(int i) {
  54. funcptr1 = &globalfunction;
  55. }
  56. void callclass(int i) {
  57. funcptr5 = &Test::classfunction;
  58. }
  59. void run(int i) {
  60. (*funcptr1)(this, i);
  61. (*funcptr2)(this, i);
  62. (*funcptr3)(this, i);
  63. (*funcptr4)(this, i);
  64. // (this->*funcptr5)(this, i);
  65. }
  66. };
  67. int main() {
  68. Test test;
  69. ExternClass extClass;
  70. // Global function with class-function-ptr outside class
  71. test.funcptr2 = &globalfunction;
  72. // Function in namespace with local function pointer
  73. test.funcptr3 = &Name_Space::namespacefunc;
  74. // Class function with class-function-ptr outside class
  75. test.funcptr4 = &ExternClass::staticExternClassfunction;
  76. // Class function with class-function-ptr outside class
  77. test.funcptr5 = &Test::classfunction;
  78. // Class function with local function-ptr
  79. void (Test:: * classfunc)(int i) = &Test::classfunction;
  80. test.run(10);
  81. // (*returnfunction("global"))(10);
  82. // printf("Using typedef:\n");
  83. #if 0
  84. typedef void (*functiontype)(int);
  85. functiontype typefuncptr = &globalfunction;
  86. (*typefuncptr)(11);
  87. #endif
  88. return 0;
  89. }
  90. #endif
  91. #if 0
  92. template<typename R, typename P1, typename P2>
  93. class Callback
  94. {
  95. public:
  96. typedef R(*FuncType)(void*, P1, P2);
  97. Callback() : func(0), obj(0) {}
  98. Callback(FuncType f, void* o) : func(f), obj(o) {}
  99. R operator()(P1 a1, P2 a2)
  100. {
  101. return (*func)(obj, a1, a2);
  102. }
  103. private:
  104. FuncType func;
  105. void* obj;
  106. };
  107. template<typename R, class T, typename P1, typename P2, R(T::* Func)(P1, P2)>
  108. R Wrapper(void* o, P1 a1, P2 a2)
  109. {
  110. return (static_cast<T*>(o)->*Func)(a1, a2);
  111. }
  112. class Foo
  113. {
  114. public:
  115. float Average(int n1, int n2)
  116. {
  117. return (n1 + n2) / 2.0f;
  118. }
  119. };
  120. float Calculate(int n1, int n2, Callback<float, int, int> callback)
  121. {
  122. return callback(n1, n2);
  123. }
  124. int main()
  125. {
  126. Foo f;
  127. Callback<float, int, int> cb
  128. (&Wrapper<float, Foo, int, int, &Foo::Average>, &f);
  129. float result = Calculate(50, 100, cb);
  130. // result == 75.0f
  131. return 0;
  132. }
  133. #endif
  134. #if 0
  135. namespace my
  136. {
  137. using Callback = function<void()>;
  138. template< class Key, class Value > using Map_ = unordered_map<Key, Value>;
  139. class Subject
  140. {
  141. public:
  142. enum Id : uint64_t {};
  143. private:
  144. Map_<uint64_t, Callback> m_callbacks;
  145. static auto id_value()
  146. -> uint64_t&
  147. {
  148. static uint64_t the_id;
  149. return the_id;
  150. }
  151. public:
  152. auto add_listener(Callback cb)
  153. -> Id
  154. {
  155. const auto id = Id(++id_value());
  156. m_callbacks.emplace(id, move(cb));
  157. return id;
  158. }
  159. auto remove_listener(const Id id)
  160. -> bool
  161. {
  162. const auto it = m_callbacks.find(id);
  163. if (it == m_callbacks.end())
  164. {
  165. return false;
  166. }
  167. m_callbacks.erase(it);
  168. return true;
  169. }
  170. void notify_all() const
  171. {
  172. for (const auto& pair : m_callbacks)
  173. {
  174. pair.second();
  175. }
  176. }
  177. };
  178. }
  179. struct Observer_1
  180. {
  181. void notify() { cout << "Observer_1::notify() called." << endl; }
  182. };
  183. struct Observer_2
  184. {
  185. void notify() { cout << "Observer_2::notify() called." << endl; }
  186. };
  187. auto main()
  188. -> int
  189. {
  190. my::Subject subject;
  191. Observer_1 one;
  192. Observer_2 two;
  193. using Id = my::Subject::Id;
  194. const Id listener_id_1 = subject.add_listener([&] { one.notify(); });
  195. const Id listener_id_2 = subject.add_listener([&] { two.notify(); });
  196. cout << "After adding two listeners:" << endl;
  197. subject.notify_all();
  198. cout << endl;
  199. subject.remove_listener(listener_id_1)
  200. and (cout << "Removed listener 1." << endl)
  201. or (cout << "Did not find registration of listener 1." << endl);
  202. cout << endl;
  203. cout << "After removing or attempting to remove listener 1:" << endl;
  204. subject.notify_all();
  205. }
  206. #endif
  207. #if 0
  208. class A
  209. {
  210. public:
  211. std::function<void(int, const std::string&)> m_CbFunc = nullptr;
  212. void foo()
  213. {
  214. if (m_CbFunc)
  215. {
  216. m_CbFunc(100, "event fired");
  217. }
  218. }
  219. };
  220. class B
  221. {
  222. public:
  223. unsigned int TestVariable = 10;
  224. B()
  225. {
  226. auto aFunc = std::bind(&B::eventHandler, this, std::placeholders::_1, std::placeholders::_2);
  227. anObjA.m_CbFunc = aFunc;
  228. }
  229. void eventHandler(int i, const std::string& s)
  230. {
  231. std::cout << s << ": " << i << std::endl;
  232. }
  233. void DoSomethingOnA()
  234. {
  235. anObjA.foo();
  236. }
  237. A anObjA;
  238. };
  239. int main(int argc, char* argv[])
  240. {
  241. B anObjB;
  242. anObjB.DoSomethingOnA();
  243. }
  244. #endif