command_queue_mt.h 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340
  1. /*************************************************************************/
  2. /* command_queue_mt.h */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /*************************************************************************/
  30. #ifndef COMMAND_QUEUE_MT_H
  31. #define COMMAND_QUEUE_MT_H
  32. #include "os/memory.h"
  33. #include "os/mutex.h"
  34. #include "os/semaphore.h"
  35. #include "simple_type.h"
  36. #include "typedefs.h"
  37. /**
  38. @author Juan Linietsky <[email protected]>
  39. */
  40. class CommandQueueMT {
  41. struct SyncSemaphore {
  42. Semaphore *sem;
  43. bool in_use;
  44. };
  45. struct CommandBase {
  46. virtual void call() = 0;
  47. virtual ~CommandBase(){};
  48. };
  49. template <class T, class M>
  50. struct Command0 : public CommandBase {
  51. T *instance;
  52. M method;
  53. virtual void call() { (instance->*method)(); }
  54. };
  55. template <class T, class M, class P1>
  56. struct Command1 : public CommandBase {
  57. T *instance;
  58. M method;
  59. typename GetSimpleTypeT<P1>::type_t p1;
  60. virtual void call() { (instance->*method)(p1); }
  61. };
  62. template <class T, class M, class P1, class P2>
  63. struct Command2 : public CommandBase {
  64. T *instance;
  65. M method;
  66. typename GetSimpleTypeT<P1>::type_t p1;
  67. typename GetSimpleTypeT<P2>::type_t p2;
  68. virtual void call() { (instance->*method)(p1, p2); }
  69. };
  70. template <class T, class M, class P1, class P2, class P3>
  71. struct Command3 : public CommandBase {
  72. T *instance;
  73. M method;
  74. typename GetSimpleTypeT<P1>::type_t p1;
  75. typename GetSimpleTypeT<P2>::type_t p2;
  76. typename GetSimpleTypeT<P3>::type_t p3;
  77. virtual void call() { (instance->*method)(p1, p2, p3); }
  78. };
  79. template <class T, class M, class P1, class P2, class P3, class P4>
  80. struct Command4 : public CommandBase {
  81. T *instance;
  82. M method;
  83. typename GetSimpleTypeT<P1>::type_t p1;
  84. typename GetSimpleTypeT<P2>::type_t p2;
  85. typename GetSimpleTypeT<P3>::type_t p3;
  86. typename GetSimpleTypeT<P4>::type_t p4;
  87. virtual void call() { (instance->*method)(p1, p2, p3, p4); }
  88. };
  89. template <class T, class M, class P1, class P2, class P3, class P4, class P5>
  90. struct Command5 : public CommandBase {
  91. T *instance;
  92. M method;
  93. typename GetSimpleTypeT<P1>::type_t p1;
  94. typename GetSimpleTypeT<P2>::type_t p2;
  95. typename GetSimpleTypeT<P3>::type_t p3;
  96. typename GetSimpleTypeT<P4>::type_t p4;
  97. typename GetSimpleTypeT<P5>::type_t p5;
  98. virtual void call() { (instance->*method)(p1, p2, p3, p4, p5); }
  99. };
  100. template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6>
  101. struct Command6 : public CommandBase {
  102. T *instance;
  103. M method;
  104. typename GetSimpleTypeT<P1>::type_t p1;
  105. typename GetSimpleTypeT<P2>::type_t p2;
  106. typename GetSimpleTypeT<P3>::type_t p3;
  107. typename GetSimpleTypeT<P4>::type_t p4;
  108. typename GetSimpleTypeT<P5>::type_t p5;
  109. typename GetSimpleTypeT<P6>::type_t p6;
  110. virtual void call() { (instance->*method)(p1, p2, p3, p4, p5, p6); }
  111. };
  112. template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7>
  113. struct Command7 : public CommandBase {
  114. T *instance;
  115. M method;
  116. typename GetSimpleTypeT<P1>::type_t p1;
  117. typename GetSimpleTypeT<P2>::type_t p2;
  118. typename GetSimpleTypeT<P3>::type_t p3;
  119. typename GetSimpleTypeT<P4>::type_t p4;
  120. typename GetSimpleTypeT<P5>::type_t p5;
  121. typename GetSimpleTypeT<P6>::type_t p6;
  122. typename GetSimpleTypeT<P7>::type_t p7;
  123. virtual void call() { (instance->*method)(p1, p2, p3, p4, p5, p6, p7); }
  124. };
  125. template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
  126. struct Command8 : public CommandBase {
  127. T *instance;
  128. M method;
  129. typename GetSimpleTypeT<P1>::type_t p1;
  130. typename GetSimpleTypeT<P2>::type_t p2;
  131. typename GetSimpleTypeT<P3>::type_t p3;
  132. typename GetSimpleTypeT<P4>::type_t p4;
  133. typename GetSimpleTypeT<P5>::type_t p5;
  134. typename GetSimpleTypeT<P6>::type_t p6;
  135. typename GetSimpleTypeT<P7>::type_t p7;
  136. typename GetSimpleTypeT<P8>::type_t p8;
  137. virtual void call() { (instance->*method)(p1, p2, p3, p4, p5, p6, p7, p8); }
  138. };
  139. template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9>
  140. struct Command9 : public CommandBase {
  141. T *instance;
  142. M method;
  143. typename GetSimpleTypeT<P1>::type_t p1;
  144. typename GetSimpleTypeT<P2>::type_t p2;
  145. typename GetSimpleTypeT<P3>::type_t p3;
  146. typename GetSimpleTypeT<P4>::type_t p4;
  147. typename GetSimpleTypeT<P5>::type_t p5;
  148. typename GetSimpleTypeT<P6>::type_t p6;
  149. typename GetSimpleTypeT<P7>::type_t p7;
  150. typename GetSimpleTypeT<P8>::type_t p8;
  151. typename GetSimpleTypeT<P9>::type_t p9;
  152. virtual void call() { (instance->*method)(p1, p2, p3, p4, p5, p6, p7, p8, p9); }
  153. };
  154. template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10>
  155. struct Command10 : public CommandBase {
  156. T *instance;
  157. M method;
  158. typename GetSimpleTypeT<P1>::type_t p1;
  159. typename GetSimpleTypeT<P2>::type_t p2;
  160. typename GetSimpleTypeT<P3>::type_t p3;
  161. typename GetSimpleTypeT<P4>::type_t p4;
  162. typename GetSimpleTypeT<P5>::type_t p5;
  163. typename GetSimpleTypeT<P6>::type_t p6;
  164. typename GetSimpleTypeT<P7>::type_t p7;
  165. typename GetSimpleTypeT<P8>::type_t p8;
  166. typename GetSimpleTypeT<P9>::type_t p9;
  167. typename GetSimpleTypeT<P10>::type_t p10;
  168. virtual void call() { (instance->*method)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); }
  169. };
  170. template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10, class P11>
  171. struct Command11 : public CommandBase {
  172. T *instance;
  173. M method;
  174. typename GetSimpleTypeT<P1>::type_t p1;
  175. typename GetSimpleTypeT<P2>::type_t p2;
  176. typename GetSimpleTypeT<P3>::type_t p3;
  177. typename GetSimpleTypeT<P4>::type_t p4;
  178. typename GetSimpleTypeT<P5>::type_t p5;
  179. typename GetSimpleTypeT<P6>::type_t p6;
  180. typename GetSimpleTypeT<P7>::type_t p7;
  181. typename GetSimpleTypeT<P8>::type_t p8;
  182. typename GetSimpleTypeT<P9>::type_t p9;
  183. typename GetSimpleTypeT<P10>::type_t p10;
  184. typename GetSimpleTypeT<P11>::type_t p11;
  185. virtual void call() { (instance->*method)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); }
  186. };
  187. /* comands that return */
  188. template <class T, class M, class R>
  189. struct CommandRet0 : public CommandBase {
  190. T *instance;
  191. M method;
  192. R *ret;
  193. SyncSemaphore *sync;
  194. virtual void call() {
  195. *ret = (instance->*method)();
  196. sync->sem->post();
  197. sync->in_use = false;
  198. }
  199. };
  200. template <class T, class M, class P1, class R>
  201. struct CommandRet1 : public CommandBase {
  202. T *instance;
  203. M method;
  204. typename GetSimpleTypeT<P1>::type_t p1;
  205. R *ret;
  206. SyncSemaphore *sync;
  207. virtual void call() {
  208. *ret = (instance->*method)(p1);
  209. sync->sem->post();
  210. sync->in_use = false;
  211. }
  212. };
  213. template <class T, class M, class P1, class P2, class R>
  214. struct CommandRet2 : public CommandBase {
  215. T *instance;
  216. M method;
  217. typename GetSimpleTypeT<P1>::type_t p1;
  218. typename GetSimpleTypeT<P2>::type_t p2;
  219. R *ret;
  220. SyncSemaphore *sync;
  221. virtual void call() {
  222. *ret = (instance->*method)(p1, p2);
  223. sync->sem->post();
  224. sync->in_use = false;
  225. }
  226. };
  227. template <class T, class M, class P1, class P2, class P3, class R>
  228. struct CommandRet3 : public CommandBase {
  229. T *instance;
  230. M method;
  231. typename GetSimpleTypeT<P1>::type_t p1;
  232. typename GetSimpleTypeT<P2>::type_t p2;
  233. typename GetSimpleTypeT<P3>::type_t p3;
  234. R *ret;
  235. SyncSemaphore *sync;
  236. virtual void call() {
  237. *ret = (instance->*method)(p1, p2, p3);
  238. sync->sem->post();
  239. sync->in_use = false;
  240. }
  241. };
  242. template <class T, class M, class P1, class P2, class P3, class P4, class R>
  243. struct CommandRet4 : public CommandBase {
  244. T *instance;
  245. M method;
  246. typename GetSimpleTypeT<P1>::type_t p1;
  247. typename GetSimpleTypeT<P2>::type_t p2;
  248. typename GetSimpleTypeT<P3>::type_t p3;
  249. typename GetSimpleTypeT<P4>::type_t p4;
  250. R *ret;
  251. SyncSemaphore *sync;
  252. virtual void call() {
  253. *ret = (instance->*method)(p1, p2, p3, p4);
  254. sync->sem->post();
  255. sync->in_use = false;
  256. }
  257. };
  258. template <class T, class M, class P1, class P2, class P3, class P4, class P5, class R>
  259. struct CommandRet5 : public CommandBase {
  260. T *instance;
  261. M method;
  262. typename GetSimpleTypeT<P1>::type_t p1;
  263. typename GetSimpleTypeT<P2>::type_t p2;
  264. typename GetSimpleTypeT<P3>::type_t p3;
  265. typename GetSimpleTypeT<P4>::type_t p4;
  266. typename GetSimpleTypeT<P5>::type_t p5;
  267. R *ret;
  268. SyncSemaphore *sync;
  269. virtual void call() {
  270. *ret = (instance->*method)(p1, p2, p3, p4, p5);
  271. sync->sem->post();
  272. sync->in_use = false;
  273. }
  274. };
  275. template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class R>
  276. struct CommandRet6 : public CommandBase {
  277. T *instance;
  278. M method;
  279. typename GetSimpleTypeT<P1>::type_t p1;
  280. typename GetSimpleTypeT<P2>::type_t p2;
  281. typename GetSimpleTypeT<P3>::type_t p3;
  282. typename GetSimpleTypeT<P4>::type_t p4;
  283. typename GetSimpleTypeT<P5>::type_t p5;
  284. typename GetSimpleTypeT<P6>::type_t p6;
  285. R *ret;
  286. SyncSemaphore *sync;
  287. virtual void call() {
  288. *ret = (instance->*method)(p1, p2, p3, p4, p5, p6);
  289. sync->sem->post();
  290. sync->in_use = false;
  291. }
  292. };
  293. template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class R>
  294. struct CommandRet7 : public CommandBase {
  295. T *instance;
  296. M method;
  297. typename GetSimpleTypeT<P1>::type_t p1;
  298. typename GetSimpleTypeT<P2>::type_t p2;
  299. typename GetSimpleTypeT<P3>::type_t p3;
  300. typename GetSimpleTypeT<P4>::type_t p4;
  301. typename GetSimpleTypeT<P5>::type_t p5;
  302. typename GetSimpleTypeT<P6>::type_t p6;
  303. typename GetSimpleTypeT<P7>::type_t p7;
  304. R *ret;
  305. SyncSemaphore *sync;
  306. virtual void call() {
  307. *ret = (instance->*method)(p1, p2, p3, p4, p5, p6, p7);
  308. sync->sem->post();
  309. sync->in_use = false;
  310. }
  311. };
  312. template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class R>
  313. struct CommandRet8 : public CommandBase {
  314. T *instance;
  315. M method;
  316. typename GetSimpleTypeT<P1>::type_t p1;
  317. typename GetSimpleTypeT<P2>::type_t p2;
  318. typename GetSimpleTypeT<P3>::type_t p3;
  319. typename GetSimpleTypeT<P4>::type_t p4;
  320. typename GetSimpleTypeT<P5>::type_t p5;
  321. typename GetSimpleTypeT<P6>::type_t p6;
  322. typename GetSimpleTypeT<P7>::type_t p7;
  323. typename GetSimpleTypeT<P8>::type_t p8;
  324. R *ret;
  325. SyncSemaphore *sync;
  326. virtual void call() {
  327. *ret = (instance->*method)(p1, p2, p3, p4, p5, p6, p7, p8);
  328. sync->sem->post();
  329. sync->in_use = false;
  330. }
  331. };
  332. /** commands that don't return but sync */
  333. /* comands that return */
  334. template <class T, class M>
  335. struct CommandSync0 : public CommandBase {
  336. T *instance;
  337. M method;
  338. SyncSemaphore *sync;
  339. virtual void call() {
  340. (instance->*method)();
  341. sync->sem->post();
  342. sync->in_use = false;
  343. }
  344. };
  345. template <class T, class M, class P1>
  346. struct CommandSync1 : public CommandBase {
  347. T *instance;
  348. M method;
  349. typename GetSimpleTypeT<P1>::type_t p1;
  350. SyncSemaphore *sync;
  351. virtual void call() {
  352. (instance->*method)(p1);
  353. sync->sem->post();
  354. sync->in_use = false;
  355. }
  356. };
  357. template <class T, class M, class P1, class P2>
  358. struct CommandSync2 : public CommandBase {
  359. T *instance;
  360. M method;
  361. typename GetSimpleTypeT<P1>::type_t p1;
  362. typename GetSimpleTypeT<P2>::type_t p2;
  363. SyncSemaphore *sync;
  364. virtual void call() {
  365. (instance->*method)(p1, p2);
  366. sync->sem->post();
  367. sync->in_use = false;
  368. }
  369. };
  370. template <class T, class M, class P1, class P2, class P3>
  371. struct CommandSync3 : public CommandBase {
  372. T *instance;
  373. M method;
  374. typename GetSimpleTypeT<P1>::type_t p1;
  375. typename GetSimpleTypeT<P2>::type_t p2;
  376. typename GetSimpleTypeT<P3>::type_t p3;
  377. SyncSemaphore *sync;
  378. virtual void call() {
  379. (instance->*method)(p1, p2, p3);
  380. sync->sem->post();
  381. sync->in_use = false;
  382. }
  383. };
  384. template <class T, class M, class P1, class P2, class P3, class P4>
  385. struct CommandSync4 : public CommandBase {
  386. T *instance;
  387. M method;
  388. typename GetSimpleTypeT<P1>::type_t p1;
  389. typename GetSimpleTypeT<P2>::type_t p2;
  390. typename GetSimpleTypeT<P3>::type_t p3;
  391. typename GetSimpleTypeT<P4>::type_t p4;
  392. SyncSemaphore *sync;
  393. virtual void call() {
  394. (instance->*method)(p1, p2, p3, p4);
  395. sync->sem->post();
  396. sync->in_use = false;
  397. }
  398. };
  399. template <class T, class M, class P1, class P2, class P3, class P4, class P5>
  400. struct CommandSync5 : public CommandBase {
  401. T *instance;
  402. M method;
  403. typename GetSimpleTypeT<P1>::type_t p1;
  404. typename GetSimpleTypeT<P2>::type_t p2;
  405. typename GetSimpleTypeT<P3>::type_t p3;
  406. typename GetSimpleTypeT<P4>::type_t p4;
  407. typename GetSimpleTypeT<P5>::type_t p5;
  408. SyncSemaphore *sync;
  409. virtual void call() {
  410. (instance->*method)(p1, p2, p3, p4, p5);
  411. sync->sem->post();
  412. sync->in_use = false;
  413. }
  414. };
  415. template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6>
  416. struct CommandSync6 : public CommandBase {
  417. T *instance;
  418. M method;
  419. typename GetSimpleTypeT<P1>::type_t p1;
  420. typename GetSimpleTypeT<P2>::type_t p2;
  421. typename GetSimpleTypeT<P3>::type_t p3;
  422. typename GetSimpleTypeT<P4>::type_t p4;
  423. typename GetSimpleTypeT<P5>::type_t p5;
  424. typename GetSimpleTypeT<P6>::type_t p6;
  425. SyncSemaphore *sync;
  426. virtual void call() {
  427. (instance->*method)(p1, p2, p3, p4, p5, p6);
  428. sync->sem->post();
  429. sync->in_use = false;
  430. }
  431. };
  432. template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7>
  433. struct CommandSync7 : public CommandBase {
  434. T *instance;
  435. M method;
  436. typename GetSimpleTypeT<P1>::type_t p1;
  437. typename GetSimpleTypeT<P2>::type_t p2;
  438. typename GetSimpleTypeT<P3>::type_t p3;
  439. typename GetSimpleTypeT<P4>::type_t p4;
  440. typename GetSimpleTypeT<P5>::type_t p5;
  441. typename GetSimpleTypeT<P6>::type_t p6;
  442. typename GetSimpleTypeT<P7>::type_t p7;
  443. SyncSemaphore *sync;
  444. virtual void call() {
  445. (instance->*method)(p1, p2, p3, p4, p5, p6, p7);
  446. sync->sem->post();
  447. sync->in_use = false;
  448. }
  449. };
  450. template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
  451. struct CommandSync8 : public CommandBase {
  452. T *instance;
  453. M method;
  454. typename GetSimpleTypeT<P1>::type_t p1;
  455. typename GetSimpleTypeT<P2>::type_t p2;
  456. typename GetSimpleTypeT<P3>::type_t p3;
  457. typename GetSimpleTypeT<P4>::type_t p4;
  458. typename GetSimpleTypeT<P5>::type_t p5;
  459. typename GetSimpleTypeT<P6>::type_t p6;
  460. typename GetSimpleTypeT<P7>::type_t p7;
  461. typename GetSimpleTypeT<P8>::type_t p8;
  462. SyncSemaphore *sync;
  463. virtual void call() {
  464. (instance->*method)(p1, p2, p3, p4, p5, p6, p7, p8);
  465. sync->sem->post();
  466. sync->in_use = false;
  467. }
  468. };
  469. /***** BASE *******/
  470. enum {
  471. COMMAND_MEM_SIZE_KB = 256,
  472. COMMAND_MEM_SIZE = COMMAND_MEM_SIZE_KB * 1024,
  473. SYNC_SEMAPHORES = 8
  474. };
  475. uint8_t command_mem[COMMAND_MEM_SIZE];
  476. uint32_t read_ptr;
  477. uint32_t write_ptr;
  478. SyncSemaphore sync_sems[SYNC_SEMAPHORES];
  479. Mutex *mutex;
  480. Semaphore *sync;
  481. template <class T>
  482. T *allocate() {
  483. // alloc size is size+T+safeguard
  484. uint32_t alloc_size = sizeof(T) + sizeof(uint32_t);
  485. tryagain:
  486. if (write_ptr < read_ptr) {
  487. // behind read_ptr, check that there is room
  488. if ((read_ptr - write_ptr) <= alloc_size)
  489. return NULL;
  490. } else if (write_ptr >= read_ptr) {
  491. // ahead of read_ptr, check that there is room
  492. if ((COMMAND_MEM_SIZE - write_ptr) < alloc_size + 4) {
  493. // no room at the end, wrap down;
  494. if (read_ptr == 0) // don't want write_ptr to become read_ptr
  495. return NULL;
  496. // if this happens, it's a bug
  497. ERR_FAIL_COND_V((COMMAND_MEM_SIZE - write_ptr) < sizeof(uint32_t), NULL);
  498. // zero means, wrap to beginning
  499. uint32_t *p = (uint32_t *)&command_mem[write_ptr];
  500. *p = 0;
  501. write_ptr = 0;
  502. goto tryagain;
  503. }
  504. }
  505. // allocate the size
  506. uint32_t *p = (uint32_t *)&command_mem[write_ptr];
  507. *p = sizeof(T);
  508. write_ptr += sizeof(uint32_t);
  509. // allocate the command
  510. T *cmd = memnew_placement(&command_mem[write_ptr], T);
  511. write_ptr += sizeof(T);
  512. return cmd;
  513. }
  514. template <class T>
  515. T *allocate_and_lock() {
  516. lock();
  517. T *ret;
  518. while ((ret = allocate<T>()) == NULL) {
  519. unlock();
  520. // sleep a little until fetch happened and some room is made
  521. wait_for_flush();
  522. lock();
  523. }
  524. return ret;
  525. }
  526. bool flush_one() {
  527. tryagain:
  528. // tried to read an empty queue
  529. if (read_ptr == write_ptr)
  530. return false;
  531. uint32_t size = *(uint32_t *)(&command_mem[read_ptr]);
  532. if (size == 0) {
  533. //end of ringbuffer, wrap
  534. read_ptr = 0;
  535. goto tryagain;
  536. }
  537. read_ptr += sizeof(uint32_t);
  538. CommandBase *cmd = reinterpret_cast<CommandBase *>(&command_mem[read_ptr]);
  539. cmd->call();
  540. cmd->~CommandBase();
  541. read_ptr += size;
  542. return true;
  543. }
  544. void lock();
  545. void unlock();
  546. void wait_for_flush();
  547. SyncSemaphore *_alloc_sync_sem();
  548. public:
  549. /* NORMAL PUSH COMMANDS */
  550. template <class T, class M>
  551. void push(T *p_instance, M p_method) {
  552. Command0<T, M> *cmd = allocate_and_lock<Command0<T, M> >();
  553. cmd->instance = p_instance;
  554. cmd->method = p_method;
  555. unlock();
  556. if (sync) sync->post();
  557. }
  558. template <class T, class M, class P1>
  559. void push(T *p_instance, M p_method, P1 p1) {
  560. Command1<T, M, P1> *cmd = allocate_and_lock<Command1<T, M, P1> >();
  561. cmd->instance = p_instance;
  562. cmd->method = p_method;
  563. cmd->p1 = p1;
  564. unlock();
  565. if (sync) sync->post();
  566. }
  567. template <class T, class M, class P1, class P2>
  568. void push(T *p_instance, M p_method, P1 p1, P2 p2) {
  569. Command2<T, M, P1, P2> *cmd = allocate_and_lock<Command2<T, M, P1, P2> >();
  570. cmd->instance = p_instance;
  571. cmd->method = p_method;
  572. cmd->p1 = p1;
  573. cmd->p2 = p2;
  574. unlock();
  575. if (sync) sync->post();
  576. }
  577. template <class T, class M, class P1, class P2, class P3>
  578. void push(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3) {
  579. Command3<T, M, P1, P2, P3> *cmd = allocate_and_lock<Command3<T, M, P1, P2, P3> >();
  580. cmd->instance = p_instance;
  581. cmd->method = p_method;
  582. cmd->p1 = p1;
  583. cmd->p2 = p2;
  584. cmd->p3 = p3;
  585. unlock();
  586. if (sync) sync->post();
  587. }
  588. template <class T, class M, class P1, class P2, class P3, class P4>
  589. void push(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4) {
  590. Command4<T, M, P1, P2, P3, P4> *cmd = allocate_and_lock<Command4<T, M, P1, P2, P3, P4> >();
  591. cmd->instance = p_instance;
  592. cmd->method = p_method;
  593. cmd->p1 = p1;
  594. cmd->p2 = p2;
  595. cmd->p3 = p3;
  596. cmd->p4 = p4;
  597. unlock();
  598. if (sync) sync->post();
  599. }
  600. template <class T, class M, class P1, class P2, class P3, class P4, class P5>
  601. void push(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
  602. Command5<T, M, P1, P2, P3, P4, P5> *cmd = allocate_and_lock<Command5<T, M, P1, P2, P3, P4, P5> >();
  603. cmd->instance = p_instance;
  604. cmd->method = p_method;
  605. cmd->p1 = p1;
  606. cmd->p2 = p2;
  607. cmd->p3 = p3;
  608. cmd->p4 = p4;
  609. cmd->p5 = p5;
  610. unlock();
  611. if (sync) sync->post();
  612. }
  613. template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6>
  614. void push(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {
  615. Command6<T, M, P1, P2, P3, P4, P5, P6> *cmd = allocate_and_lock<Command6<T, M, P1, P2, P3, P4, P5, P6> >();
  616. cmd->instance = p_instance;
  617. cmd->method = p_method;
  618. cmd->p1 = p1;
  619. cmd->p2 = p2;
  620. cmd->p3 = p3;
  621. cmd->p4 = p4;
  622. cmd->p5 = p5;
  623. cmd->p6 = p6;
  624. unlock();
  625. if (sync) sync->post();
  626. }
  627. template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7>
  628. void push(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) {
  629. Command7<T, M, P1, P2, P3, P4, P5, P6, P7> *cmd = allocate_and_lock<Command7<T, M, P1, P2, P3, P4, P5, P6, P7> >();
  630. cmd->instance = p_instance;
  631. cmd->method = p_method;
  632. cmd->p1 = p1;
  633. cmd->p2 = p2;
  634. cmd->p3 = p3;
  635. cmd->p4 = p4;
  636. cmd->p5 = p5;
  637. cmd->p6 = p6;
  638. cmd->p7 = p7;
  639. unlock();
  640. if (sync) sync->post();
  641. }
  642. template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
  643. void push(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) {
  644. Command8<T, M, P1, P2, P3, P4, P5, P6, P7, P8> *cmd = allocate_and_lock<Command8<T, M, P1, P2, P3, P4, P5, P6, P7, P8> >();
  645. cmd->instance = p_instance;
  646. cmd->method = p_method;
  647. cmd->p1 = p1;
  648. cmd->p2 = p2;
  649. cmd->p3 = p3;
  650. cmd->p4 = p4;
  651. cmd->p5 = p5;
  652. cmd->p6 = p6;
  653. cmd->p7 = p7;
  654. cmd->p8 = p8;
  655. unlock();
  656. if (sync) sync->post();
  657. }
  658. template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9>
  659. void push(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9) {
  660. Command9<T, M, P1, P2, P3, P4, P5, P6, P7, P8, P9> *cmd = allocate_and_lock<Command9<T, M, P1, P2, P3, P4, P5, P6, P7, P8, P9> >();
  661. cmd->instance = p_instance;
  662. cmd->method = p_method;
  663. cmd->p1 = p1;
  664. cmd->p2 = p2;
  665. cmd->p3 = p3;
  666. cmd->p4 = p4;
  667. cmd->p5 = p5;
  668. cmd->p6 = p6;
  669. cmd->p7 = p7;
  670. cmd->p8 = p8;
  671. cmd->p9 = p9;
  672. unlock();
  673. if (sync) sync->post();
  674. }
  675. template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10>
  676. void push(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10) {
  677. Command10<T, M, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10> *cmd = allocate_and_lock<Command10<T, M, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10> >();
  678. cmd->instance = p_instance;
  679. cmd->method = p_method;
  680. cmd->p1 = p1;
  681. cmd->p2 = p2;
  682. cmd->p3 = p3;
  683. cmd->p4 = p4;
  684. cmd->p5 = p5;
  685. cmd->p6 = p6;
  686. cmd->p7 = p7;
  687. cmd->p8 = p8;
  688. cmd->p9 = p9;
  689. cmd->p10 = p10;
  690. unlock();
  691. if (sync) sync->post();
  692. }
  693. template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10, class P11>
  694. void push(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10, P11 p11) {
  695. Command11<T, M, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11> *cmd = allocate_and_lock<Command11<T, M, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11> >();
  696. cmd->instance = p_instance;
  697. cmd->method = p_method;
  698. cmd->p1 = p1;
  699. cmd->p2 = p2;
  700. cmd->p3 = p3;
  701. cmd->p4 = p4;
  702. cmd->p5 = p5;
  703. cmd->p6 = p6;
  704. cmd->p7 = p7;
  705. cmd->p8 = p8;
  706. cmd->p9 = p9;
  707. cmd->p10 = p10;
  708. cmd->p11 = p11;
  709. unlock();
  710. if (sync) sync->post();
  711. }
  712. /*** PUSH AND RET COMMANDS ***/
  713. template <class T, class M, class R>
  714. void push_and_ret(T *p_instance, M p_method, R *r_ret) {
  715. SyncSemaphore *ss = _alloc_sync_sem();
  716. CommandRet0<T, M, R> *cmd = allocate_and_lock<CommandRet0<T, M, R> >();
  717. cmd->instance = p_instance;
  718. cmd->method = p_method;
  719. cmd->ret = r_ret;
  720. cmd->sync = ss;
  721. unlock();
  722. if (sync) sync->post();
  723. ss->sem->wait();
  724. }
  725. template <class T, class M, class P1, class R>
  726. void push_and_ret(T *p_instance, M p_method, P1 p1, R *r_ret) {
  727. SyncSemaphore *ss = _alloc_sync_sem();
  728. CommandRet1<T, M, P1, R> *cmd = allocate_and_lock<CommandRet1<T, M, P1, R> >();
  729. cmd->instance = p_instance;
  730. cmd->method = p_method;
  731. cmd->p1 = p1;
  732. cmd->ret = r_ret;
  733. cmd->sync = ss;
  734. unlock();
  735. if (sync) sync->post();
  736. ss->sem->wait();
  737. }
  738. template <class T, class M, class P1, class P2, class R>
  739. void push_and_ret(T *p_instance, M p_method, P1 p1, P2 p2, R *r_ret) {
  740. SyncSemaphore *ss = _alloc_sync_sem();
  741. CommandRet2<T, M, P1, P2, R> *cmd = allocate_and_lock<CommandRet2<T, M, P1, P2, R> >();
  742. cmd->instance = p_instance;
  743. cmd->method = p_method;
  744. cmd->p1 = p1;
  745. cmd->p2 = p2;
  746. cmd->ret = r_ret;
  747. cmd->sync = ss;
  748. unlock();
  749. if (sync) sync->post();
  750. ss->sem->wait();
  751. }
  752. template <class T, class M, class P1, class P2, class P3, class R>
  753. void push_and_ret(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, R *r_ret) {
  754. SyncSemaphore *ss = _alloc_sync_sem();
  755. CommandRet3<T, M, P1, P2, P3, R> *cmd = allocate_and_lock<CommandRet3<T, M, P1, P2, P3, R> >();
  756. cmd->instance = p_instance;
  757. cmd->method = p_method;
  758. cmd->p1 = p1;
  759. cmd->p2 = p2;
  760. cmd->p3 = p3;
  761. cmd->ret = r_ret;
  762. cmd->sync = ss;
  763. unlock();
  764. if (sync) sync->post();
  765. ss->sem->wait();
  766. }
  767. template <class T, class M, class P1, class P2, class P3, class P4, class R>
  768. void push_and_ret(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, R *r_ret) {
  769. SyncSemaphore *ss = _alloc_sync_sem();
  770. CommandRet4<T, M, P1, P2, P3, P4, R> *cmd = allocate_and_lock<CommandRet4<T, M, P1, P2, P3, P4, R> >();
  771. cmd->instance = p_instance;
  772. cmd->method = p_method;
  773. cmd->p1 = p1;
  774. cmd->p2 = p2;
  775. cmd->p3 = p3;
  776. cmd->p4 = p4;
  777. cmd->ret = r_ret;
  778. cmd->sync = ss;
  779. unlock();
  780. if (sync) sync->post();
  781. ss->sem->wait();
  782. }
  783. template <class T, class M, class P1, class P2, class P3, class P4, class P5, class R>
  784. void push_and_ret(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, R *r_ret) {
  785. SyncSemaphore *ss = _alloc_sync_sem();
  786. CommandRet5<T, M, P1, P2, P3, P4, P5, R> *cmd = allocate_and_lock<CommandRet5<T, M, P1, P2, P3, P4, P5, R> >();
  787. cmd->instance = p_instance;
  788. cmd->method = p_method;
  789. cmd->p1 = p1;
  790. cmd->p2 = p2;
  791. cmd->p3 = p3;
  792. cmd->p4 = p4;
  793. cmd->p5 = p5;
  794. cmd->ret = r_ret;
  795. cmd->sync = ss;
  796. unlock();
  797. if (sync) sync->post();
  798. ss->sem->wait();
  799. }
  800. template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class R>
  801. void push_and_ret(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, R *r_ret) {
  802. SyncSemaphore *ss = _alloc_sync_sem();
  803. CommandRet6<T, M, P1, P2, P3, P4, P5, P6, R> *cmd = allocate_and_lock<CommandRet6<T, M, P1, P2, P3, P4, P5, P6, R> >();
  804. cmd->instance = p_instance;
  805. cmd->method = p_method;
  806. cmd->p1 = p1;
  807. cmd->p2 = p2;
  808. cmd->p3 = p3;
  809. cmd->p4 = p4;
  810. cmd->p5 = p5;
  811. cmd->p6 = p6;
  812. cmd->ret = r_ret;
  813. cmd->sync = ss;
  814. unlock();
  815. if (sync) sync->post();
  816. ss->sem->wait();
  817. }
  818. template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class R>
  819. void push_and_ret(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, R *r_ret) {
  820. SyncSemaphore *ss = _alloc_sync_sem();
  821. CommandRet7<T, M, P1, P2, P3, P4, P5, P6, P7, R> *cmd = allocate_and_lock<CommandRet7<T, M, P1, P2, P3, P4, P5, P6, P7, R> >();
  822. cmd->instance = p_instance;
  823. cmd->method = p_method;
  824. cmd->p1 = p1;
  825. cmd->p2 = p2;
  826. cmd->p3 = p3;
  827. cmd->p4 = p4;
  828. cmd->p5 = p5;
  829. cmd->p6 = p6;
  830. cmd->p7 = p7;
  831. cmd->ret = r_ret;
  832. cmd->sync = ss;
  833. unlock();
  834. if (sync) sync->post();
  835. ss->sem->wait();
  836. }
  837. template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class R>
  838. void push_and_ret(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, R *r_ret) {
  839. SyncSemaphore *ss = _alloc_sync_sem();
  840. CommandRet8<T, M, P1, P2, P3, P4, P5, P6, P7, P8, R> *cmd = allocate_and_lock<CommandRet8<T, M, P1, P2, P3, P4, P5, P6, P7, P8, R> >();
  841. cmd->instance = p_instance;
  842. cmd->method = p_method;
  843. cmd->p1 = p1;
  844. cmd->p2 = p2;
  845. cmd->p3 = p3;
  846. cmd->p4 = p4;
  847. cmd->p5 = p5;
  848. cmd->p6 = p6;
  849. cmd->p7 = p7;
  850. cmd->p8 = p8;
  851. cmd->ret = r_ret;
  852. cmd->sync = ss;
  853. unlock();
  854. if (sync) sync->post();
  855. ss->sem->wait();
  856. }
  857. template <class T, class M>
  858. void push_and_sync(T *p_instance, M p_method) {
  859. SyncSemaphore *ss = _alloc_sync_sem();
  860. CommandSync0<T, M> *cmd = allocate_and_lock<CommandSync0<T, M> >();
  861. cmd->instance = p_instance;
  862. cmd->method = p_method;
  863. cmd->sync = ss;
  864. unlock();
  865. if (sync) sync->post();
  866. ss->sem->wait();
  867. }
  868. template <class T, class M, class P1>
  869. void push_and_sync(T *p_instance, M p_method, P1 p1) {
  870. SyncSemaphore *ss = _alloc_sync_sem();
  871. CommandSync1<T, M, P1> *cmd = allocate_and_lock<CommandSync1<T, M, P1> >();
  872. cmd->instance = p_instance;
  873. cmd->method = p_method;
  874. cmd->p1 = p1;
  875. cmd->sync = ss;
  876. unlock();
  877. if (sync) sync->post();
  878. ss->sem->wait();
  879. }
  880. template <class T, class M, class P1, class P2>
  881. void push_and_sync(T *p_instance, M p_method, P1 p1, P2 p2) {
  882. SyncSemaphore *ss = _alloc_sync_sem();
  883. CommandSync2<T, M, P1, P2> *cmd = allocate_and_lock<CommandSync2<T, M, P1, P2> >();
  884. cmd->instance = p_instance;
  885. cmd->method = p_method;
  886. cmd->p1 = p1;
  887. cmd->p2 = p2;
  888. cmd->sync = ss;
  889. unlock();
  890. if (sync) sync->post();
  891. ss->sem->wait();
  892. }
  893. template <class T, class M, class P1, class P2, class P3>
  894. void push_and_sync(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3) {
  895. SyncSemaphore *ss = _alloc_sync_sem();
  896. CommandSync3<T, M, P1, P2, P3> *cmd = allocate_and_lock<CommandSync3<T, M, P1, P2, P3> >();
  897. cmd->instance = p_instance;
  898. cmd->method = p_method;
  899. cmd->p1 = p1;
  900. cmd->p2 = p2;
  901. cmd->p3 = p3;
  902. cmd->sync = ss;
  903. unlock();
  904. if (sync) sync->post();
  905. ss->sem->wait();
  906. }
  907. template <class T, class M, class P1, class P2, class P3, class P4>
  908. void push_and_sync(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4) {
  909. SyncSemaphore *ss = _alloc_sync_sem();
  910. CommandSync4<T, M, P1, P2, P3, P4> *cmd = allocate_and_lock<CommandSync4<T, M, P1, P2, P3, P4> >();
  911. cmd->instance = p_instance;
  912. cmd->method = p_method;
  913. cmd->p1 = p1;
  914. cmd->p2 = p2;
  915. cmd->p3 = p3;
  916. cmd->p4 = p4;
  917. cmd->sync = ss;
  918. unlock();
  919. if (sync) sync->post();
  920. ss->sem->wait();
  921. }
  922. template <class T, class M, class P1, class P2, class P3, class P4, class P5>
  923. void push_and_sync(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
  924. SyncSemaphore *ss = _alloc_sync_sem();
  925. CommandSync5<T, M, P1, P2, P3, P4, P5> *cmd = allocate_and_lock<CommandSync5<T, M, P1, P2, P3, P4, P5> >();
  926. cmd->instance = p_instance;
  927. cmd->method = p_method;
  928. cmd->p1 = p1;
  929. cmd->p2 = p2;
  930. cmd->p3 = p3;
  931. cmd->p4 = p4;
  932. cmd->p5 = p5;
  933. cmd->sync = ss;
  934. unlock();
  935. if (sync) sync->post();
  936. ss->sem->wait();
  937. }
  938. template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6>
  939. void push_and_sync(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {
  940. SyncSemaphore *ss = _alloc_sync_sem();
  941. CommandSync6<T, M, P1, P2, P3, P4, P5, P6> *cmd = allocate_and_lock<CommandSync6<T, M, P1, P2, P3, P4, P5, P6> >();
  942. cmd->instance = p_instance;
  943. cmd->method = p_method;
  944. cmd->p1 = p1;
  945. cmd->p2 = p2;
  946. cmd->p3 = p3;
  947. cmd->p4 = p4;
  948. cmd->p5 = p5;
  949. cmd->p6 = p6;
  950. cmd->sync = ss;
  951. unlock();
  952. if (sync) sync->post();
  953. ss->sem->wait();
  954. }
  955. template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7>
  956. void push_and_sync(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) {
  957. SyncSemaphore *ss = _alloc_sync_sem();
  958. CommandSync7<T, M, P1, P2, P3, P4, P5, P6, P7> *cmd = allocate_and_lock<CommandSync7<T, M, P1, P2, P3, P4, P5, P6, P7> >();
  959. cmd->instance = p_instance;
  960. cmd->method = p_method;
  961. cmd->p1 = p1;
  962. cmd->p2 = p2;
  963. cmd->p3 = p3;
  964. cmd->p4 = p4;
  965. cmd->p5 = p5;
  966. cmd->p6 = p6;
  967. cmd->p7 = p7;
  968. cmd->sync = ss;
  969. unlock();
  970. if (sync) sync->post();
  971. ss->sem->wait();
  972. }
  973. template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
  974. void push_and_sync(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) {
  975. SyncSemaphore *ss = _alloc_sync_sem();
  976. CommandSync8<T, M, P1, P2, P3, P4, P5, P6, P7, P8> *cmd = allocate_and_lock<CommandSync8<T, M, P1, P2, P3, P4, P5, P6, P7, P8> >();
  977. cmd->instance = p_instance;
  978. cmd->method = p_method;
  979. cmd->p1 = p1;
  980. cmd->p2 = p2;
  981. cmd->p3 = p3;
  982. cmd->p4 = p4;
  983. cmd->p5 = p5;
  984. cmd->p6 = p6;
  985. cmd->p7 = p7;
  986. cmd->p8 = p8;
  987. cmd->sync = ss;
  988. unlock();
  989. if (sync) sync->post();
  990. ss->sem->wait();
  991. }
  992. void wait_and_flush_one() {
  993. ERR_FAIL_COND(!sync);
  994. sync->wait();
  995. lock();
  996. flush_one();
  997. unlock();
  998. }
  999. void flush_all() {
  1000. //ERR_FAIL_COND(sync);
  1001. lock();
  1002. while (true) {
  1003. bool exit = !flush_one();
  1004. if (exit)
  1005. break;
  1006. }
  1007. unlock();
  1008. }
  1009. CommandQueueMT(bool p_sync);
  1010. ~CommandQueueMT();
  1011. };
  1012. #endif