Deferrer.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  1. #pragma once
  2. // интерфейс отложенных вызовов
  3. template <typename O>
  4. class IDeferrer
  5. {
  6. public:
  7. virtual ~IDeferrer() {}
  8. virtual void Call(O*) = null;
  9. virtual void Trace(string & str) {};
  10. public:
  11. };
  12. // хелпер шаблон выбора одного из двух типов на основе логического
  13. // значения вычисляемого на этапе компиляции
  14. template<typename T, typename U, bool C> struct type_select
  15. {
  16. typedef T result;
  17. };
  18. template<typename T, typename U> struct type_select<T,U,false>
  19. {
  20. typedef U result;
  21. };
  22. // хелпер-шаблон для определения является ли параметр шаблона абстрактным типом
  23. template<typename T>
  24. struct is_abstract
  25. {
  26. private:
  27. struct yes_type { char c; };
  28. struct no_type { char c[2]; };
  29. template<class U>
  30. static no_type check_sig(U (*)[1]);
  31. template<class U>
  32. static yes_type check_sig(...);
  33. static const unsigned int s1 = sizeof(check_sig<T>(0));
  34. public:
  35. static const bool result = (s1 == sizeof(yes_type));
  36. };
  37. // хелпер-шаблон для пробразования ссылки в чистый тип
  38. // если это можно (нельзя например ссылки на абстрактный тип, ссылки на array<> )
  39. template <typename T>
  40. struct remove_ref_if_can
  41. {
  42. typedef T result;
  43. };
  44. template <typename T>
  45. struct remove_ref_if_can<T&>
  46. {
  47. typedef typename type_select<T&, T, is_abstract<T>::result>::result result;
  48. };
  49. // специальные случаи (исключения из правил) - когда нельзя сохранять типы по значению (либо дорого, либо просто нельзя)
  50. //////////////////////////////////////////////////////////////////////////
  51. template <>
  52. struct remove_ref_if_can<const array<unsigned int>&>
  53. {
  54. typedef const array<unsigned int>& result;
  55. };
  56. template <>
  57. struct remove_ref_if_can<array<byte>&>
  58. {
  59. typedef array<byte>& result;
  60. };
  61. //////////////////////////////////////////////////////////////////////////
  62. // хелпер-шаблон для преобразования указателя в чистый тип,
  63. template <typename T>
  64. struct remove_pointer
  65. {
  66. typedef T result;
  67. };
  68. template <typename T>
  69. struct remove_pointer<T*>
  70. {
  71. typedef T result;
  72. };
  73. // хелпер-шаблон для преобразования указателя в чистый тип,
  74. // если можно ( нельзя например указатель на абстрактный тип, нельзя const char* и т.п.)
  75. template <typename T>
  76. struct remove_ptr_if_can
  77. {
  78. typedef T result;
  79. };
  80. template <typename T>
  81. struct remove_ptr_if_can<T*>
  82. {
  83. typedef typename type_select<T*, T, is_abstract<T>::result>::result result;
  84. };
  85. // шаблон-конвертатор ссылки в указатель
  86. template<typename Source, typename Target>
  87. struct value_to_pointer
  88. {
  89. static Target convert(Source & src) { return src; }
  90. };
  91. template<typename Source, typename Target>
  92. struct value_to_pointer<Source, Target*>
  93. {
  94. static Target* convert(Source & src) { return &src; }
  95. };
  96. template<typename Source, typename Target>
  97. struct value_to_pointer<Source&, Target&>
  98. {
  99. static Target& convert(Source& src) { return src; }
  100. };
  101. template<typename Source, typename Target>
  102. struct value_to_pointer<Source*, Target*>
  103. {
  104. static Target* convert(Source* src) { return src; }
  105. };
  106. // шаблон для преобразования указателя в ссылку если это не абстрактный тип
  107. // схема работы
  108. // 1. это если тип Source не указатель - соотв. тогда он не конвертируется
  109. template<typename Source>
  110. struct pointer_to_value
  111. {
  112. static Source& convert(Source& src) { return src; }
  113. };
  114. // 2. это если тип Source - ссылка - нужно для того чтобы не создавались ссылки
  115. // на ссылки, которые запрещены в языке
  116. template<typename Source>
  117. struct pointer_to_value<Source&>
  118. {
  119. static Source& convert(Source& src) { return src; }
  120. };
  121. // 3. это самый сложный случай. если Source указатель и если это не указатель
  122. // на абстрактный класс (который как известно по значению нельзя использовать)
  123. // то разыменовываем указатель, если класс абстрактный - то оставляем его указателем
  124. template<typename Source>
  125. struct pointer_to_value<Source*>
  126. {
  127. // константа времени компиляции - определеяет требуется конвертирование типа или нет
  128. static const bool needConvert = is_abstract<remove_pointer<Source>::result>::result;
  129. // тип возвращаемый функций pointer_to_value::convert()
  130. // (либо указатель, либо ссылка в зависимости от значения needConvert)
  131. typedef typename type_select<Source*, Source&, needConvert>::result ReturnType;
  132. // хелперный класс - общий вид - случай когда надо конвертировать
  133. template <typename U, bool doNotConvert>
  134. struct convert_helper
  135. {
  136. static ReturnType convert(U src) { return *src; }
  137. };
  138. // хелперный класс - специализация для случая когда не надо конвертировать
  139. template <typename U>
  140. struct convert_helper<U, true>
  141. {
  142. static ReturnType convert(U src) { return src; }
  143. };
  144. // функция-конвертор
  145. static ReturnType convert(Source* src)
  146. {
  147. return convert_helper<Source*, needConvert>::convert(src);
  148. }
  149. };
  150. // шаблон класса отложенного вызова для функции без аргументов
  151. template <typename O, typename R>
  152. class Deferrer0 : public IDeferrer<O>
  153. {
  154. public:
  155. typedef R (O::*FuncType)();
  156. Deferrer0(const char * funcName, FuncType func) :
  157. m_funcName(funcName),
  158. m_func(func) {}
  159. virtual void Call(O* obj)
  160. {
  161. (obj->*m_func)();
  162. }
  163. virtual void Trace(string & str)
  164. {
  165. str += m_funcName; str += "();";
  166. }
  167. private:
  168. FuncType m_func;
  169. const char * m_funcName;
  170. };
  171. #ifndef STOP_DEBUG
  172. void DeferrerTrace(string & str, dword value);
  173. void DeferrerTrace(string & str, long value);
  174. void DeferrerTrace(string & str, int value);
  175. void DeferrerTrace(string & str, unsigned int value);
  176. void DeferrerTrace(string & str, float value);
  177. void DeferrerTrace(string & str, const Vector & value);
  178. void DeferrerTrace(string & str, const Matrix & value);
  179. void DeferrerTrace(string & str, const Vector4 & value);
  180. void DeferrerTrace(string & str, bool value);
  181. void DeferrerTrace(string & str, const Plane & value);
  182. void DeferrerTrace(string & str, PhysicsCollisionGroup value);
  183. void DeferrerTrace(string & str, IPhysMaterial * material);
  184. void DeferrerTrace(string & str, IAnimation * animation);
  185. void DeferrerTrace(string & str, IPhysRigidBody & body);
  186. #endif
  187. // шаблон класса отложенного вызова для функции с 1-м аргументом
  188. template <typename O, typename R, typename P1>
  189. class Deferrer1 : public IDeferrer<O>
  190. {
  191. public:
  192. typedef R (O::*FuncType)(P1);
  193. Deferrer1(const char * funcName, FuncType func, P1 par1 ) :
  194. m_funcName(funcName),
  195. m_func(func),
  196. m_param1(pointer_to_value<P1>::convert(par1)) {}
  197. virtual void Call(O* obj)
  198. {
  199. (obj->*m_func)(value_to_pointer<INNER_P1, P1>::convert(m_param1));
  200. }
  201. #ifndef STOP_DEBUG
  202. virtual void Trace(string & str)
  203. {
  204. str += m_funcName; str += "(";
  205. DeferrerTrace(str, m_param1);
  206. str += ");";
  207. }
  208. #endif
  209. private:
  210. FuncType m_func;
  211. const char * m_funcName;
  212. typedef typename remove_ptr_if_can<typename remove_ref_if_can<P1>::result>::result INNER_P1;
  213. INNER_P1 m_param1;
  214. };
  215. // шаблон класса отложенного вызова для функции с 2-мя аргументами
  216. template <typename O, typename R, typename P1, typename P2>
  217. class Deferrer2 : public IDeferrer<O>
  218. {
  219. public:
  220. typedef R (O::*FuncType)(P1, P2);
  221. Deferrer2(const char * funcName, FuncType func, P1 par1, P2 par2) :
  222. m_funcName(funcName),
  223. m_func(func),
  224. m_param1(pointer_to_value<P1>::convert(par1)),
  225. m_param2(pointer_to_value<P2>::convert(par2)) {}
  226. virtual void Call(O* obj)
  227. {
  228. (obj->*m_func)( value_to_pointer<INNER_P1, P1>::convert(m_param1),
  229. value_to_pointer<INNER_P2, P2>::convert(m_param2));
  230. }
  231. #ifndef STOP_DEBUG
  232. virtual void Trace(string & str)
  233. {
  234. str += m_funcName; str += "(";
  235. DeferrerTrace(str, m_param1); str += ", ";
  236. DeferrerTrace(str, m_param2);
  237. str += ");";
  238. }
  239. #endif
  240. private:
  241. FuncType m_func;
  242. const char * m_funcName;
  243. typedef typename remove_ptr_if_can<typename remove_ref_if_can<P1>::result>::result INNER_P1;
  244. typedef typename remove_ptr_if_can<typename remove_ref_if_can<P2>::result>::result INNER_P2;
  245. INNER_P1 m_param1;
  246. INNER_P2 m_param2;
  247. };
  248. // шаблон класса отложенного вызова для функции с 3-мя аргументами
  249. template <typename O, typename R, typename P1, typename P2, typename P3>
  250. class Deferrer3 : public IDeferrer<O>
  251. {
  252. public:
  253. typedef R (O::*FuncType)(P1, P2, P3);
  254. Deferrer3(const char * funcName, FuncType func, P1 par1, P2 par2, P3 par3) :
  255. m_funcName(funcName),
  256. m_func(func),
  257. m_param1(pointer_to_value<P1>::convert(par1)),
  258. m_param2(pointer_to_value<P2>::convert(par2)),
  259. m_param3(pointer_to_value<P3>::convert(par3)) {}
  260. virtual void Call(O* obj)
  261. {
  262. (obj->*m_func)( value_to_pointer<INNER_P1, P1>::convert(m_param1),
  263. value_to_pointer<INNER_P2, P2>::convert(m_param2),
  264. value_to_pointer<INNER_P3, P3>::convert(m_param3));
  265. }
  266. #ifndef STOP_DEBUG
  267. virtual void Trace(string & str)
  268. {
  269. str += m_funcName; str += "(";
  270. DeferrerTrace(str, m_param1); str += ", ";
  271. DeferrerTrace(str, m_param2); str += ", ";
  272. DeferrerTrace(str, m_param3);
  273. str += ");";
  274. }
  275. #endif
  276. private:
  277. FuncType m_func;
  278. const char * m_funcName;
  279. typedef typename remove_ptr_if_can<typename remove_ref_if_can<P1>::result>::result INNER_P1;
  280. typedef typename remove_ptr_if_can<typename remove_ref_if_can<P2>::result>::result INNER_P2;
  281. typedef typename remove_ptr_if_can<typename remove_ref_if_can<P3>::result>::result INNER_P3;
  282. INNER_P1 m_param1;
  283. INNER_P2 m_param2;
  284. INNER_P3 m_param3;
  285. };
  286. // шаблон класса отложенного вызова для функции с 4-мя аргументами
  287. template <typename O, typename R, typename P1, typename P2, typename P3, typename P4>
  288. class Deferrer4 : public IDeferrer<O>
  289. {
  290. public:
  291. typedef R (O::*FuncType)(P1, P2, P3, P4);
  292. Deferrer4(const char * funcName, FuncType func, P1 par1, P2 par2, P3 par3, P4 par4) :
  293. m_funcName(funcName),
  294. m_func(func),
  295. m_param1(pointer_to_value<P1>::convert(par1)),
  296. m_param2(pointer_to_value<P2>::convert(par2)),
  297. m_param3(pointer_to_value<P3>::convert(par3)),
  298. m_param4(pointer_to_value<P4>::convert(par4)) {}
  299. virtual void Call(O* obj)
  300. {
  301. (obj->*m_func)( value_to_pointer<INNER_P1, P1>::convert(m_param1),
  302. value_to_pointer<INNER_P2, P2>::convert(m_param2),
  303. value_to_pointer<INNER_P3, P3>::convert(m_param3),
  304. value_to_pointer<INNER_P4, P4>::convert(m_param4));
  305. }
  306. #ifndef STOP_DEBUG
  307. virtual void Trace(string & str)
  308. {
  309. str += m_funcName; str += "(";
  310. DeferrerTrace(str, m_param1); str += ", ";
  311. DeferrerTrace(str, m_param2); str += ", ";
  312. DeferrerTrace(str, m_param3); str += ", ";
  313. DeferrerTrace(str, m_param4);
  314. str += ");";
  315. }
  316. #endif
  317. private:
  318. FuncType m_func;
  319. const char * m_funcName;
  320. typedef typename remove_ptr_if_can<typename remove_ref_if_can<P1>::result>::result INNER_P1;
  321. typedef typename remove_ptr_if_can<typename remove_ref_if_can<P2>::result>::result INNER_P2;
  322. typedef typename remove_ptr_if_can<typename remove_ref_if_can<P3>::result>::result INNER_P3;
  323. typedef typename remove_ptr_if_can<typename remove_ref_if_can<P4>::result>::result INNER_P4;
  324. INNER_P1 m_param1;
  325. INNER_P2 m_param2;
  326. INNER_P3 m_param3;
  327. INNER_P4 m_param4;
  328. };
  329. // шаблон класса отложенного вызова для функции с 5-ю аргументами
  330. template <typename O, typename R, typename P1, typename P2, typename P3, typename P4, typename P5>
  331. class Deferrer5 : public IDeferrer<O>
  332. {
  333. public:
  334. typedef R (O::*FuncType)(P1, P2, P3, P4, P5);
  335. Deferrer5(const char * funcName, FuncType func, P1 par1, P2 par2, P3 par3, P4 par4, P5 par5) :
  336. m_funcName(funcName),
  337. m_func(func),
  338. m_param1(pointer_to_value<P1>::convert(par1)),
  339. m_param2(pointer_to_value<P2>::convert(par2)),
  340. m_param3(pointer_to_value<P3>::convert(par3)),
  341. m_param4(pointer_to_value<P4>::convert(par4)),
  342. m_param5(pointer_to_value<P5>::convert(par5)) {}
  343. virtual void Call(O* obj)
  344. {
  345. (obj->*m_func)( value_to_pointer<INNER_P1, P1>::convert(m_param1),
  346. value_to_pointer<INNER_P2, P2>::convert(m_param2),
  347. value_to_pointer<INNER_P3, P3>::convert(m_param3),
  348. value_to_pointer<INNER_P4, P4>::convert(m_param4),
  349. value_to_pointer<INNER_P5, P5>::convert(m_param5));
  350. }
  351. #ifndef STOP_DEBUG
  352. virtual void Trace(string & str)
  353. {
  354. str += m_funcName; str += "(";
  355. DeferrerTrace(str, m_param1); str += ", ";
  356. DeferrerTrace(str, m_param2); str += ", ";
  357. DeferrerTrace(str, m_param3); str += ", ";
  358. DeferrerTrace(str, m_param4); str += ", ";
  359. DeferrerTrace(str, m_param5);
  360. str += ");";
  361. }
  362. #endif
  363. private:
  364. FuncType m_func;
  365. const char * m_funcName;
  366. typedef typename remove_ptr_if_can<typename remove_ref_if_can<P1>::result>::result INNER_P1;
  367. typedef typename remove_ptr_if_can<typename remove_ref_if_can<P2>::result>::result INNER_P2;
  368. typedef typename remove_ptr_if_can<typename remove_ref_if_can<P3>::result>::result INNER_P3;
  369. typedef typename remove_ptr_if_can<typename remove_ref_if_can<P4>::result>::result INNER_P4;
  370. typedef typename remove_ptr_if_can<typename remove_ref_if_can<P5>::result>::result INNER_P5;
  371. INNER_P1 m_param1;
  372. INNER_P2 m_param2;
  373. INNER_P3 m_param3;
  374. INNER_P4 m_param4;
  375. INNER_P5 m_param5;
  376. };
  377. // шаблон класса отложенного вызова для функции с 6-ю аргументами
  378. template <typename O, typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
  379. class Deferrer6 : public IDeferrer<O>
  380. {
  381. public:
  382. typedef R (O::*FuncType)(P1, P2, P3, P4, P5, P6);
  383. Deferrer6(const char * funcName, FuncType func, P1 par1, P2 par2, P3 par3, P4 par4, P5 par5, P6 par6) :
  384. m_funcName(funcName),
  385. m_func(func),
  386. m_param1(pointer_to_value<P1>::convert(par1)),
  387. m_param2(pointer_to_value<P2>::convert(par2)),
  388. m_param3(pointer_to_value<P3>::convert(par3)),
  389. m_param4(pointer_to_value<P4>::convert(par4)),
  390. m_param5(pointer_to_value<P5>::convert(par5)),
  391. m_param6(pointer_to_value<P6>::convert(par6)){}
  392. virtual void Call(O* obj)
  393. {
  394. (obj->*m_func)( value_to_pointer<INNER_P1, P1>::convert(m_param1),
  395. value_to_pointer<INNER_P2, P2>::convert(m_param2),
  396. value_to_pointer<INNER_P3, P3>::convert(m_param3),
  397. value_to_pointer<INNER_P4, P4>::convert(m_param4),
  398. value_to_pointer<INNER_P5, P5>::convert(m_param5),
  399. value_to_pointer<INNER_P6, P6>::convert(m_param6));
  400. }
  401. #ifndef STOP_DEBUG
  402. virtual void Trace(string & str)
  403. {
  404. str += m_funcName; str += "(";
  405. DeferrerTrace(str, m_param1); str += ", ";
  406. DeferrerTrace(str, m_param2); str += ", ";
  407. DeferrerTrace(str, m_param3); str += ", ";
  408. DeferrerTrace(str, m_param4); str += ", ";
  409. DeferrerTrace(str, m_param5); str += ", ";
  410. DeferrerTrace(str, m_param6);
  411. str += ");";
  412. }
  413. #endif
  414. private:
  415. FuncType m_func;
  416. const char * m_funcName;
  417. typedef typename remove_ptr_if_can<typename remove_ref_if_can<P1>::result>::result INNER_P1;
  418. typedef typename remove_ptr_if_can<typename remove_ref_if_can<P2>::result>::result INNER_P2;
  419. typedef typename remove_ptr_if_can<typename remove_ref_if_can<P3>::result>::result INNER_P3;
  420. typedef typename remove_ptr_if_can<typename remove_ref_if_can<P4>::result>::result INNER_P4;
  421. typedef typename remove_ptr_if_can<typename remove_ref_if_can<P5>::result>::result INNER_P5;
  422. typedef typename remove_ptr_if_can<typename remove_ref_if_can<P6>::result>::result INNER_P6;
  423. INNER_P1 m_param1;
  424. INNER_P2 m_param2;
  425. INNER_P3 m_param3;
  426. INNER_P4 m_param4;
  427. INNER_P5 m_param5;
  428. INNER_P6 m_param6;
  429. };
  430. class MemPool
  431. {
  432. public:
  433. MemPool();
  434. virtual ~MemPool();
  435. void * Alloc(dword size);
  436. void Free(void * ptr);
  437. void Reset();
  438. static MemPool * ptr;
  439. private:
  440. char * buffer;
  441. word * list;
  442. word lastIndex;
  443. dword chunkSize;
  444. dword numBlocks;
  445. };
  446. // переопределенный оператор new для деффереров
  447. inline void * operator new(size_t size, char c1, char c2)
  448. {
  449. return MemPool::ptr->Alloc(dword(size));
  450. //return api->Reallocate(null, dword(size), _FL_);
  451. }
  452. // переопределенный оператор delete для деффереров
  453. inline void operator delete(void * p, char c1, char c2)
  454. {
  455. // сюда не должно попадать
  456. //_asm int 3
  457. Assert(false);
  458. }
  459. #define NEW2 new('a', 'b')
  460. //#define NEW2 NEW
  461. //#define def_delete(X) delete (X)
  462. #ifdef STOP_DEBUG
  463. #define CONSTRUCT_MCALLS m_calls(_FL_)
  464. #define DECLARE_MCALLS(classname) array<IDeferrer<classname>*> m_calls;
  465. #define def_delete(exp) { delete_deferrer(exp); }
  466. #define DELETE_MCALLS { for (long i = 0; i < m_calls; ++i) delete_deferrer(m_calls[i]); m_calls.DelAll(); }
  467. #define TRACE_MCALLS
  468. #define DEF_FREF(__func) null, &__func
  469. #else
  470. #define MAX_MCALLS 16
  471. #define CONSTRUCT_MCALLS m_calls(_FL_), m_copyCalls(_FL_, MAX_MCALLS + 1), m_copyRoller(0)
  472. #define DECLARE_MCALLS(classname) array<IDeferrer<classname>*> m_calls, m_copyCalls; dword m_copyRoller;
  473. #define def_delete(exp) { if (m_copyCalls.Size() < MAX_MCALLS) { m_copyCalls.Add(exp); m_copyRoller = m_copyCalls.Last(); } else { m_copyRoller = (m_copyRoller + 1) % MAX_MCALLS; delete_deferrer(m_copyCalls[m_copyRoller]); m_copyCalls[m_copyRoller] = exp; } }
  474. #define DELETE_MCALLS { for (long i=0; i<m_calls; i++) delete_deferrer(m_calls[i]); m_calls.DelAll(); for (long i=0; i<m_copyCalls; i++) delete_deferrer(m_copyCalls[i]); m_copyCalls.DelAll(); }
  475. #define TRACE_MCALLS { string str; if (m_copyCalls.Len()) { for (dword i=0, idx=0; i<MAX_MCALLS; i++) { dword n = (m_copyRoller + i + 1) % MAX_MCALLS; if (n > m_copyCalls.Last()) continue; str.Empty(); api->Trace("== %d ================================================================", idx); m_copyCalls[n]->Trace(str); api->Trace(str.c_str()); idx++; if (n == m_copyRoller) break; } api->Trace("-- end ----------------------------------------------------------------"); } }
  476. #define DEF_FREF(__func) #__func, &__func
  477. #endif
  478. template<class T> inline void delete_deferrer(T * _T)
  479. {
  480. if (_T)
  481. _T->~T();
  482. MemPool::ptr->Free(_T);
  483. }
  484. // шаблонные функции-хэлперы
  485. template <typename O, typename R>
  486. IDeferrer<O>* MakeDeferrer(const char * funcName, typename Deferrer0<O, R>::FuncType func)
  487. {
  488. // api->Trace("Deferred call object: size = %d", sizeof(Deferrer0<O, F>));
  489. return NEW2 Deferrer0<O, R>(funcName, func);
  490. }
  491. template <typename O, typename R, typename P1>
  492. IDeferrer<O>* MakeDeferrer(const char * funcName, typename Deferrer1<O, R, P1>::FuncType func, P1 param1)
  493. {
  494. // api->Trace("Deferred call object: size = %d", sizeof(Deferrer1<O, F, P1>));
  495. return NEW2 Deferrer1<O, R, P1>(funcName, func, param1);
  496. }
  497. template <typename O, typename R, typename P1, typename P2>
  498. IDeferrer<O>* MakeDeferrer(const char * funcName, typename Deferrer2<O, R, P1, P2>::FuncType func, P1 param1, P2 param2)
  499. {
  500. // api->Trace("Deferred call object: size = %d", sizeof(Deferrer2<O, F, P1, P2>));
  501. return NEW2 Deferrer2<O, R, P1, P2>(funcName, func, param1, param2);
  502. }
  503. template <typename O, typename R, typename P1, typename P2, typename P3>
  504. IDeferrer<O>* MakeDeferrer(const char * funcName, typename Deferrer3<O, R, P1, P2, P3>::FuncType func, P1 param1, P2 param2, P3 param3)
  505. {
  506. // api->Trace("Deferred call object: size = %d", sizeof(Deferrer3<O, F, P1, P2, P3>));
  507. return NEW2 Deferrer3<O, R, P1, P2, P3>(funcName, func, param1, param2, param3);
  508. }
  509. template <typename O, typename R, typename P1, typename P2, typename P3, typename P4>
  510. IDeferrer<O>* MakeDeferrer(const char * funcName, typename Deferrer4<O, R, P1, P2, P3, P4>::FuncType func, P1 param1, P2 param2, P3 param3, P4 param4)
  511. {
  512. // api->Trace("Deferred call object: size = %d", sizeof(Deferrer4<O, F, P1, P2, P3, P4>));
  513. return NEW2 Deferrer4<O, R, P1, P2, P3, P4>(funcName, func, param1, param2, param3, param4);
  514. }
  515. template <typename O, typename R, typename P1, typename P2, typename P3, typename P4, typename P5>
  516. IDeferrer<O>* MakeDeferrer(const char * funcName, typename Deferrer5<O, R, P1, P2, P3, P4, P5>::FuncType func, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5)
  517. {
  518. // api->Trace("Deferred call object: size = %d", sizeof(Deferrer5<O, F, P1, P2, P3, P4, P5>));
  519. return NEW2 Deferrer5<O, R, P1, P2, P3, P4, P5>(funcName, func, param1, param2, param3, param4, param5);
  520. }
  521. template <typename O, typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
  522. IDeferrer<O>* MakeDeferrer(const char * funcName, typename Deferrer6<O, R, P1, P2, P3, P4, P5, P6>::FuncType func, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5, P6 param6)
  523. {
  524. // api->Trace("Deferred call object: size = %d", sizeof(Deferrer5<O, F, P1, P2, P3, P4, P5>));
  525. return NEW2 Deferrer6<O, R, P1, P2, P3, P4, P5, P6>(funcName, func, param1, param2, param3, param4, param5, param6);
  526. }