12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232 |
- /*************************************************************************/
- /* command_queue_mt.h */
- /*************************************************************************/
- /* This file is part of: */
- /* GODOT ENGINE */
- /* https://godotengine.org */
- /*************************************************************************/
- /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
- /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
- /* */
- /* Permission is hereby granted, free of charge, to any person obtaining */
- /* a copy of this software and associated documentation files (the */
- /* "Software"), to deal in the Software without restriction, including */
- /* without limitation the rights to use, copy, modify, merge, publish, */
- /* distribute, sublicense, and/or sell copies of the Software, and to */
- /* permit persons to whom the Software is furnished to do so, subject to */
- /* the following conditions: */
- /* */
- /* The above copyright notice and this permission notice shall be */
- /* included in all copies or substantial portions of the Software. */
- /* */
- /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
- /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
- /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
- /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
- /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
- /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
- /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
- /*************************************************************************/
- #ifndef COMMAND_QUEUE_MT_H
- #define COMMAND_QUEUE_MT_H
- #include "os/memory.h"
- #include "os/mutex.h"
- #include "os/semaphore.h"
- #include "simple_type.h"
- #include "typedefs.h"
- /**
- @author Juan Linietsky <reduzio@gmail.com>
- */
- class CommandQueueMT {
- struct SyncSemaphore {
- Semaphore *sem;
- bool in_use;
- };
- struct CommandBase {
- virtual void call() = 0;
- virtual ~CommandBase(){};
- };
- template <class T, class M>
- struct Command0 : public CommandBase {
- T *instance;
- M method;
- virtual void call() { (instance->*method)(); }
- };
- template <class T, class M, class P1>
- struct Command1 : public CommandBase {
- T *instance;
- M method;
- typename GetSimpleTypeT<P1>::type_t p1;
- virtual void call() { (instance->*method)(p1); }
- };
- template <class T, class M, class P1, class P2>
- struct Command2 : public CommandBase {
- T *instance;
- M method;
- typename GetSimpleTypeT<P1>::type_t p1;
- typename GetSimpleTypeT<P2>::type_t p2;
- virtual void call() { (instance->*method)(p1, p2); }
- };
- template <class T, class M, class P1, class P2, class P3>
- struct Command3 : public CommandBase {
- T *instance;
- M method;
- typename GetSimpleTypeT<P1>::type_t p1;
- typename GetSimpleTypeT<P2>::type_t p2;
- typename GetSimpleTypeT<P3>::type_t p3;
- virtual void call() { (instance->*method)(p1, p2, p3); }
- };
- template <class T, class M, class P1, class P2, class P3, class P4>
- struct Command4 : public CommandBase {
- T *instance;
- M method;
- typename GetSimpleTypeT<P1>::type_t p1;
- typename GetSimpleTypeT<P2>::type_t p2;
- typename GetSimpleTypeT<P3>::type_t p3;
- typename GetSimpleTypeT<P4>::type_t p4;
- virtual void call() { (instance->*method)(p1, p2, p3, p4); }
- };
- template <class T, class M, class P1, class P2, class P3, class P4, class P5>
- struct Command5 : public CommandBase {
- T *instance;
- M method;
- typename GetSimpleTypeT<P1>::type_t p1;
- typename GetSimpleTypeT<P2>::type_t p2;
- typename GetSimpleTypeT<P3>::type_t p3;
- typename GetSimpleTypeT<P4>::type_t p4;
- typename GetSimpleTypeT<P5>::type_t p5;
- virtual void call() { (instance->*method)(p1, p2, p3, p4, p5); }
- };
- template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6>
- struct Command6 : public CommandBase {
- T *instance;
- M method;
- typename GetSimpleTypeT<P1>::type_t p1;
- typename GetSimpleTypeT<P2>::type_t p2;
- typename GetSimpleTypeT<P3>::type_t p3;
- typename GetSimpleTypeT<P4>::type_t p4;
- typename GetSimpleTypeT<P5>::type_t p5;
- typename GetSimpleTypeT<P6>::type_t p6;
- virtual void call() { (instance->*method)(p1, p2, p3, p4, p5, p6); }
- };
- template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7>
- struct Command7 : public CommandBase {
- T *instance;
- M method;
- typename GetSimpleTypeT<P1>::type_t p1;
- typename GetSimpleTypeT<P2>::type_t p2;
- typename GetSimpleTypeT<P3>::type_t p3;
- typename GetSimpleTypeT<P4>::type_t p4;
- typename GetSimpleTypeT<P5>::type_t p5;
- typename GetSimpleTypeT<P6>::type_t p6;
- typename GetSimpleTypeT<P7>::type_t p7;
- virtual void call() { (instance->*method)(p1, p2, p3, p4, p5, p6, p7); }
- };
- template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
- struct Command8 : public CommandBase {
- T *instance;
- M method;
- typename GetSimpleTypeT<P1>::type_t p1;
- typename GetSimpleTypeT<P2>::type_t p2;
- typename GetSimpleTypeT<P3>::type_t p3;
- typename GetSimpleTypeT<P4>::type_t p4;
- typename GetSimpleTypeT<P5>::type_t p5;
- typename GetSimpleTypeT<P6>::type_t p6;
- typename GetSimpleTypeT<P7>::type_t p7;
- typename GetSimpleTypeT<P8>::type_t p8;
- virtual void call() { (instance->*method)(p1, p2, p3, p4, p5, p6, p7, p8); }
- };
- /* comands that return */
- template <class T, class M, class R>
- struct CommandRet0 : public CommandBase {
- T *instance;
- M method;
- R *ret;
- SyncSemaphore *sync;
- virtual void call() {
- *ret = (instance->*method)();
- sync->sem->post();
- sync->in_use = false;
- ;
- }
- };
- template <class T, class M, class P1, class R>
- struct CommandRet1 : public CommandBase {
- T *instance;
- M method;
- typename GetSimpleTypeT<P1>::type_t p1;
- R *ret;
- SyncSemaphore *sync;
- virtual void call() {
- *ret = (instance->*method)(p1);
- sync->sem->post();
- sync->in_use = false;
- }
- };
- template <class T, class M, class P1, class P2, class R>
- struct CommandRet2 : public CommandBase {
- T *instance;
- M method;
- typename GetSimpleTypeT<P1>::type_t p1;
- typename GetSimpleTypeT<P2>::type_t p2;
- R *ret;
- SyncSemaphore *sync;
- virtual void call() {
- *ret = (instance->*method)(p1, p2);
- sync->sem->post();
- sync->in_use = false;
- ;
- }
- };
- template <class T, class M, class P1, class P2, class P3, class R>
- struct CommandRet3 : public CommandBase {
- T *instance;
- M method;
- typename GetSimpleTypeT<P1>::type_t p1;
- typename GetSimpleTypeT<P2>::type_t p2;
- typename GetSimpleTypeT<P3>::type_t p3;
- R *ret;
- SyncSemaphore *sync;
- virtual void call() {
- *ret = (instance->*method)(p1, p2, p3);
- sync->sem->post();
- sync->in_use = false;
- ;
- }
- };
- template <class T, class M, class P1, class P2, class P3, class P4, class R>
- struct CommandRet4 : public CommandBase {
- T *instance;
- M method;
- typename GetSimpleTypeT<P1>::type_t p1;
- typename GetSimpleTypeT<P2>::type_t p2;
- typename GetSimpleTypeT<P3>::type_t p3;
- typename GetSimpleTypeT<P4>::type_t p4;
- R *ret;
- SyncSemaphore *sync;
- virtual void call() {
- *ret = (instance->*method)(p1, p2, p3, p4);
- sync->sem->post();
- sync->in_use = false;
- ;
- }
- };
- template <class T, class M, class P1, class P2, class P3, class P4, class P5, class R>
- struct CommandRet5 : public CommandBase {
- T *instance;
- M method;
- typename GetSimpleTypeT<P1>::type_t p1;
- typename GetSimpleTypeT<P2>::type_t p2;
- typename GetSimpleTypeT<P3>::type_t p3;
- typename GetSimpleTypeT<P4>::type_t p4;
- typename GetSimpleTypeT<P5>::type_t p5;
- R *ret;
- SyncSemaphore *sync;
- virtual void call() {
- *ret = (instance->*method)(p1, p2, p3, p4, p5);
- sync->sem->post();
- sync->in_use = false;
- ;
- }
- };
- template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class R>
- struct CommandRet6 : public CommandBase {
- T *instance;
- M method;
- typename GetSimpleTypeT<P1>::type_t p1;
- typename GetSimpleTypeT<P2>::type_t p2;
- typename GetSimpleTypeT<P3>::type_t p3;
- typename GetSimpleTypeT<P4>::type_t p4;
- typename GetSimpleTypeT<P5>::type_t p5;
- typename GetSimpleTypeT<P6>::type_t p6;
- R *ret;
- SyncSemaphore *sync;
- virtual void call() {
- *ret = (instance->*method)(p1, p2, p3, p4, p5, p6);
- sync->sem->post();
- sync->in_use = false;
- ;
- }
- };
- template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class R>
- struct CommandRet7 : public CommandBase {
- T *instance;
- M method;
- typename GetSimpleTypeT<P1>::type_t p1;
- typename GetSimpleTypeT<P2>::type_t p2;
- typename GetSimpleTypeT<P3>::type_t p3;
- typename GetSimpleTypeT<P4>::type_t p4;
- typename GetSimpleTypeT<P5>::type_t p5;
- typename GetSimpleTypeT<P6>::type_t p6;
- typename GetSimpleTypeT<P7>::type_t p7;
- R *ret;
- SyncSemaphore *sync;
- virtual void call() {
- *ret = (instance->*method)(p1, p2, p3, p4, p5, p6, p7);
- sync->sem->post();
- sync->in_use = false;
- ;
- }
- };
- template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class R>
- struct CommandRet8 : public CommandBase {
- T *instance;
- M method;
- typename GetSimpleTypeT<P1>::type_t p1;
- typename GetSimpleTypeT<P2>::type_t p2;
- typename GetSimpleTypeT<P3>::type_t p3;
- typename GetSimpleTypeT<P4>::type_t p4;
- typename GetSimpleTypeT<P5>::type_t p5;
- typename GetSimpleTypeT<P6>::type_t p6;
- typename GetSimpleTypeT<P7>::type_t p7;
- typename GetSimpleTypeT<P8>::type_t p8;
- R *ret;
- SyncSemaphore *sync;
- virtual void call() {
- *ret = (instance->*method)(p1, p2, p3, p4, p5, p6, p7, p8);
- sync->sem->post();
- sync->in_use = false;
- ;
- }
- };
- /** commands that don't return but sync */
- /* comands that return */
- template <class T, class M>
- struct CommandSync0 : public CommandBase {
- T *instance;
- M method;
- SyncSemaphore *sync;
- virtual void call() {
- (instance->*method)();
- sync->sem->post();
- sync->in_use = false;
- ;
- }
- };
- template <class T, class M, class P1>
- struct CommandSync1 : public CommandBase {
- T *instance;
- M method;
- typename GetSimpleTypeT<P1>::type_t p1;
- SyncSemaphore *sync;
- virtual void call() {
- (instance->*method)(p1);
- sync->sem->post();
- sync->in_use = false;
- ;
- }
- };
- template <class T, class M, class P1, class P2>
- struct CommandSync2 : public CommandBase {
- T *instance;
- M method;
- typename GetSimpleTypeT<P1>::type_t p1;
- typename GetSimpleTypeT<P2>::type_t p2;
- SyncSemaphore *sync;
- virtual void call() {
- (instance->*method)(p1, p2);
- sync->sem->post();
- sync->in_use = false;
- ;
- }
- };
- template <class T, class M, class P1, class P2, class P3>
- struct CommandSync3 : public CommandBase {
- T *instance;
- M method;
- typename GetSimpleTypeT<P1>::type_t p1;
- typename GetSimpleTypeT<P2>::type_t p2;
- typename GetSimpleTypeT<P3>::type_t p3;
- SyncSemaphore *sync;
- virtual void call() {
- (instance->*method)(p1, p2, p3);
- sync->sem->post();
- sync->in_use = false;
- ;
- }
- };
- template <class T, class M, class P1, class P2, class P3, class P4>
- struct CommandSync4 : public CommandBase {
- T *instance;
- M method;
- typename GetSimpleTypeT<P1>::type_t p1;
- typename GetSimpleTypeT<P2>::type_t p2;
- typename GetSimpleTypeT<P3>::type_t p3;
- typename GetSimpleTypeT<P4>::type_t p4;
- SyncSemaphore *sync;
- virtual void call() {
- (instance->*method)(p1, p2, p3, p4);
- sync->sem->post();
- sync->in_use = false;
- ;
- }
- };
- template <class T, class M, class P1, class P2, class P3, class P4, class P5>
- struct CommandSync5 : public CommandBase {
- T *instance;
- M method;
- typename GetSimpleTypeT<P1>::type_t p1;
- typename GetSimpleTypeT<P2>::type_t p2;
- typename GetSimpleTypeT<P3>::type_t p3;
- typename GetSimpleTypeT<P4>::type_t p4;
- typename GetSimpleTypeT<P5>::type_t p5;
- SyncSemaphore *sync;
- virtual void call() {
- (instance->*method)(p1, p2, p3, p4, p5);
- sync->sem->post();
- sync->in_use = false;
- ;
- }
- };
- template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6>
- struct CommandSync6 : public CommandBase {
- T *instance;
- M method;
- typename GetSimpleTypeT<P1>::type_t p1;
- typename GetSimpleTypeT<P2>::type_t p2;
- typename GetSimpleTypeT<P3>::type_t p3;
- typename GetSimpleTypeT<P4>::type_t p4;
- typename GetSimpleTypeT<P5>::type_t p5;
- typename GetSimpleTypeT<P6>::type_t p6;
- SyncSemaphore *sync;
- virtual void call() {
- (instance->*method)(p1, p2, p3, p4, p5, p6);
- sync->sem->post();
- sync->in_use = false;
- ;
- }
- };
- template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7>
- struct CommandSync7 : public CommandBase {
- T *instance;
- M method;
- typename GetSimpleTypeT<P1>::type_t p1;
- typename GetSimpleTypeT<P2>::type_t p2;
- typename GetSimpleTypeT<P3>::type_t p3;
- typename GetSimpleTypeT<P4>::type_t p4;
- typename GetSimpleTypeT<P5>::type_t p5;
- typename GetSimpleTypeT<P6>::type_t p6;
- typename GetSimpleTypeT<P7>::type_t p7;
- SyncSemaphore *sync;
- virtual void call() {
- (instance->*method)(p1, p2, p3, p4, p5, p6, p7);
- sync->sem->post();
- sync->in_use = false;
- ;
- }
- };
- template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
- struct CommandSync8 : public CommandBase {
- T *instance;
- M method;
- typename GetSimpleTypeT<P1>::type_t p1;
- typename GetSimpleTypeT<P2>::type_t p2;
- typename GetSimpleTypeT<P3>::type_t p3;
- typename GetSimpleTypeT<P4>::type_t p4;
- typename GetSimpleTypeT<P5>::type_t p5;
- typename GetSimpleTypeT<P6>::type_t p6;
- typename GetSimpleTypeT<P7>::type_t p7;
- typename GetSimpleTypeT<P8>::type_t p8;
- SyncSemaphore *sync;
- virtual void call() {
- (instance->*method)(p1, p2, p3, p4, p5, p6, p7, p8);
- sync->sem->post();
- sync->in_use = false;
- ;
- }
- };
- /***** BASE *******/
- enum {
- COMMAND_MEM_SIZE_KB = 256,
- COMMAND_MEM_SIZE = COMMAND_MEM_SIZE_KB * 1024,
- SYNC_SEMAPHORES = 8
- };
- uint8_t command_mem[COMMAND_MEM_SIZE];
- uint32_t read_ptr;
- uint32_t write_ptr;
- SyncSemaphore sync_sems[SYNC_SEMAPHORES];
- Mutex *mutex;
- Semaphore *sync;
- template <class T>
- T *allocate() {
- // alloc size is size+T+safeguard
- uint32_t alloc_size = sizeof(T) + sizeof(uint32_t);
- tryagain:
- if (write_ptr < read_ptr) {
- // behind read_ptr, check that there is room
- if ((read_ptr - write_ptr) <= alloc_size)
- return NULL;
- } else if (write_ptr >= read_ptr) {
- // ahead of read_ptr, check that there is room
- if ((COMMAND_MEM_SIZE - write_ptr) < alloc_size + 4) {
- // no room at the end, wrap down;
- if (read_ptr == 0) // dont want write_ptr to become read_ptr
- return NULL;
- // if this happens, it's a bug
- ERR_FAIL_COND_V((COMMAND_MEM_SIZE - write_ptr) < sizeof(uint32_t), NULL);
- // zero means, wrap to begining
- uint32_t *p = (uint32_t *)&command_mem[write_ptr];
- *p = 0;
- write_ptr = 0;
- goto tryagain;
- }
- }
- // allocate the size
- uint32_t *p = (uint32_t *)&command_mem[write_ptr];
- *p = sizeof(T);
- write_ptr += sizeof(uint32_t);
- // allocate the command
- T *cmd = memnew_placement(&command_mem[write_ptr], T);
- write_ptr += sizeof(T);
- return cmd;
- }
- template <class T>
- T *allocate_and_lock() {
- lock();
- T *ret;
- while ((ret = allocate<T>()) == NULL) {
- unlock();
- // sleep a little until fetch happened and some room is made
- wait_for_flush();
- lock();
- }
- return ret;
- }
- bool flush_one() {
- tryagain:
- // tried to read an empty queue
- if (read_ptr == write_ptr)
- return false;
- uint32_t size = *(uint32_t *)(&command_mem[read_ptr]);
- if (size == 0) {
- //end of ringbuffer, wrap
- read_ptr = 0;
- goto tryagain;
- }
- read_ptr += sizeof(uint32_t);
- CommandBase *cmd = reinterpret_cast<CommandBase *>(&command_mem[read_ptr]);
- cmd->call();
- cmd->~CommandBase();
- read_ptr += size;
- return true;
- }
- void lock();
- void unlock();
- void wait_for_flush();
- SyncSemaphore *_alloc_sync_sem();
- public:
- /* NORMAL PUSH COMMANDS */
- template <class T, class M>
- void push(T *p_instance, M p_method) {
- Command0<T, M> *cmd = allocate_and_lock<Command0<T, M> >();
- cmd->instance = p_instance;
- cmd->method = p_method;
- unlock();
- if (sync) sync->post();
- }
- template <class T, class M, class P1>
- void push(T *p_instance, M p_method, P1 p1) {
- Command1<T, M, P1> *cmd = allocate_and_lock<Command1<T, M, P1> >();
- cmd->instance = p_instance;
- cmd->method = p_method;
- cmd->p1 = p1;
- unlock();
- if (sync) sync->post();
- }
- template <class T, class M, class P1, class P2>
- void push(T *p_instance, M p_method, P1 p1, P2 p2) {
- Command2<T, M, P1, P2> *cmd = allocate_and_lock<Command2<T, M, P1, P2> >();
- cmd->instance = p_instance;
- cmd->method = p_method;
- cmd->p1 = p1;
- cmd->p2 = p2;
- unlock();
- if (sync) sync->post();
- }
- template <class T, class M, class P1, class P2, class P3>
- void push(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3) {
- Command3<T, M, P1, P2, P3> *cmd = allocate_and_lock<Command3<T, M, P1, P2, P3> >();
- cmd->instance = p_instance;
- cmd->method = p_method;
- cmd->p1 = p1;
- cmd->p2 = p2;
- cmd->p3 = p3;
- unlock();
- if (sync) sync->post();
- }
- template <class T, class M, class P1, class P2, class P3, class P4>
- void push(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4) {
- Command4<T, M, P1, P2, P3, P4> *cmd = allocate_and_lock<Command4<T, M, P1, P2, P3, P4> >();
- cmd->instance = p_instance;
- cmd->method = p_method;
- cmd->p1 = p1;
- cmd->p2 = p2;
- cmd->p3 = p3;
- cmd->p4 = p4;
- unlock();
- if (sync) sync->post();
- }
- template <class T, class M, class P1, class P2, class P3, class P4, class P5>
- void push(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
- Command5<T, M, P1, P2, P3, P4, P5> *cmd = allocate_and_lock<Command5<T, M, P1, P2, P3, P4, P5> >();
- cmd->instance = p_instance;
- cmd->method = p_method;
- cmd->p1 = p1;
- cmd->p2 = p2;
- cmd->p3 = p3;
- cmd->p4 = p4;
- cmd->p5 = p5;
- unlock();
- if (sync) sync->post();
- }
- template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6>
- void push(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {
- Command6<T, M, P1, P2, P3, P4, P5, P6> *cmd = allocate_and_lock<Command6<T, M, P1, P2, P3, P4, P5, P6> >();
- cmd->instance = p_instance;
- cmd->method = p_method;
- cmd->p1 = p1;
- cmd->p2 = p2;
- cmd->p3 = p3;
- cmd->p4 = p4;
- cmd->p5 = p5;
- cmd->p6 = p6;
- unlock();
- if (sync) sync->post();
- }
- template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7>
- void push(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) {
- Command7<T, M, P1, P2, P3, P4, P5, P6, P7> *cmd = allocate_and_lock<Command7<T, M, P1, P2, P3, P4, P5, P6, P7> >();
- cmd->instance = p_instance;
- cmd->method = p_method;
- cmd->p1 = p1;
- cmd->p2 = p2;
- cmd->p3 = p3;
- cmd->p4 = p4;
- cmd->p5 = p5;
- cmd->p6 = p6;
- cmd->p7 = p7;
- unlock();
- if (sync) sync->post();
- }
- template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
- void push(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) {
- 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> >();
- cmd->instance = p_instance;
- cmd->method = p_method;
- cmd->p1 = p1;
- cmd->p2 = p2;
- cmd->p3 = p3;
- cmd->p4 = p4;
- cmd->p5 = p5;
- cmd->p6 = p6;
- cmd->p7 = p7;
- cmd->p8 = p8;
- unlock();
- if (sync) sync->post();
- }
- /*** PUSH AND RET COMMANDS ***/
- template <class T, class M, class R>
- void push_and_ret(T *p_instance, M p_method, R *r_ret) {
- SyncSemaphore *ss = _alloc_sync_sem();
- CommandRet0<T, M, R> *cmd = allocate_and_lock<CommandRet0<T, M, R> >();
- cmd->instance = p_instance;
- cmd->method = p_method;
- cmd->ret = r_ret;
- cmd->sync = ss;
- unlock();
- if (sync) sync->post();
- ss->sem->wait();
- }
- template <class T, class M, class P1, class R>
- void push_and_ret(T *p_instance, M p_method, P1 p1, R *r_ret) {
- SyncSemaphore *ss = _alloc_sync_sem();
- CommandRet1<T, M, P1, R> *cmd = allocate_and_lock<CommandRet1<T, M, P1, R> >();
- cmd->instance = p_instance;
- cmd->method = p_method;
- cmd->p1 = p1;
- cmd->ret = r_ret;
- cmd->sync = ss;
- unlock();
- if (sync) sync->post();
- ss->sem->wait();
- }
- template <class T, class M, class P1, class P2, class R>
- void push_and_ret(T *p_instance, M p_method, P1 p1, P2 p2, R *r_ret) {
- SyncSemaphore *ss = _alloc_sync_sem();
- CommandRet2<T, M, P1, P2, R> *cmd = allocate_and_lock<CommandRet2<T, M, P1, P2, R> >();
- cmd->instance = p_instance;
- cmd->method = p_method;
- cmd->p1 = p1;
- cmd->p2 = p2;
- cmd->ret = r_ret;
- cmd->sync = ss;
- unlock();
- if (sync) sync->post();
- ss->sem->wait();
- }
- template <class T, class M, class P1, class P2, class P3, class R>
- void push_and_ret(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, R *r_ret) {
- SyncSemaphore *ss = _alloc_sync_sem();
- CommandRet3<T, M, P1, P2, P3, R> *cmd = allocate_and_lock<CommandRet3<T, M, P1, P2, P3, R> >();
- cmd->instance = p_instance;
- cmd->method = p_method;
- cmd->p1 = p1;
- cmd->p2 = p2;
- cmd->p3 = p3;
- cmd->ret = r_ret;
- cmd->sync = ss;
- unlock();
- if (sync) sync->post();
- ss->sem->wait();
- }
- template <class T, class M, class P1, class P2, class P3, class P4, class R>
- void push_and_ret(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, R *r_ret) {
- SyncSemaphore *ss = _alloc_sync_sem();
- CommandRet4<T, M, P1, P2, P3, P4, R> *cmd = allocate_and_lock<CommandRet4<T, M, P1, P2, P3, P4, R> >();
- cmd->instance = p_instance;
- cmd->method = p_method;
- cmd->p1 = p1;
- cmd->p2 = p2;
- cmd->p3 = p3;
- cmd->p4 = p4;
- cmd->ret = r_ret;
- cmd->sync = ss;
- unlock();
- if (sync) sync->post();
- ss->sem->wait();
- }
- template <class T, class M, class P1, class P2, class P3, class P4, class P5, class R>
- void push_and_ret(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, R *r_ret) {
- SyncSemaphore *ss = _alloc_sync_sem();
- CommandRet5<T, M, P1, P2, P3, P4, P5, R> *cmd = allocate_and_lock<CommandRet5<T, M, P1, P2, P3, P4, P5, R> >();
- cmd->instance = p_instance;
- cmd->method = p_method;
- cmd->p1 = p1;
- cmd->p2 = p2;
- cmd->p3 = p3;
- cmd->p4 = p4;
- cmd->p5 = p5;
- cmd->ret = r_ret;
- cmd->sync = ss;
- unlock();
- if (sync) sync->post();
- ss->sem->wait();
- }
- template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class R>
- 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) {
- SyncSemaphore *ss = _alloc_sync_sem();
- CommandRet6<T, M, P1, P2, P3, P4, P5, P6, R> *cmd = allocate_and_lock<CommandRet6<T, M, P1, P2, P3, P4, P5, P6, R> >();
- cmd->instance = p_instance;
- cmd->method = p_method;
- cmd->p1 = p1;
- cmd->p2 = p2;
- cmd->p3 = p3;
- cmd->p4 = p4;
- cmd->p5 = p5;
- cmd->p6 = p6;
- cmd->ret = r_ret;
- cmd->sync = ss;
- unlock();
- if (sync) sync->post();
- ss->sem->wait();
- }
- template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class R>
- 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) {
- SyncSemaphore *ss = _alloc_sync_sem();
- 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> >();
- cmd->instance = p_instance;
- cmd->method = p_method;
- cmd->p1 = p1;
- cmd->p2 = p2;
- cmd->p3 = p3;
- cmd->p4 = p4;
- cmd->p5 = p5;
- cmd->p6 = p6;
- cmd->p7 = p7;
- cmd->ret = r_ret;
- cmd->sync = ss;
- unlock();
- if (sync) sync->post();
- ss->sem->wait();
- }
- template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class R>
- 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) {
- SyncSemaphore *ss = _alloc_sync_sem();
- 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> >();
- cmd->instance = p_instance;
- cmd->method = p_method;
- cmd->p1 = p1;
- cmd->p2 = p2;
- cmd->p3 = p3;
- cmd->p4 = p4;
- cmd->p5 = p5;
- cmd->p6 = p6;
- cmd->p7 = p7;
- cmd->p8 = p8;
- cmd->ret = r_ret;
- cmd->sync = ss;
- unlock();
- if (sync) sync->post();
- ss->sem->wait();
- }
- template <class T, class M>
- void push_and_sync(T *p_instance, M p_method) {
- SyncSemaphore *ss = _alloc_sync_sem();
- CommandSync0<T, M> *cmd = allocate_and_lock<CommandSync0<T, M> >();
- cmd->instance = p_instance;
- cmd->method = p_method;
- cmd->sync = ss;
- unlock();
- if (sync) sync->post();
- ss->sem->wait();
- }
- template <class T, class M, class P1>
- void push_and_sync(T *p_instance, M p_method, P1 p1) {
- SyncSemaphore *ss = _alloc_sync_sem();
- CommandSync1<T, M, P1> *cmd = allocate_and_lock<CommandSync1<T, M, P1> >();
- cmd->instance = p_instance;
- cmd->method = p_method;
- cmd->p1 = p1;
- cmd->sync = ss;
- unlock();
- if (sync) sync->post();
- ss->sem->wait();
- }
- template <class T, class M, class P1, class P2>
- void push_and_sync(T *p_instance, M p_method, P1 p1, P2 p2) {
- SyncSemaphore *ss = _alloc_sync_sem();
- CommandSync2<T, M, P1, P2> *cmd = allocate_and_lock<CommandSync2<T, M, P1, P2> >();
- cmd->instance = p_instance;
- cmd->method = p_method;
- cmd->p1 = p1;
- cmd->p2 = p2;
- cmd->sync = ss;
- unlock();
- if (sync) sync->post();
- ss->sem->wait();
- }
- template <class T, class M, class P1, class P2, class P3>
- void push_and_sync(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3) {
- SyncSemaphore *ss = _alloc_sync_sem();
- CommandSync3<T, M, P1, P2, P3> *cmd = allocate_and_lock<CommandSync3<T, M, P1, P2, P3> >();
- cmd->instance = p_instance;
- cmd->method = p_method;
- cmd->p1 = p1;
- cmd->p2 = p2;
- cmd->p3 = p3;
- cmd->sync = ss;
- unlock();
- if (sync) sync->post();
- ss->sem->wait();
- }
- template <class T, class M, class P1, class P2, class P3, class P4>
- void push_and_sync(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4) {
- SyncSemaphore *ss = _alloc_sync_sem();
- CommandSync4<T, M, P1, P2, P3, P4> *cmd = allocate_and_lock<CommandSync4<T, M, P1, P2, P3, P4> >();
- cmd->instance = p_instance;
- cmd->method = p_method;
- cmd->p1 = p1;
- cmd->p2 = p2;
- cmd->p3 = p3;
- cmd->p4 = p4;
- cmd->sync = ss;
- unlock();
- if (sync) sync->post();
- ss->sem->wait();
- }
- template <class T, class M, class P1, class P2, class P3, class P4, class P5>
- void push_and_sync(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
- SyncSemaphore *ss = _alloc_sync_sem();
- CommandSync5<T, M, P1, P2, P3, P4, P5> *cmd = allocate_and_lock<CommandSync5<T, M, P1, P2, P3, P4, P5> >();
- cmd->instance = p_instance;
- cmd->method = p_method;
- cmd->p1 = p1;
- cmd->p2 = p2;
- cmd->p3 = p3;
- cmd->p4 = p4;
- cmd->p5 = p5;
- cmd->sync = ss;
- unlock();
- if (sync) sync->post();
- ss->sem->wait();
- }
- template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6>
- void push_and_sync(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {
- SyncSemaphore *ss = _alloc_sync_sem();
- CommandSync6<T, M, P1, P2, P3, P4, P5, P6> *cmd = allocate_and_lock<CommandSync6<T, M, P1, P2, P3, P4, P5, P6> >();
- cmd->instance = p_instance;
- cmd->method = p_method;
- cmd->p1 = p1;
- cmd->p2 = p2;
- cmd->p3 = p3;
- cmd->p4 = p4;
- cmd->p5 = p5;
- cmd->p6 = p6;
- cmd->sync = ss;
- unlock();
- if (sync) sync->post();
- ss->sem->wait();
- }
- template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7>
- void push_and_sync(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) {
- SyncSemaphore *ss = _alloc_sync_sem();
- CommandSync7<T, M, P1, P2, P3, P4, P5, P6, P7> *cmd = allocate_and_lock<CommandSync7<T, M, P1, P2, P3, P4, P5, P6, P7> >();
- cmd->instance = p_instance;
- cmd->method = p_method;
- cmd->p1 = p1;
- cmd->p2 = p2;
- cmd->p3 = p3;
- cmd->p4 = p4;
- cmd->p5 = p5;
- cmd->p6 = p6;
- cmd->p7 = p7;
- cmd->sync = ss;
- unlock();
- if (sync) sync->post();
- ss->sem->wait();
- }
- template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
- 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) {
- SyncSemaphore *ss = _alloc_sync_sem();
- 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> >();
- cmd->instance = p_instance;
- cmd->method = p_method;
- cmd->p1 = p1;
- cmd->p2 = p2;
- cmd->p3 = p3;
- cmd->p4 = p4;
- cmd->p5 = p5;
- cmd->p6 = p6;
- cmd->p7 = p7;
- cmd->p8 = p8;
- cmd->sync = ss;
- unlock();
- if (sync) sync->post();
- ss->sem->wait();
- }
- void wait_and_flush_one() {
- ERR_FAIL_COND(!sync);
- sync->wait();
- lock();
- flush_one();
- unlock();
- }
- void flush_all() {
- //ERR_FAIL_COND(sync);
- lock();
- while (true) {
- bool exit = !flush_one();
- if (exit)
- break;
- }
- unlock();
- }
- CommandQueueMT(bool p_sync);
- ~CommandQueueMT();
- };
- #endif
|