csutil/threadmanager.h Source File (Crystal Space 2.0 Public API Reference)

| ## Public API Reference

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

csutil/threadmanager.h

    00001 /*
    00002   Copyright (C) 2008 by Michael Gist
    00003
    00004   This library is free software; you can redistribute it and/or
    00005   modify it under the terms of the GNU Lesser General Public
    00006   License as published by the Free Software Foundation; either
    00007   version 2 of the License, or (at your option) any later version.
    00008
    00009   This library is distributed in the hope that it will be useful,
    00010   but WITHOUT ANY WARRANTY; without even the implied warranty of
    00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00012   Library General Public License for more details.
    00013
    00014   You should have received a copy of the GNU Library General Public
    00015   License along with this library; if not, write to the Free
    00016   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    00017 */
    00018
    00019 #ifndef __CS_CSUTIL_THREADMANAGER_H__
    00020 #define __CS_CSUTIL_THREADMANAGER_H__
    00021
    00022 #include "csutil/eventhandlers.h"
    00023 #include "csutil/objreg.h"
    00024 #include "csutil/threadevent.h"
    00025 #include "csutil/threadjobqueue.h"
    00026 #include "iengine/engine.h"
    00027 #include "imap/loader.h"
    00028 #include "iutil/event.h"
    00029 #include "iutil/eventh.h"
    00030 #include "iutil/eventq.h"
    00031 #include "iutil/threadmanager.h"
    00032
    00033 struct iEvent;
    00034
    00035 class CS_CRYSTALSPACE_EXPORT csThreadManager : public scfImplementation1<csThreadManager,
    00036   iThreadManager>
    00037 {
    00038   class ListAccessQueue : public csRefCount
    00039   {
    00040   public:
    00041     ListAccessQueue();
    00042     ~ListAccessQueue();
    00043
    00044     void Enqueue(iJob* job, QueueType type);
    00045     void ProcessQueue(uint num);
    00046     int32 GetQueueCount() const;
    00047     void ProcessAll ();
    00048   private:
    00049     inline void ProcessHighQueue(uint& i, uint& num);
    00050     inline void ProcessMedQueue(uint& i, uint& num);
    00051     inline void ProcessLowQueue(uint& i, uint& num);
    00052
    00053     CS::Threading::RecursiveMutex highQueueLock;
    00054     CS::Threading::RecursiveMutex medQueueLock;
    00055     CS::Threading::RecursiveMutex lowQueueLock;
    00056     csFIFO<csRef<iJob> > highqueue;
    00057     csFIFO<csRef<iJob> > medqueue;
    00058     csFIFO<csRef<iJob> > lowqueue;
    00059     int32 total;
    00060   };
    00061 public:
    00062   csThreadManager(iObjectRegistry* objReg);
    00063   virtual ~csThreadManager();
    00064   void Init(iConfigManager* config);
    00065
    00066   void Process(uint num = 1);
    00067   bool Wait(csRefArray<iThreadReturn>& threadReturns, bool process = true);
    00068
    00070   void ProcessAll ();
    00071
    00072   inline void PushToQueue(QueueType queueType, iJob* job)
    00073   {
    00074     if(queueType == THREADED || queueType == THREADEDL)
    00075     {
    00076       {
    00077         CS::Threading::MutexScopedLock lock(waitingThreadsLock);
    00078         threadQueue->Enqueue(job);
    00079       }
    00080
    00081       for(size_t i=0; i<waitingThreads.GetSize(); ++i)
    00082       {
    00083         waitingThreads[i]->NotifyAll();
    00084       }
    00085     }
    00086     else
    00087     {
    00088       {
    00089         CS::Threading::MutexScopedLock lock(waitingMainLock);
    00090         listQueue->Enqueue(job, queueType);
    00091       }
    00092       waitingMain.NotifyOne();
    00093     }
    00094   }
    00095
    00096   inline bool RunNow(QueueType queueType, bool wait, bool forceQueue)
    00097   {
    00098     // True if we're executing something to be run in the main thread,
    00099     // and we are the main thread, and we're not forcing it to be put on a queue for later.
    00100     bool noThread = alwaysRunNow || (IsMainThread() && queueType != THREADED && queueType != THREADEDL && !forceQueue);
    00101
    00102     // True if we're executing something to not be run in the main thread, while all other threads are busy.
    00103     bool runNow = noThread || ((queueType == THREADED || queueType == THREADEDL) && !IsMainThread() && ((waiting >= threadCount-1) ||
    00104         (threadQueue->GetQueueCount() > 2*threadCount-1) || wait));
    00105
    00106     return runNow;
    00107   }
    00108
    00109   inline int32 GetThreadCount()
    00110   {
    00111     return threadCount;
    00112   }
    00113
    00114   inline void SetAlwaysRunNow(bool v)
    00115   {
    00116     alwaysRunNow = v;
    00117   }
    00118
    00119   inline bool GetAlwaysRunNow()
    00120   {
    00121     return alwaysRunNow;
    00122   }
    00123
    00124   inline bool Exiting()
    00125   {
    00126     return exiting;
    00127   }
    00128
    00129 protected:
    00130   csEventID ProcessPerFrame;
    00131
    00132 private:
    00133
    00134   static CS::Threading::ThreadID tid;
    00135
    00136   inline bool IsMainThread()
    00137   {
    00138     return tid == CS::Threading::Thread::GetThreadID();
    00139   }
    00140
    00141   CS::Threading::Mutex waitingMainLock;
    00142   CS::Threading::Condition waitingMain;
    00143
    00144   CS::Threading::Mutex waitingThreadsLock;
    00145   csArray<CS::Threading::Condition*> waitingThreads;
    00146
    00147   int32 waiting;
    00148   int32 threadCount;
    00149   bool alwaysRunNow;
    00150
    00151   iObjectRegistry* objectReg;
    00152   csRef<CS::Threading::ThreadedJobQueue> threadQueue;
    00153   csRef<ListAccessQueue> listQueue;
    00154   csRef<iEventQueue> eventQueue;
    00155   csTicks waitingTime;
    00156   bool exiting;
    00157
    00158   class TMEventHandler : public scfImplementation1<TMEventHandler,
    00159       iEventHandler>
    00160   {
    00161   public:
    00162     TMEventHandler(csThreadManager* parent) :
    00163         scfImplementationType (this), parent (parent)
    00164     {
    00165     }
    00166
    00167     virtual ~TMEventHandler()
    00168     {
    00169     }
    00170
    00171     bool HandleEvent(iEvent& Event)
    00172     {
    00173       if(Event.Name == parent->ProcessPerFrame)
    00174       {
    00175         if(!parent->alwaysRunNow)
    00176         {
    00177           parent->Process(5);
    00178         }
    00179       }
    00180       return false;
    00181     }
    00182
    00183     CS_EVENTHANDLER_PHASE_LOGIC("crystalspace.threadmanager")
    00184
    00185   private:
    00186     csThreadManager* parent;
    00187   };
    00188   csRef<iEventHandler> tMEventHandler;
    00189 };
    00190
    00191 class csThreadReturn : public scfImplementation1<csThreadReturn, iThreadReturn>
    00192 {
    00193 public:
    00194   csThreadReturn(iThreadManager* tm) : scfImplementationType(this),
    00195     finished(false), success(false), result(0), tm(tm), waitLock(0),
    00196     wait(0)
    00197   {
    00198   }
    00199
    00200   virtual ~csThreadReturn()
    00201   {
    00202   }
    00203
    00204   bool IsFinished()
    00205   {
    00206     CS::Threading::MutexScopedLock lock(updateLock);
    00207     return finished;
    00208   }
    00209
    00210   bool WasSuccessful()
    00211   {
    00212     CS::Threading::MutexScopedLock lock(updateLock);
    00213     return success;
    00214   }
    00215
    00216   void* GetResultPtr() { return result; }
    00217   csRef<iBase> GetResultRefPtr() { return refResult; }
    00218
    00219   void MarkFinished()
    00220   {
    00221     if(waitLock)
    00222       waitLock->Lock();
    00223
    00224     {
    00225       CS::Threading::MutexScopedLock ulock(updateLock);
    00226       finished = true;
    00227       if(wait)
    00228       {
    00229          wait->NotifyAll();
    00230       }
    00231     }
    00232
    00233     if(waitLock)
    00234       waitLock->Unlock();
    00235   }
    00236
    00237   void MarkSuccessful()
    00238   {
    00239     CS::Threading::MutexScopedLock lock(updateLock);
    00240     success = true;
    00241   }
    00242
    00243   void SetResult(void* result) { this->result = result; }
    00244   void SetResult(csRef<iBase> result) { refResult = result; }
    00245
    00246   void Copy(iThreadReturn* other)
    00247   {
    00248     result = other->GetResultPtr();
    00249     refResult = other->GetResultRefPtr();
    00250     finished = other->IsFinished();
    00251   }
    00252
    00253   void Wait(bool process = true)
    00254   {
    00255     if(tm.IsValid())
    00256     {
    00257       csRefArray<iThreadReturn> rets;
    00258       rets.Push(this);
    00259       tm->Wait(rets, process);
    00260     }
    00261   }
    00262
    00263   void SetWaitPtrs(CS::Threading::Condition* c, CS::Threading::Mutex* m)
    00264   {
    00265     CS::Threading::MutexScopedLock lock(updateLock);
    00266     wait = c;
    00267     waitLock = m;
    00268   }
    00269
    00270   void SetJob(iJob* j)
    00271   {
    00272       job = j;
    00273   }
    00274
    00275   iJob* GetJob() const
    00276   {
    00277       return job;
    00278   }
    00279
    00280 private:
    00281   bool finished;
    00282   bool success;
    00283   void* result;
    00284   csRef<iBase> refResult;
    00285   csWeakRef<iThreadManager> tm;
    00286   CS::Threading::Mutex* waitLock;
    00287   CS::Threading::Condition* wait;
    00288   CS::Threading::Mutex updateLock;
    00289   csRef<iJob> job;
    00290 };
    00291
    00292 template<class T, typename A1, typename A2>
    00293 csPtr<iJob> QueueEvent(csRef<iThreadManager> tm, ThreadedCallable<T>* object, bool (T::*method)(A1, A2), void const** &argsTC, QueueType queueType)
    00294 {
    00295   csRef<ThreadEvent2<T, A1, A2> > threadEvent;
    00296   threadEvent.AttachNew(new ThreadEvent2<T, A1, A2>(object, method, argsTC));
    00297   tm->PushToQueue(queueType, threadEvent);
    00298   return csPtr<iJob>(threadEvent);
    00299 }
    00300
    00301 template<class T, typename A1, typename A2, typename A3>
    00302 csPtr<iJob> QueueEvent(csRef<iThreadManager> tm, ThreadedCallable<T>* object, bool (T::*method)(A1, A2, A3), void const** &argsTC, QueueType queueType)
    00303 {
    00304   csRef<ThreadEvent3<T, A1, A2, A3> > threadEvent;
    00305   threadEvent.AttachNew(new ThreadEvent3<T, A1, A2, A3>(object, method, argsTC));
    00306   tm->PushToQueue(queueType, threadEvent);
    00307   return csPtr<iJob>(threadEvent);
    00308 }
    00309
    00310 template<class T, typename A1, typename A2, typename A3, typename A4>
    00311 csPtr<iJob> QueueEvent(csRef<iThreadManager> tm, ThreadedCallable<T>* object, bool (T::*method)(A1, A2, A3, A4), void const** &argsTC, QueueType queueType)
    00312 {
    00313   csRef<ThreadEvent4<T, A1, A2, A3, A4> > threadEvent;
    00314   threadEvent.AttachNew(new ThreadEvent4<T, A1, A2, A3, A4>(object, method, argsTC));
    00315   tm->PushToQueue(queueType, threadEvent);
    00316   return csPtr<iJob>(threadEvent);
    00317 }
    00318
    00319 template<class T, typename A1, typename A2, typename A3, typename A4, typename A5>
    00320 csPtr<iJob> QueueEvent(csRef<iThreadManager> tm, ThreadedCallable<T>* object, bool (T::*method)(A1, A2, A3, A4, A5), void const** &argsTC, QueueType queueType)
    00321 {
    00322   csRef<ThreadEvent5<T, A1, A2, A3, A4, A5> > threadEvent;
    00323   threadEvent.AttachNew(new ThreadEvent5<T, A1, A2, A3, A4, A5>(object, method, argsTC));
    00324   tm->PushToQueue(queueType, threadEvent);
    00325   return csPtr<iJob>(threadEvent);
    00326 }
    00327
    00328 template<class T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
    00329 csPtr<iJob> QueueEvent(csRef<iThreadManager> tm, ThreadedCallable<T>* object, bool (T::*method)(A1, A2, A3, A4, A5, A6), void const** &argsTC, QueueType queueType)
    00330 {
    00331   csRef<ThreadEvent6<T, A1, A2, A3, A4, A5, A6> > threadEvent;
    00332   threadEvent.AttachNew(new ThreadEvent6<T, A1, A2, A3, A4, A5, A6>(object, method, argsTC));
    00333   tm->PushToQueue(queueType, threadEvent);
    00334   return csPtr<iJob>(threadEvent);
    00335 }
    00336
    00337 template<class T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
    00338 csPtr<iJob> QueueEvent(csRef<iThreadManager> tm, ThreadedCallable<T>* object, bool (T::*method)(A1, A2, A3, A4, A5, A6, A7), void const** &argsTC, QueueType queueType)
    00339 {
    00340   csRef<ThreadEvent7<T, A1, A2, A3, A4, A5, A6, A7> > threadEvent;
    00341   threadEvent.AttachNew(new ThreadEvent7<T, A1, A2, A3, A4, A5, A6, A7>(object, method, argsTC));
    00342   tm->PushToQueue(queueType, threadEvent);
    00343   return csPtr<iJob>(threadEvent);
    00344 }
    00345
    00346 template<class T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
    00347 csPtr<iJob> QueueEvent(csRef<iThreadManager> tm, ThreadedCallable<T>* object, bool (T::*method)(A1, A2, A3, A4, A5, A6, A7, A8), void const** &argsTC, QueueType queueType)
    00348 {
    00349   csRef<ThreadEvent8<T, A1, A2, A3, A4, A5, A6, A7, A8> > threadEvent;
    00350   threadEvent.AttachNew(new ThreadEvent8<T, A1, A2, A3, A4, A5, A6, A7, A8>(object, method, argsTC));
    00351   tm->PushToQueue(queueType, threadEvent);
    00352   return csPtr<iJob>(threadEvent);
    00353 }
    00354
    00355 template<class T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
    00356 csPtr<iJob> QueueEvent(csRef<iThreadManager> tm, ThreadedCallable<T>* object, bool (T::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9), void const** &argsTC, QueueType queueType)
    00357 {
    00358   csRef<ThreadEvent9<T, A1, A2, A3, A4, A5, A6, A7, A8, A9> > threadEvent;
    00359   threadEvent.AttachNew(new ThreadEvent9<T, A1, A2, A3, A4, A5, A6, A7, A8, A9>(object, method, argsTC));
    00360   tm->PushToQueue(queueType, threadEvent);
    00361   return csPtr<iJob>(threadEvent);
    00362 }
    00363
    00364 template<class T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10>
    00365 csPtr<iJob> QueueEvent(csRef<iThreadManager> tm, ThreadedCallable<T>* object, bool (T::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10), void const** &argsTC, QueueType queueType)
    00366 {
    00367   csRef<ThreadEvent10<T, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10> > threadEvent;
    00368   threadEvent.AttachNew(new ThreadEvent10<T, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>(object, method, argsTC));
    00369   tm->PushToQueue(queueType, threadEvent);
    00370   return csPtr<iJob>(threadEvent);
    00371 }
    00372
    00373 template<class T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11>
    00374 csPtr<iJob> QueueEvent(csRef<iThreadManager> tm, ThreadedCallable<T>* object, bool (T::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11), void const** &argsTC, QueueType queueType)
    00375 {
    00376   csRef<ThreadEvent11<T, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11> > threadEvent;
    00377   threadEvent.AttachNew(new ThreadEvent11<T, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>(object, method, argsTC));
    00378   tm->PushToQueue(queueType, threadEvent);
    00379   return csPtr<iJob>(threadEvent);
    00380 }
    00381
    00382 template<class T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12>
    00383 csPtr<iJob> QueueEvent(csRef<iThreadManager> tm, ThreadedCallable<T>* object, bool (T::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12), void const** &argsTC, QueueType queueType)
    00384 {
    00385   csRef<ThreadEvent12<T, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12> > threadEvent;
    00386   threadEvent.AttachNew(new ThreadEvent12<T, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12>(object, method, argsTC));
    00387   tm->PushToQueue(queueType, threadEvent);
    00388   return csPtr<iJob>(threadEvent);
    00389 }
    00390
    00391 template<class T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename A13>
    00392 csPtr<iJob> QueueEvent(csRef<iThreadManager> tm, ThreadedCallable<T>* object, bool (T::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13), void const** &argsTC, QueueType queueType)
    00393 {
    00394   csRef<ThreadEvent13<T, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13> > threadEvent;
    00395   threadEvent.AttachNew(new ThreadEvent13<T, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13>(object, method, argsTC));
    00396   tm->PushToQueue(queueType, threadEvent);
    00397   return csPtr<iJob>(threadEvent);
    00398 }
    00399
    00400 template<class T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename A13, typename A14>
    00401 csPtr<iJob> QueueEvent(csRef<iThreadManager> tm, ThreadedCallable<T>* object, bool (T::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14), void const** &argsTC, QueueType queueType)
    00402 {
    00403   csRef<ThreadEvent14<T, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14> > threadEvent;
    00404   threadEvent.AttachNew(new ThreadEvent14<T, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14>(object, method, argsTC));
    00405   tm->PushToQueue(queueType, threadEvent);
    00406   return csPtr<iJob>(threadEvent);
    00407 }
    00408
    00409 template<class T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename A13, typename A14, typename A15>
    00410 csPtr<iJob> QueueEvent(csRef<iThreadManager> tm, ThreadedCallable<T>* object, bool (T::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15), void const** &argsTC, QueueType queueType)
    00411 {
    00412   csRef<ThreadEvent15<T, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15> > threadEvent;
    00413   threadEvent.AttachNew(new ThreadEvent15<T, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15>(object, method, argsTC));
    00414   tm->PushToQueue(queueType, threadEvent);
    00415   return csPtr<iJob>(threadEvent);
    00416 }
    00417
    00418 #define THREADED_CALLABLE_DECL(type, function, returnClass, queueType, wait, forceQueue) \
    00419   bool function##TC(csRef<iThreadReturn> ret, bool sync); \
    00420   inline csRef<iThreadReturn> function##Wait() \
    00421 { \
    00422   const type* objTC = const_cast<const type*>(this); \
    00423   return objTC->function##Wait(); \
    00424 } \
    00425   inline csRef<iThreadReturn> function##Wait() const \
    00426 { \
    00427   return function##T(true); \
    00428 } \
    00429   inline csRef<iThreadReturn> function() \
    00430 { \
    00431   const type* objTC = const_cast<const type*>(this); \
    00432   return objTC->function(); \
    00433 } \
    00434   inline csRef<iThreadReturn> function() const \
    00435 { \
    00436   return function##T(false); \
    00437 } \
    00438   inline csRef<iThreadReturn> function##T(bool Wait) const \
    00439 { \
    00440   csRef<iThreadManager> tm = csQueryRegistry<iThreadManager>(GetObjectRegistry()); \
    00441   csRef<iThreadReturn> ret; \
    00442   ret.AttachNew(new returnClass(tm)); \
    00443   if(!tm.IsValid() || tm->Exiting()) \
    00444   { \
    00445     ret->MarkFinished(); \
    00446     return ret; \
    00447   } \
    00448   if(tm->RunNow(queueType, Wait || wait, forceQueue)) \
    00449   { \
    00450     type* objTC = const_cast<type*>(this); \
    00451     if(objTC->function##TC(ret, Wait || wait)) \
    00452     { \
    00453       ret->MarkSuccessful(); \
    00454     } \
    00455     ret->MarkFinished(); \
    00456     return ret; \
    00457   } \
    00458   bool sync = Wait || wait; \
    00459   void const** argsTC = new void const*[3]; \
    00460   TEventMemPool *mempool = new TEventMemPool; \
    00461   argsTC[0] = mempool; \
    00462   argsTC[1] = mempool->Store<csRef<iThreadReturn> >(&ret); \
    00463   argsTC[2] = mempool->Store<bool>(&sync); \
    00464   csRef<iJob> job = QueueEvent<type, csRef<iThreadReturn>, bool>(tm, (ThreadedCallable<type>*)this, &type::function##TC, argsTC, queueType); \
    00465   ret->SetJob(job); \
    00466   if(Wait || wait) \
    00467   { \
    00468     ret->Wait(); \
    00469   } \
    00470   return ret; \
    00471 }
    00472
    00473 #define THREADED_CALLABLE_DECL1(type, function, returnClass, T1, A1, queueType, wait, forceQueue) \
    00474   bool function##TC(csRef<iThreadReturn> ret, bool sync, T1 A1); \
    00475   inline csRef<iThreadReturn> function##Wait(T1 A1) \
    00476 { \
    00477   const type* objTC = const_cast<const type*>(this); \
    00478   return objTC->function##Wait(A1); \
    00479 } \
    00480   inline csRef<iThreadReturn> function##Wait(T1 A1) const \
    00481 { \
    00482   return function##T(true, A1); \
    00483 } \
    00484   inline csRef<iThreadReturn> function(T1 A1) \
    00485 { \
    00486   const type* objTC = const_cast<const type*>(this); \
    00487   return objTC->function(A1); \
    00488 } \
    00489   inline csRef<iThreadReturn> function(T1 A1) const \
    00490 { \
    00491   return function##T(false, A1); \
    00492 } \
    00493   inline csRef<iThreadReturn> function##T(bool Wait, T1 A1) const \
    00494 { \
    00495   csRef<iThreadManager> tm = csQueryRegistry<iThreadManager>(GetObjectRegistry()); \
    00496   csRef<iThreadReturn> ret; \
    00497   ret.AttachNew(new returnClass(tm)); \
    00498   if(!tm.IsValid() || tm->Exiting()) \
    00499   { \
    00500     ret->MarkFinished(); \
    00501     return ret; \
    00502   } \
    00503   if(tm->RunNow(queueType, Wait || wait, forceQueue)) \
    00504   { \
    00505     type* objTC = const_cast<type*>(this); \
    00506     if(objTC->function##TC(ret, Wait || wait, A1)) \
    00507     { \
    00508       ret->MarkSuccessful(); \
    00509     } \
    00510     ret->MarkFinished(); \
    00511     return ret; \
    00512   } \
    00513   bool sync = Wait || wait; \
    00514   void const** argsTC = new void const*[4]; \
    00515   TEventMemPool *mempool = new TEventMemPool; \
    00516   argsTC[0] = mempool; \
    00517   argsTC[1] = mempool->Store<csRef<iThreadReturn> >(&ret); \
    00518   argsTC[2] = mempool->Store<bool>(&sync); \
    00519   argsTC[3] = mempool->Store<T1>(&A1); \
    00520   csRef<iJob> job = QueueEvent<type, csRef<iThreadReturn>, bool, T1>(tm, (ThreadedCallable<type>*)this, &type::function##TC, argsTC, queueType); \
    00521   ret->SetJob(job); \
    00522   if(Wait || wait) \
    00523   { \
    00524     ret->Wait(); \
    00525   } \
    00526   return ret; \
    00527 }
    00528
    00529 #define THREADED_CALLABLE_DECL2(type, function, returnClass, T1, A1, T2, A2, queueType, wait, forceQueue) \
    00530   bool function##TC(csRef<iThreadReturn> ret, bool sync, T1 A1, T2 A2); \
    00531   inline csRef<iThreadReturn> function##Wait(T1 A1, T2 A2) \
    00532 { \
    00533   const type* objTC = const_cast<const type*>(this); \
    00534   return objTC->function##Wait(A1, A2); \
    00535 } \
    00536   inline csRef<iThreadReturn> function##Wait(T1 A1, T2 A2) const \
    00537 { \
    00538   return function##T(true, A1, A2); \
    00539 } \
    00540   inline csRef<iThreadReturn> function(T1 A1, T2 A2) \
    00541 { \
    00542   const type* objTC = const_cast<const type*>(this); \
    00543   return objTC->function(A1, A2); \
    00544 } \
    00545   inline csRef<iThreadReturn> function(T1 A1, T2 A2) const \
    00546 { \
    00547   return function##T(false, A1, A2); \
    00548 } \
    00549   inline csRef<iThreadReturn> function##T(bool Wait, T1 A1, T2 A2) const \
    00550 { \
    00551   csRef<iThreadManager> tm = csQueryRegistry<iThreadManager>(GetObjectRegistry()); \
    00552   csRef<iThreadReturn> ret; \
    00553   ret.AttachNew(new returnClass(tm)); \
    00554   if(!tm.IsValid() || tm->Exiting()) \
    00555   { \
    00556     ret->MarkFinished(); \
    00557     return ret; \
    00558   } \
    00559   if(tm->RunNow(queueType, Wait || wait, forceQueue)) \
    00560   { \
    00561     type* objTC = const_cast<type*>(this); \
    00562     if(objTC->function##TC(ret, Wait || wait, A1, A2)) \
    00563     { \
    00564       ret->MarkSuccessful(); \
    00565     } \
    00566     ret->MarkFinished(); \
    00567     return ret; \
    00568   } \
    00569   bool sync = Wait || wait; \
    00570   void const** argsTC = new void const*[5]; \
    00571   TEventMemPool *mempool = new TEventMemPool; \
    00572   argsTC[0] = mempool; \
    00573   argsTC[1] = mempool->Store<csRef<iThreadReturn> >(&ret); \
    00574   argsTC[2] = mempool->Store<bool>(&sync); \
    00575   argsTC[3] = mempool->Store<T1>(&A1); \
    00576   argsTC[4] = mempool->Store<T2>(&A2); \
    00577   csRef<iJob> job = QueueEvent<type, csRef<iThreadReturn>, bool, T1, T2>(tm, (ThreadedCallable<type>*)this, &type::function##TC, argsTC, queueType); \
    00578   ret->SetJob(job); \
    00579   if(Wait || wait) \
    00580   { \
    00581     ret->Wait(); \
    00582   } \
    00583   return ret; \
    00584 }
    00585
    00586 #define THREADED_CALLABLE_DECL3(type, function, returnClass, T1, A1, T2, A2, T3, A3, queueType, wait, forceQueue) \
    00587   bool function##TC(csRef<iThreadReturn> ret, bool sync, T1 A1, T2 A2, T3 A3); \
    00588   inline csRef<iThreadReturn> function##Wait(T1 A1, T2 A2, T3 A3) \
    00589 { \
    00590   const type* objTC = const_cast<const type*>(this); \
    00591   return objTC->function##Wait(A1, A2, A3); \
    00592 } \
    00593   inline csRef<iThreadReturn> function##Wait(T1 A1, T2 A2, T3 A3) const \
    00594 { \
    00595   return function##T(true, A1, A2, A3); \
    00596 } \
    00597   inline csRef<iThreadReturn> function(T1 A1, T2 A2, T3 A3) \
    00598 { \
    00599   const type* objTC = const_cast<const type*>(this); \
    00600   return objTC->function(A1, A2, A3); \
    00601 } \
    00602   inline csRef<iThreadReturn> function(T1 A1, T2 A2, T3 A3) const \
    00603 { \
    00604   return function##T(false, A1, A2, A3); \
    00605 } \
    00606   inline csRef<iThreadReturn> function##T(bool Wait, T1 A1, T2 A2, T3 A3) const \
    00607 { \
    00608   csRef<iThreadManager> tm = csQueryRegistry<iThreadManager>(GetObjectRegistry()); \
    00609   csRef<iThreadReturn> ret; \
    00610   ret.AttachNew(new returnClass(tm)); \
    00611   if(!tm.IsValid() || tm->Exiting()) \
    00612   { \
    00613     ret->MarkFinished(); \
    00614     return ret; \
    00615   } \
    00616   if(tm->RunNow(queueType, Wait || wait, forceQueue)) \
    00617   { \
    00618     type* objTC = const_cast<type*>(this); \
    00619     if(objTC->function##TC(ret, Wait || wait, A1, A2, A3)) \
    00620     { \
    00621       ret->MarkSuccessful(); \
    00622     } \
    00623     ret->MarkFinished(); \
    00624     return ret; \
    00625   } \
    00626   bool sync = Wait || wait; \
    00627   void const** argsTC = new void const*[6]; \
    00628   TEventMemPool *mempool = new TEventMemPool; \
    00629   argsTC[0] = mempool; \
    00630   argsTC[1] = mempool->Store<csRef<iThreadReturn> >(&ret); \
    00631   argsTC[2] = mempool->Store<bool>(&sync); \
    00632   argsTC[3] = mempool->Store<T1>(&A1); \
    00633   argsTC[4] = mempool->Store<T2>(&A2); \
    00634   argsTC[5] = mempool->Store<T3>(&A3); \
    00635   csRef<iJob> job = QueueEvent<type, csRef<iThreadReturn>, bool, T1, T2, T3>(tm, (ThreadedCallable<type>*)this, &type::function##TC, argsTC, queueType); \
    00636   ret->SetJob(job); \
    00637   if(Wait || wait) \
    00638   { \
    00639     ret->Wait(); \
    00640   } \
    00641   return ret; \
    00642 }
    00643
    00644 #define THREADED_CALLABLE_DECL4(type, function, returnClass, T1, A1, T2, A2, T3, A3, T4, A4, queueType, wait, forceQueue) \
    00645   bool function##TC(csRef<iThreadReturn> ret, bool sync, T1 A1, T2 A2, T3 A3, T4 A4); \
    00646   inline csRef<iThreadReturn> function##Wait(T1 A1, T2 A2, T3 A3, T4 A4) \
    00647 { \
    00648   const type* objTC = const_cast<const type*>(this); \
    00649   return objTC->function##Wait(A1, A2, A3, A4); \
    00650 } \
    00651   inline csRef<iThreadReturn> function##Wait(T1 A1, T2 A2, T3 A3, T4 A4) const \
    00652 { \
    00653   return function##T(true, A1, A2, A3, A4); \
    00654 } \
    00655   inline csRef<iThreadReturn> function(T1 A1, T2 A2, T3 A3, T4 A4) \
    00656 { \
    00657   const type* objTC = const_cast<const type*>(this); \
    00658   return objTC->function(A1, A2, A3, A4); \
    00659 } \
    00660   inline csRef<iThreadReturn> function(T1 A1, T2 A2, T3 A3, T4 A4) const \
    00661 { \
    00662   return function##T(false, A1, A2, A3, A4); \
    00663 } \
    00664   inline csRef<iThreadReturn> function##T(bool Wait, T1 A1, T2 A2, T3 A3, T4 A4) const \
    00665 { \
    00666   csRef<iThreadManager> tm = csQueryRegistry<iThreadManager>(GetObjectRegistry()); \
    00667   csRef<iThreadReturn> ret; \
    00668   ret.AttachNew(new returnClass(tm)); \
    00669   if(!tm.IsValid() || tm->Exiting()) \
    00670   { \
    00671     ret->MarkFinished(); \
    00672     return ret; \
    00673   } \
    00674   if(tm->RunNow(queueType, Wait || wait, forceQueue)) \
    00675   { \
    00676     type* objTC = const_cast<type*>(this); \
    00677     if(objTC->function##TC(ret, Wait || wait, A1, A2, A3, A4)) \
    00678     { \
    00679       ret->MarkSuccessful(); \
    00680     } \
    00681     ret->MarkFinished(); \
    00682     return ret; \
    00683   } \
    00684   bool sync = Wait || wait; \
    00685   void const** argsTC = new void const*[7]; \
    00686   TEventMemPool *mempool = new TEventMemPool; \
    00687   argsTC[0] = mempool; \
    00688   argsTC[1] = mempool->Store<csRef<iThreadReturn> >(&ret); \
    00689   argsTC[2] = mempool->Store<bool>(&sync); \
    00690   argsTC[3] = mempool->Store<T1>(&A1); \
    00691   argsTC[4] = mempool->Store<T2>(&A2); \
    00692   argsTC[5] = mempool->Store<T3>(&A3); \
    00693   argsTC[6] = mempool->Store<T4>(&A4); \
    00694   csRef<iJob> job = QueueEvent<type, csRef<iThreadReturn>, bool, T1, T2, T3, T4>(tm, (ThreadedCallable<type>*)this, &type::function##TC, argsTC, queueType); \
    00695   ret->SetJob(job); \
    00696   if(Wait || wait) \
    00697   { \
    00698     ret->Wait(); \
    00699   } \
    00700   return ret; \
    00701 }
    00702
    00703 #define THREADED_CALLABLE_DECL5(type, function, returnClass, T1, A1, T2, A2, T3, A3, T4, A4, T5, A5, queueType, wait, forceQueue) \
    00704   bool function##TC(csRef<iThreadReturn> ret, bool sync, T1 A1, T2 A2, T3 A3, T4 A4, T5 A5); \
    00705   inline csRef<iThreadReturn> function##Wait(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5) \
    00706 { \
    00707   const type* objTC = const_cast<const type*>(this); \
    00708   return objTC->function##Wait(A1, A2, A3, A4, A5); \
    00709 } \
    00710   inline csRef<iThreadReturn> function##Wait(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5) const \
    00711 { \
    00712   return function##T(true, A1, A2, A3, A4, A5); \
    00713 } \
    00714   inline csRef<iThreadReturn> function(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5) \
    00715 { \
    00716   const type* objTC = const_cast<const type*>(this); \
    00717   return objTC->function(A1, A2, A3, A4, A5); \
    00718 } \
    00719   inline csRef<iThreadReturn> function(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5) const \
    00720 { \
    00721   return function##T(false, A1, A2, A3, A4, A5); \
    00722 } \
    00723   inline csRef<iThreadReturn> function##T(bool Wait, T1 A1, T2 A2, T3 A3, T4 A4, T5 A5) const \
    00724 { \
    00725   csRef<iThreadManager> tm = csQueryRegistry<iThreadManager>(GetObjectRegistry()); \
    00726   csRef<iThreadReturn> ret; \
    00727   ret.AttachNew(new returnClass(tm)); \
    00728   if(!tm.IsValid() || tm->Exiting()) \
    00729   { \
    00730     ret->MarkFinished(); \
    00731     return ret; \
    00732   } \
    00733   if(tm->RunNow(queueType, Wait || wait, forceQueue)) \
    00734   { \
    00735     type* objTC = const_cast<type*>(this); \
    00736     if(objTC->function##TC(ret, Wait || wait, A1, A2, A3, A4, A5)) \
    00737     { \
    00738       ret->MarkSuccessful(); \
    00739     } \
    00740     ret->MarkFinished(); \
    00741     return ret; \
    00742   } \
    00743   bool sync = Wait || wait; \
    00744   void const** argsTC = new void const*[8]; \
    00745   TEventMemPool *mempool = new TEventMemPool; \
    00746   argsTC[0] = mempool; \
    00747   argsTC[1] = mempool->Store<csRef<iThreadReturn> >(&ret); \
    00748   argsTC[2] = mempool->Store<bool>(&sync); \
    00749   argsTC[3] = mempool->Store<T1>(&A1); \
    00750   argsTC[4] = mempool->Store<T2>(&A2); \
    00751   argsTC[5] = mempool->Store<T3>(&A3); \
    00752   argsTC[6] = mempool->Store<T4>(&A4); \
    00753   argsTC[7] = mempool->Store<T5>(&A5); \
    00754   csRef<iJob> job = QueueEvent<type, csRef<iThreadReturn>, bool, T1, T2, T3, T4, T5>(tm, (ThreadedCallable<type>*)this, &type::function##TC, argsTC, queueType); \
    00755   ret->SetJob(job); \
    00756   if(Wait || wait) \
    00757   { \
    00758     ret->Wait(); \
    00759   } \
    00760   return ret; \
    00761 }
    00762
    00763 #define THREADED_CALLABLE_DECL6(type, function, returnClass, T1, A1, T2, A2, T3, A3, T4, A4, T5, A5, T6, A6, queueType, wait, forceQueue) \
    00764   bool function##TC(csRef<iThreadReturn> ret, bool sync, T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6); \
    00765   inline csRef<iThreadReturn> function##Wait(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6) \
    00766 { \
    00767   const type* objTC = const_cast<const type*>(this); \
    00768   return objTC->function##Wait(A1, A2, A3, A4, A5, A6); \
    00769 } \
    00770   inline csRef<iThreadReturn> function##Wait(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6) const \
    00771 { \
    00772   return function##T(true, A1, A2, A3, A4, A5, A6); \
    00773 } \
    00774   inline csRef<iThreadReturn> function(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6) \
    00775 { \
    00776   const type* objTC = const_cast<const type*>(this); \
    00777   return objTC->function(A1, A2, A3, A4, A5, A6); \
    00778 } \
    00779   inline csRef<iThreadReturn> function(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6) const \
    00780 { \
    00781   return function##T(false, A1, A2, A3, A4, A5, A6); \
    00782 } \
    00783   inline csRef<iThreadReturn> function##T(bool Wait, T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6) const \
    00784 { \
    00785   csRef<iThreadManager> tm = csQueryRegistry<iThreadManager>(GetObjectRegistry()); \
    00786   csRef<iThreadReturn> ret; \
    00787   ret.AttachNew(new returnClass(tm)); \
    00788   if(!tm.IsValid() || tm->Exiting()) \
    00789   { \
    00790     ret->MarkFinished(); \
    00791     return ret; \
    00792   } \
    00793   if(tm->RunNow(queueType, Wait || wait, forceQueue)) \
    00794   { \
    00795     type* objTC = const_cast<type*>(this); \
    00796     if(objTC->function##TC(ret, Wait || wait, A1, A2, A3, A4, A5, A6)) \
    00797     { \
    00798       ret->MarkSuccessful(); \
    00799     } \
    00800     ret->MarkFinished(); \
    00801     return ret; \
    00802   } \
    00803   bool sync = Wait || wait; \
    00804   void const** argsTC = new void const*[9]; \
    00805   TEventMemPool *mempool = new TEventMemPool; \
    00806   argsTC[0] = mempool; \
    00807   argsTC[1] = mempool->Store<csRef<iThreadReturn> >(&ret); \
    00808   argsTC[2] = mempool->Store<bool>(&sync); \
    00809   argsTC[3] = mempool->Store<T1>(&A1); \
    00810   argsTC[4] = mempool->Store<T2>(&A2); \
    00811   argsTC[5] = mempool->Store<T3>(&A3); \
    00812   argsTC[6] = mempool->Store<T4>(&A4); \
    00813   argsTC[7] = mempool->Store<T5>(&A5); \
    00814   argsTC[8] = mempool->Store<T6>(&A6); \
    00815   csRef<iJob> job = QueueEvent<type, csRef<iThreadReturn>, bool, T1, T2, T3, T4, T5, T6>(tm, (ThreadedCallable<type>*)this, &type::function##TC, argsTC, queueType); \
    00816   ret->SetJob(job); \
    00817   if(Wait || wait) \
    00818   { \
    00819     ret->Wait(); \
    00820   } \
    00821   return ret; \
    00822 }
    00823
    00824 #define THREADED_CALLABLE_DECL7(type, function, returnClass, T1, A1, T2, A2, T3, A3, T4, A4, T5, A5, T6, A6, T7, A7, queueType, wait, forceQueue) \
    00825   bool function##TC(csRef<iThreadReturn> ret, bool sync, T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7); \
    00826   inline csRef<iThreadReturn> function##Wait(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7) \
    00827 { \
    00828   const type* objTC = const_cast<const type*>(this); \
    00829   return objTC->function##Wait(A1, A2, A3, A4, A5, A6, A7); \
    00830 } \
    00831   inline csRef<iThreadReturn> function##Wait(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7) const \
    00832 { \
    00833   return function##T(true, A1, A2, A3, A4, A5, A6, A7); \
    00834 } \
    00835   inline csRef<iThreadReturn> function(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7) \
    00836 { \
    00837   const type* objTC = const_cast<const type*>(this); \
    00838   return objTC->function(A1, A2, A3, A4, A5, A6, A7); \
    00839 } \
    00840   inline csRef<iThreadReturn> function(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7) const \
    00841 { \
    00842   return function##T(false, A1, A2, A3, A4, A5, A6, A7); \
    00843 } \
    00844   inline csRef<iThreadReturn> function##T(bool Wait, T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7) const \
    00845 { \
    00846   csRef<iThreadManager> tm = csQueryRegistry<iThreadManager>(GetObjectRegistry()); \
    00847   csRef<iThreadReturn> ret; \
    00848   ret.AttachNew(new returnClass(tm)); \
    00849   if(!tm.IsValid() || tm->Exiting()) \
    00850   { \
    00851     ret->MarkFinished(); \
    00852     return ret; \
    00853   } \
    00854   if(tm->RunNow(queueType, Wait || wait, forceQueue)) \
    00855   { \
    00856     type* objTC = const_cast<type*>(this); \
    00857     if(objTC->function##TC(ret, Wait || wait, A1, A2, A3, A4, A5, A6, A7)) \
    00858     { \
    00859       ret->MarkSuccessful(); \
    00860     } \
    00861     ret->MarkFinished(); \
    00862     return ret; \
    00863   } \
    00864   bool sync = Wait || wait; \
    00865   void const** argsTC = new void const*[10]; \
    00866   TEventMemPool *mempool = new TEventMemPool; \
    00867   argsTC[0] = mempool; \
    00868   argsTC[1] = mempool->Store<csRef<iThreadReturn> >(&ret); \
    00869   argsTC[2] = mempool->Store<bool>(&sync); \
    00870   argsTC[3] = mempool->Store<T1>(&A1); \
    00871   argsTC[4] = mempool->Store<T2>(&A2); \
    00872   argsTC[5] = mempool->Store<T3>(&A3); \
    00873   argsTC[6] = mempool->Store<T4>(&A4); \
    00874   argsTC[7] = mempool->Store<T5>(&A5); \
    00875   argsTC[8] = mempool->Store<T6>(&A6); \
    00876   argsTC[9] = mempool->Store<T7>(&A7); \
    00877   csRef<iJob> job = QueueEvent<type, csRef<iThreadReturn>, bool, T1, T2, T3, T4, T5, T6, T7>(tm, (ThreadedCallable<type>*)this, &type::function##TC, argsTC, queueType); \
    00878   ret->SetJob(job); \
    00879   if(Wait || wait) \
    00880   { \
    00881     ret->Wait(); \
    00882   } \
    00883   return ret; \
    00884 }
    00885
    00886 #define THREADED_CALLABLE_DECL8(type, function, returnClass, T1, A1, T2, A2, T3, A3, T4, A4, T5, A5, T6, A6, T7, A7, T8, A8, queueType, wait, forceQueue) \
    00887   bool function##TC(csRef<iThreadReturn> ret, bool sync, T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8); \
    00888   inline csRef<iThreadReturn> function##Wait(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8) \
    00889 { \
    00890   const type* objTC = const_cast<const type*>(this); \
    00891   return objTC->function##Wait(A1, A2, A3, A4, A5, A6, A7, A8); \
    00892 } \
    00893   inline csRef<iThreadReturn> function##Wait(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8) const \
    00894 { \
    00895   return function##T(true, A1, A2, A3, A4, A5, A6, A7, A8); \
    00896 } \
    00897   inline csRef<iThreadReturn> function(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8) \
    00898 { \
    00899   const type* objTC = const_cast<const type*>(this); \
    00900   return objTC->function(A1, A2, A3, A4, A5, A6, A7, A8); \
    00901 } \
    00902   inline csRef<iThreadReturn> function(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8) const \
    00903 { \
    00904   return function##T(false, A1, A2, A3, A4, A5, A6, A7, A8); \
    00905 } \
    00906   inline csRef<iThreadReturn> function##T(bool Wait, T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8) const \
    00907 { \
    00908   csRef<iThreadManager> tm = csQueryRegistry<iThreadManager>(GetObjectRegistry()); \
    00909   csRef<iThreadReturn> ret; \
    00910   ret.AttachNew(new returnClass(tm)); \
    00911   if(!tm.IsValid() || tm->Exiting()) \
    00912   { \
    00913     ret->MarkFinished(); \
    00914     return ret; \
    00915   } \
    00916   if(tm->RunNow(queueType, Wait || wait, forceQueue)) \
    00917   { \
    00918     type* objTC = const_cast<type*>(this); \
    00919     if(objTC->function##TC(ret, Wait || wait, A1, A2, A3, A4, A5, A6, A7, A8)) \
    00920     { \
    00921       ret->MarkSuccessful(); \
    00922     } \
    00923     ret->MarkFinished(); \
    00924     return ret; \
    00925   } \
    00926   bool sync = Wait || wait; \
    00927   void const** argsTC = new void const*[11]; \
    00928   TEventMemPool *mempool = new TEventMemPool; \
    00929   argsTC[0] = mempool; \
    00930   argsTC[1] = mempool->Store<csRef<iThreadReturn> >(&ret); \
    00931   argsTC[2] = mempool->Store<bool>(&sync); \
    00932   argsTC[3] = mempool->Store<T1>(&A1); \
    00933   argsTC[4] = mempool->Store<T2>(&A2); \
    00934   argsTC[5] = mempool->Store<T3>(&A3); \
    00935   argsTC[6] = mempool->Store<T4>(&A4); \
    00936   argsTC[7] = mempool->Store<T5>(&A5); \
    00937   argsTC[8] = mempool->Store<T6>(&A6); \
    00938   argsTC[9] = mempool->Store<T7>(&A7); \
    00939   argsTC[10] = mempool->Store<T8>(&A8); \
    00940   csRef<iJob> job = QueueEvent<type, csRef<iThreadReturn>, bool, T1, T2, T3, T4, T5, T6, T7, T8>(tm, (ThreadedCallable<type>*)this, &type::function##TC, argsTC, queueType); \
    00941   ret->SetJob(job); \
    00942   if(Wait || wait) \
    00943   { \
    00944     ret->Wait(); \
    00945   } \
    00946   return ret; \
    00947 }
    00948
    00949 #define THREADED_CALLABLE_DECL9(type, function, returnClass, T1, A1, T2, A2, T3, A3, T4, A4, T5, A5, T6, A6, T7, A7, T8, A8, T9, A9, queueType, wait, forceQueue) \
    00950   bool function##TC(csRef<iThreadReturn> ret, bool sync, T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9); \
    00951   inline csRef<iThreadReturn> function##Wait(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9) \
    00952 { \
    00953   const type* objTC = const_cast<const type*>(this); \
    00954   return objTC->function##Wait(A1, A2, A3, A4, A5, A6, A7, A8, A9); \
    00955 } \
    00956   inline csRef<iThreadReturn> function##Wait(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9) const \
    00957 { \
    00958   return function##T(true, A1, A2, A3, A4, A5, A6, A7, A8, A9); \
    00959 } \
    00960   inline csRef<iThreadReturn> function(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9) \
    00961 { \
    00962   const type* objTC = const_cast<const type*>(this); \
    00963   return objTC->function(A1, A2, A3, A4, A5, A6, A7, A8, A9); \
    00964 } \
    00965   inline csRef<iThreadReturn> function(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9) const \
    00966 { \
    00967   return function##T(false, A1, A2, A3, A4, A5, A6, A7, A8, A9); \
    00968 } \
    00969   inline csRef<iThreadReturn> function##T(bool Wait, T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9) const \
    00970 { \
    00971   csRef<iThreadManager> tm = csQueryRegistry<iThreadManager>(GetObjectRegistry()); \
    00972   csRef<iThreadReturn> ret; \
    00973   ret.AttachNew(new returnClass(tm)); \
    00974   if(!tm.IsValid() || tm->Exiting()) \
    00975   { \
    00976     ret->MarkFinished(); \
    00977     return ret; \
    00978   } \
    00979   if(tm->RunNow(queueType, Wait || wait, forceQueue)) \
    00980   { \
    00981     type* objTC = const_cast<type*>(this); \
    00982     if(objTC->function##TC(ret, Wait || wait, A1, A2, A3, A4, A5, A6, A7, A8, A9)) \
    00983     { \
    00984       ret->MarkSuccessful(); \
    00985     } \
    00986     ret->MarkFinished(); \
    00987     return ret; \
    00988   } \
    00989   bool sync = Wait || wait; \
    00990   void const** argsTC = new void const*[12]; \
    00991   TEventMemPool *mempool = new TEventMemPool; \
    00992   argsTC[0] = mempool; \
    00993   argsTC[1] = mempool->Store<csRef<iThreadReturn> >(&ret); \
    00994   argsTC[2] = mempool->Store<bool>(&sync); \
    00995   argsTC[3] = mempool->Store<T1>(&A1); \
    00996   argsTC[4] = mempool->Store<T2>(&A2); \
    00997   argsTC[5] = mempool->Store<T3>(&A3); \
    00998   argsTC[6] = mempool->Store<T4>(&A4); \
    00999   argsTC[7] = mempool->Store<T5>(&A5); \
    01000   argsTC[8] = mempool->Store<T6>(&A6); \
    01001   argsTC[9] = mempool->Store<T7>(&A7); \
    01002   argsTC[10] = mempool->Store<T8>(&A8); \
    01003   argsTC[11] = mempool->Store<T9>(&A9); \
    01004   csRef<iJob> job = QueueEvent<type, csRef<iThreadReturn>, bool, T1, T2, T3, T4, T5, T6, T7, T8, T9>(tm, (ThreadedCallable<type>*)this, &type::function##TC, argsTC, queueType); \
    01005   ret->SetJob(job); \
    01006   if(Wait || wait) \
    01007   { \
    01008     ret->Wait(); \
    01009   } \
    01010   return ret; \
    01011 }
    01012
    01013 #define THREADED_CALLABLE_DECL10(type, function, returnClass, T1, A1, T2, A2, T3, A3, T4, A4, T5, A5, T6, A6, T7, A7, T8, A8, T9, A9, T10, A10, queueType, wait, forceQueue) \
    01014   bool function##TC(csRef<iThreadReturn> ret, bool sync, T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10); \
    01015   inline csRef<iThreadReturn> function##Wait(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10) \
    01016 { \
    01017   const type* objTC = const_cast<const type*>(this); \
    01018   return objTC->function##Wait(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10); \
    01019 } \
    01020   inline csRef<iThreadReturn> function##Wait(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10) const \
    01021 { \
    01022   return function##T(true, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10); \
    01023 } \
    01024   inline csRef<iThreadReturn> function(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10) \
    01025 { \
    01026   const type* objTC = const_cast<const type*>(this); \
    01027   return objTC->function(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10); \
    01028 } \
    01029   inline csRef<iThreadReturn> function(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10) const \
    01030 { \
    01031   return function##T(false, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10); \
    01032 } \
    01033   inline csRef<iThreadReturn> function##T(bool Wait, T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10) const \
    01034 { \
    01035   csRef<iThreadManager> tm = csQueryRegistry<iThreadManager>(GetObjectRegistry()); \
    01036   csRef<iThreadReturn> ret; \
    01037   ret.AttachNew(new returnClass(tm)); \
    01038   if(!tm.IsValid() || tm->Exiting()) \
    01039   { \
    01040     ret->MarkFinished(); \
    01041     return ret; \
    01042   } \
    01043   if(tm->RunNow(queueType, Wait || wait, forceQueue)) \
    01044   { \
    01045     type* objTC = const_cast<type*>(this); \
    01046     if(objTC->function##TC(ret, Wait || wait, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)) \
    01047     { \
    01048       ret->MarkSuccessful(); \
    01049     } \
    01050     ret->MarkFinished(); \
    01051     return ret; \
    01052   } \
    01053   bool sync = Wait || wait; \
    01054   void const** argsTC = new void const*[13]; \
    01055   TEventMemPool *mempool = new TEventMemPool; \
    01056   argsTC[0] = mempool; \
    01057   argsTC[1] = mempool->Store<csRef<iThreadReturn> >(&ret); \
    01058   argsTC[2] = mempool->Store<bool>(&sync); \
    01059   argsTC[3] = mempool->Store<T1>(&A1); \
    01060   argsTC[4] = mempool->Store<T2>(&A2); \
    01061   argsTC[5] = mempool->Store<T3>(&A3); \
    01062   argsTC[6] = mempool->Store<T4>(&A4); \
    01063   argsTC[7] = mempool->Store<T5>(&A5); \
    01064   argsTC[8] = mempool->Store<T6>(&A6); \
    01065   argsTC[9] = mempool->Store<T7>(&A7); \
    01066   argsTC[10] = mempool->Store<T8>(&A8); \
    01067   argsTC[11] = mempool->Store<T9>(&A9); \
    01068   argsTC[12] = mempool->Store<T10>(&A10); \
    01069   csRef<iJob> job = QueueEvent<type, csRef<iThreadReturn>, bool, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(tm, (ThreadedCallable<type>*)this, &type::function##TC, argsTC, queueType); \
    01070   ret->SetJob(job); \
    01071   if(Wait || wait) \
    01072   { \
    01073     ret->Wait(); \
    01074   } \
    01075   return ret; \
    01076 }
    01077
    01078 #define THREADED_CALLABLE_DECL11(type, function, returnClass, T1, A1, T2, A2, T3, A3, T4, A4, T5, A5, T6, A6, T7, A7, T8, A8, T9, A9, T10, A10, T11, A11, queueType, wait, forceQueue) \
    01079   bool function##TC(csRef<iThreadReturn> ret, bool sync, T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10, T11 A11); \
    01080   inline csRef<iThreadReturn> function##Wait(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10, T11 A11) \
    01081 { \
    01082   const type* objTC = const_cast<const type*>(this); \
    01083   return objTC->function##Wait(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11); \
    01084 } \
    01085   inline csRef<iThreadReturn> function##Wait(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10, T11 A11) const \
    01086 { \
    01087   return function##T(true, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11); \
    01088 } \
    01089   inline csRef<iThreadReturn> function(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10, T11 A11) \
    01090 { \
    01091   const type* objTC = const_cast<const type*>(this); \
    01092   return objTC->function(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11); \
    01093 } \
    01094   inline csRef<iThreadReturn> function(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10, T11 A11) const \
    01095 { \
    01096   return function##T(false, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11); \
    01097 } \
    01098   inline csRef<iThreadReturn> function##T(bool Wait, T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10, T11 A11) const \
    01099 { \
    01100   csRef<iThreadManager> tm = csQueryRegistry<iThreadManager>(GetObjectRegistry()); \
    01101   csRef<iThreadReturn> ret; \
    01102   ret.AttachNew(new returnClass(tm)); \
    01103   if(!tm.IsValid() || tm->Exiting()) \
    01104   { \
    01105     ret->MarkFinished(); \
    01106     return ret; \
    01107   } \
    01108   if(tm->RunNow(queueType, Wait || wait, forceQueue)) \
    01109   { \
    01110     type* objTC = const_cast<type*>(this); \
    01111     if(objTC->function##TC(ret, Wait || wait, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11)) \
    01112     { \
    01113       ret->MarkSuccessful(); \
    01114     } \
    01115     ret->MarkFinished(); \
    01116     return ret; \
    01117   } \
    01118   bool sync = Wait || wait; \
    01119   void const** argsTC = new void const*[14]; \
    01120   TEventMemPool *mempool = new TEventMemPool; \
    01121   argsTC[0] = mempool; \
    01122   argsTC[1] = mempool->Store<csRef<iThreadReturn> >(&ret); \
    01123   argsTC[2] = mempool->Store<bool>(&sync); \
    01124   argsTC[3] = mempool->Store<T1>(&A1); \
    01125   argsTC[4] = mempool->Store<T2>(&A2); \
    01126   argsTC[5] = mempool->Store<T3>(&A3); \
    01127   argsTC[6] = mempool->Store<T4>(&A4); \
    01128   argsTC[7] = mempool->Store<T5>(&A5); \
    01129   argsTC[8] = mempool->Store<T6>(&A6); \
    01130   argsTC[9] = mempool->Store<T7>(&A7); \
    01131   argsTC[10] = mempool->Store<T8>(&A8); \
    01132   argsTC[11] = mempool->Store<T9>(&A9); \
    01133   argsTC[12] = mempool->Store<T10>(&A10); \
    01134   argsTC[13] = mempool->Store<T11>(&A11); \
    01135   csRef<iJob> job = QueueEvent<type, csRef<iThreadReturn>, bool, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(tm, (ThreadedCallable<type>*)this, &type::function##TC, argsTC, queueType); \
    01136   ret->SetJob(job); \
    01137   if(Wait || wait) \
    01138   { \
    01139     ret->Wait(); \
    01140   } \
    01141   return ret; \
    01142 }
    01143
    01144 #define THREADED_CALLABLE_DECL12(type, function, returnClass, T1, A1, T2, A2, T3, A3, T4, A4, T5, A5, T6, A6, T7, A7, T8, A8, T9, A9, T10, A10, T11, A11, T12, A12, queueType, wait, forceQueue) \
    01145   bool function##TC(csRef<iThreadReturn> ret, bool sync, T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10, T11 A11, T12 A12); \
    01146   inline csRef<iThreadReturn> function##Wait(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10, T11 A11, T12 A12) \
    01147 { \
    01148   const type* objTC = const_cast<const type*>(this); \
    01149   return objTC->function##Wait(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12); \
    01150 } \
    01151   inline csRef<iThreadReturn> function##Wait(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10, T11 A11, T12 A12) const \
    01152 { \
    01153   return function##T(true, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12); \
    01154 } \
    01155   inline csRef<iThreadReturn> function(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10, T11 A11, T12 A12) \
    01156 { \
    01157   const type* objTC = const_cast<const type*>(this); \
    01158   return objTC->function(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12); \
    01159 } \
    01160   inline csRef<iThreadReturn> function(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10, T11 A11, T12 A12) const \
    01161 { \
    01162   return function##T(false, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12); \
    01163 } \
    01164   inline csRef<iThreadReturn> function##T(bool Wait, T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10, T11 A11, T12 A12) const \
    01165 { \
    01166   csRef<iThreadManager> tm = csQueryRegistry<iThreadManager>(GetObjectRegistry()); \
    01167   csRef<iThreadReturn> ret; \
    01168   ret.AttachNew(new returnClass(tm)); \
    01169   if(!tm.IsValid() || tm->Exiting()) \
    01170   { \
    01171     ret->MarkFinished(); \
    01172     return ret; \
    01173   } \
    01174   if(tm->RunNow(queueType, Wait || wait, forceQueue)) \
    01175   { \
    01176     type* objTC = const_cast<type*>(this); \
    01177     if(objTC->function##TC(ret, Wait || wait, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12)) \
    01178     { \
    01179       ret->MarkSuccessful(); \
    01180     } \
    01181     ret->MarkFinished(); \
    01182     return ret; \
    01183   } \
    01184   bool sync = Wait || wait; \
    01185   void const** argsTC = new void const*[15]; \
    01186   TEventMemPool *mempool = new TEventMemPool; \
    01187   argsTC[0] = mempool; \
    01188   argsTC[1] = mempool->Store<csRef<iThreadReturn> >(&ret); \
    01189   argsTC[2] = mempool->Store<bool>(&sync); \
    01190   argsTC[3] = mempool->Store<T1>(&A1); \
    01191   argsTC[4] = mempool->Store<T2>(&A2); \
    01192   argsTC[5] = mempool->Store<T3>(&A3); \
    01193   argsTC[6] = mempool->Store<T4>(&A4); \
    01194   argsTC[7] = mempool->Store<T5>(&A5); \
    01195   argsTC[8] = mempool->Store<T6>(&A6); \
    01196   argsTC[9] = mempool->Store<T7>(&A7); \
    01197   argsTC[10] = mempool->Store<T8>(&A8); \
    01198   argsTC[11] = mempool->Store<T9>(&A9); \
    01199   argsTC[12] = mempool->Store<T10>(&A10); \
    01200   argsTC[13] = mempool->Store<T11>(&A11); \
    01201   argsTC[14] = mempool->Store<T12>(&A12); \
    01202   csRef<iJob> job = QueueEvent<type, csRef<iThreadReturn>, bool, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(tm, (ThreadedCallable<type>*)this, &type::function##TC, argsTC, queueType); \
    01203   ret->SetJob(job); \
    01204   if(Wait || wait) \
    01205   { \
    01206     ret->Wait(); \
    01207   } \
    01208   return ret; \
    01209 }
    01210
    01211 #define THREADED_CALLABLE_DECL13(type, function, returnClass, T1, A1, T2, A2, T3, A3, T4, A4, T5, A5, T6, A6, T7, A7, T8, A8, T9, A9, T10, A10, T11, A11, T12, A12, T13, A13, queueType, wait, forceQueue) \
    01212   bool function##TC(csRef<iThreadReturn> ret, bool sync, T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10, T11 A11, T12 A12, T13 A13); \
    01213   inline csRef<iThreadReturn> function##Wait(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10, T11 A11, T12 A12, T13 A13) \
    01214 { \
    01215   const type* objTC = const_cast<const type*>(this); \
    01216   return objTC->function##Wait(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13); \
    01217 } \
    01218   inline csRef<iThreadReturn> function##Wait(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10, T11 A11, T12 A12, T13 A13) const \
    01219 { \
    01220   return function##T(true, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13); \
    01221 } \
    01222   inline csRef<iThreadReturn> function(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10, T11 A11, T12 A12, T13 A13) \
    01223 { \
    01224   const type* objTC = const_cast<const type*>(this); \
    01225   return objTC->function(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13); \
    01226 } \
    01227   inline csRef<iThreadReturn> function(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10, T11 A11, T12 A12, T13 A13) const \
    01228 { \
    01229   return function##T(false, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13); \
    01230 } \
    01231   inline csRef<iThreadReturn> function##T(bool Wait, T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10, T11 A11, T12 A12, T13 A13) const \
    01232 { \
    01233   csRef<iThreadManager> tm = csQueryRegistry<iThreadManager>(GetObjectRegistry()); \
    01234   csRef<iThreadReturn> ret; \
    01235   ret.AttachNew(new returnClass(tm)); \
    01236   if(!tm.IsValid() || tm->Exiting()) \
    01237   { \
    01238     ret->MarkFinished(); \
    01239     return ret; \
    01240   } \
    01241   if(tm->RunNow(queueType, Wait || wait, forceQueue)) \
    01242   { \
    01243     type* objTC = const_cast<type*>(this); \
    01244     if(objTC->function##TC(ret, Wait || wait, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13)) \
    01245     { \
    01246       ret->MarkSuccessful(); \
    01247     } \
    01248     ret->MarkFinished(); \
    01249     return ret; \
    01250   } \
    01251   bool sync = Wait || wait; \
    01252   void const** argsTC = new void const*[16]; \
    01253   TEventMemPool *mempool = new TEventMemPool; \
    01254   argsTC[0] = mempool; \
    01255   argsTC[1] = mempool->Store<csRef<iThreadReturn> >(&ret); \
    01256   argsTC[2] = mempool->Store<bool>(&sync); \
    01257   argsTC[3] = mempool->Store<T1>(&A1); \
    01258   argsTC[4] = mempool->Store<T2>(&A2); \
    01259   argsTC[5] = mempool->Store<T3>(&A3); \
    01260   argsTC[6] = mempool->Store<T4>(&A4); \
    01261   argsTC[7] = mempool->Store<T5>(&A5); \
    01262   argsTC[8] = mempool->Store<T6>(&A6); \
    01263   argsTC[9] = mempool->Store<T7>(&A7); \
    01264   argsTC[10] = mempool->Store<T8>(&A8); \
    01265   argsTC[11] = mempool->Store<T9>(&A9); \
    01266   argsTC[12] = mempool->Store<T10>(&A10); \
    01267   argsTC[13] = mempool->Store<T11>(&A11); \
    01268   argsTC[14] = mempool->Store<T12>(&A12); \
    01269   argsTC[15] = mempool->Store<T13>(&A13); \
    01270   csRef<iJob> job = QueueEvent<type, csRef<iThreadReturn>, bool, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(tm, (ThreadedCallable<type>*)this, &type::function##TC, argsTC, queueType); \
    01271   ret->SetJob(job); \
    01272   if(Wait || wait) \
    01273   { \
    01274     ret->Wait(); \
    01275   } \
    01276   return ret; \
    01277 }
    01278
    01279 #define THREADED_CALLABLE_DECL14(type, function, returnClass, T1, A1, T2, A2, T3, A3, T4, A4, T5, A5, T6, A6, T7, A7, T8, A8, T9, A9, T10, A10, T11, A11, T12, A12, T13, A13, T14, A14, queueType, wait, forceQueue) \
    01280   bool function##TC(csRef<iThreadReturn> ret, bool sync, T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10, T11 A11, T12 A12, T13 A13, T14 A14); \
    01281   inline csRef<iThreadReturn> function##Wait(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10, T11 A11, T12 A12, T13 A13, T14 A14) \
    01282 { \
    01283   const type* objTC = const_cast<const type*>(this); \
    01284   return objTC->function##Wait(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14); \
    01285 } \
    01286   inline csRef<iThreadReturn> function##Wait(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10, T11 A11, T12 A12, T13 A13, T14 A14) const \
    01287 { \
    01288   return function##T(true, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14); \
    01289 } \
    01290   inline csRef<iThreadReturn> function(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10, T11 A11, T12 A12, T13 A13, T14 A14) \
    01291 { \
    01292   const type* objTC = const_cast<const type*>(this); \
    01293   return objTC->function(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14); \
    01294 } \
    01295   inline csRef<iThreadReturn> function(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10, T11 A11, T12 A12, T13 A13, T14 A14) const \
    01296 { \
    01297   return function##T(false, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14); \
    01298 } \
    01299   inline csRef<iThreadReturn> function##T(bool Wait, T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10, T11 A11, T12 A12, T13 A13, T14 A14) const \
    01300 { \
    01301   csRef<iThreadManager> tm = csQueryRegistry<iThreadManager>(GetObjectRegistry()); \
    01302   csRef<iThreadReturn> ret; \
    01303   ret.AttachNew(new returnClass(tm)); \
    01304   if(!tm.IsValid() || tm->Exiting()) \
    01305   { \
    01306     ret->MarkFinished(); \
    01307     return ret; \
    01308   } \
    01309   if(tm->RunNow(queueType, Wait || wait, forceQueue))) \
    01310   { \
    01311     type* objTC = const_cast<type*>(this); \
    01312     if(objTC->function##TC(ret, Wait || wait, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14)) \
    01313     { \
    01314       ret->MarkSuccessful(); \
    01315     } \
    01316     ret->MarkFinished(); \
    01317     return ret; \
    01318   } \
    01319   bool sync = Wait || wait; \
    01320   void const** argsTC = new void const*[17]; \
    01321   TEventMemPool *mempool = new TEventMemPool; \
    01322   argsTC[0] = mempool; \
    01323   argsTC[1] = mempool->Store<csRef<iThreadReturn> >(ret); \
    01324   argsTC[2] = mempool->Store<bool>(&sync); \
    01325   argsTC[3] = mempool->Store<T1>(&A1); \
    01326   argsTC[4] = mempool->Store<T2>(&A2); \
    01327   argsTC[5] = mempool->Store<T3>(&A3); \
    01328   argsTC[6] = mempool->Store<T4>(&A4); \
    01329   argsTC[7] = mempool->Store<T5>(&A5); \
    01330   argsTC[8] = mempool->Store<T6>(&A6); \
    01331   argsTC[9] = mempool->Store<T7>(&A7); \
    01332   argsTC[10] = mempool->Store<T8>(&A8); \
    01333   argsTC[11] = mempool->Store<T9>(&A9); \
    01334   argsTC[12] = mempool->Store<T10>(&A10); \
    01335   argsTC[13] = mempool->Store<T11>(&A11); \
    01336   argsTC[14] = mempool->Store<T12>(&A12); \
    01337   argsTC[15] = mempool->Store<T13>(&A13); \
    01338   argsTC[16] = mempool->Store<T14>(&A14); \
    01339   csRef<iJob> job = QueueEvent<type, csRef<iThreadReturn>, bool, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(tm, (ThreadedCallable<type>*)this, &type::function##TC, argsTC, queueType); \
    01340   ret->SetJob(job); \
    01341   if(Wait || wait) \
    01342   { \
    01343     ret->Wait(); \
    01344   } \
    01345   return ret; \
    01346 }
    01347
    01348 #define THREADED_CALLABLE_DECL15(type, function, returnClass, T1, A1, T2, A2, T3, A3, T4, A4, T5, A5, T6, A6, T7, A7, T8, A8, T9, A9, T10, A10, T11, A11, T12, A12, T13, A13, T14, A14, T15, A15, queueType, wait, forceQueue) \
    01349   bool function##TC(csRef<iThreadReturn> ret, bool sync, T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10, T11 A11, T12 A12, T13 A13, T14 A14, T15 A15); \
    01350   inline csRef<iThreadReturn> function##Wait(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10, T11 A11, T12 A12, T13 A13, T14 A14, T15 A15) \
    01351 { \
    01352   const type* objTC = const_cast<const type*>(this); \
    01353   return objTC->function##Wait(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15); \
    01354 } \
    01355   inline csRef<iThreadReturn> function##Wait(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10, T11 A11, T12 A12, T13 A13, T14 A14, T15 A15) const \
    01356 { \
    01357   return function##T(true, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15); \
    01358 } \
    01359   inline csRef<iThreadReturn> function(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10, T11 A11, T12 A12, T13 A13, T14 A14, T15 A15) \
    01360 { \
    01361   const type* objTC = const_cast<const type*>(this); \
    01362   return objTC->function(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15); \
    01363 } \
    01364   inline csRef<iThreadReturn> function(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10, T11 A11, T12 A12, T13 A13, T14 A14, T15 A15) const \
    01365 { \
    01366   return function##T(false, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15); \
    01367 } \
    01368   inline csRef<iThreadReturn> function##T(bool Wait, T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6, T7 A7, T8 A8, T9 A9, T10 A10, T11 A11, T12 A12, T13 A13, T14 A14, T15 A15) const \
    01369 { \
    01370   csRef<iThreadManager> tm = csQueryRegistry<iThreadManager>(GetObjectRegistry()); \
    01371   csRef<iThreadReturn> ret; \
    01372   ret.AttachNew(new returnClass(tm)); \
    01373   if(!tm.IsValid() || tm->Exiting()) \
    01374   { \
    01375     ret->MarkFinished(); \
    01376     return ret; \
    01377   } \
    01378   if(tm->RunNow(queueType, Wait || wait, forceQueue))) \
    01379   { \
    01380     type* objTC = const_cast<type*>(this); \
    01381     if(objTC->function##TC(ret, Wait || wait, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15)) \
    01382     { \
    01383       ret->MarkSuccessful(); \
    01384     } \
    01385     ret->MarkFinished(); \
    01386     return ret; \
    01387   } \
    01388   bool sync = Wait || wait; \
    01389   void const** argsTC = new void const*[18]; \
    01390   TEventMemPool *mempool = new TEventMemPool; \
    01391   argsTC[0] = mempool; \
    01392   argsTC[1] = mempool->Store<csRef<iThreadReturn> >(ret); \
    01393   argsTC[2] = mempool->Store<bool>(&sync); \
    01394   argsTC[3] = mempool->Store<T1>(&A1); \
    01395   argsTC[4] = mempool->Store<T2>(&A2); \
    01396   argsTC[5] = mempool->Store<T3>(&A3); \
    01397   argsTC[6] = mempool->Store<T4>(&A4); \
    01398   argsTC[7] = mempool->Store<T5>(&A5); \
    01399   argsTC[8] = mempool->Store<T6>(&A6); \
    01400   argsTC[9] = mempool->Store<T7>(&A7); \
    01401   argsTC[10] = mempool->Store<T8>(&A8); \
    01402   argsTC[11] = mempool->Store<T9>(&A9); \
    01403   argsTC[12] = mempool->Store<T10>(&A10); \
    01404   argsTC[13] = mempool->Store<T11>(&A11); \
    01405   argsTC[14] = mempool->Store<T12>(&A12); \
    01406   argsTC[15] = mempool->Store<T13>(&A13); \
    01407   argsTC[16] = mempool->Store<T14>(&A14); \
    01408   argsTC[17] = mempool->Store<T15>(&A15); \
    01409   csRef<iJob> job = QueueEvent<type, csRef<iThreadReturn>, bool, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(tm, (ThreadedCallable<type>*)this, &type::function##TC, argsTC, queueType); \
    01410   ret->SetJob(job); \
    01411   if(Wait || wait) \
    01412   { \
    01413     ret->Wait(); \
    01414   } \
    01415   return ret; \
    01416 }
    01417
    01418 #define THREADED_CALLABLE_IMPL(type, function) \
    01419   bool type::function##TC(csRef<iThreadReturn> ret, bool sync)
    01420
    01421 #define THREADED_CALLABLE_IMPL1(type, function, A1) \
    01422   bool type::function##TC(csRef<iThreadReturn> ret, bool sync, A1)
    01423
    01424 #define THREADED_CALLABLE_IMPL2(type, function, A1, A2) \
    01425   bool type::function##TC(csRef<iThreadReturn> ret, bool sync, A1, A2)
    01426
    01427 #define THREADED_CALLABLE_IMPL3(type, function, A1, A2, A3) \
    01428   bool type::function##TC(csRef<iThreadReturn> ret, bool sync, A1, A2, A3)
    01429
    01430 #define THREADED_CALLABLE_IMPL4(type, function, A1, A2, A3, A4) \
    01431   bool type::function##TC(csRef<iThreadReturn> ret, bool sync, A1, A2, A3, A4)
    01432
    01433 #define THREADED_CALLABLE_IMPL5(type, function, A1, A2, A3, A4, A5) \
    01434   bool type::function##TC(csRef<iThreadReturn> ret, bool sync, A1, A2, A3, A4, A5)
    01435
    01436 #define THREADED_CALLABLE_IMPL6(type, function, A1, A2, A3, A4, A5, A6) \
    01437   bool type::function##TC(csRef<iThreadReturn> ret, bool sync, A1, A2, A3, A4, A5, A6)
    01438
    01439 #define THREADED_CALLABLE_IMPL7(type, function, A1, A2, A3, A4, A5, A6, A7) \
    01440   bool type::function##TC(csRef<iThreadReturn> ret, bool sync, A1, A2, A3, A4, A5, A6, A7)
    01441
    01442 #define THREADED_CALLABLE_IMPL8(type, function, A1, A2, A3, A4, A5, A6, A7, A8) \
    01443   bool type::function##TC(csRef<iThreadReturn> ret, bool sync, A1, A2, A3, A4, A5, A6, A7, A8)
    01444
    01445 #define THREADED_CALLABLE_IMPL9(type, function, A1, A2, A3, A4, A5, A6, A7, A8, A9) \
    01446   bool type::function##TC(csRef<iThreadReturn> ret, bool sync, A1, A2, A3, A4, A5, A6, A7, A8, A9)
    01447
    01448 #define THREADED_CALLABLE_IMPL10(type, function, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) \
    01449   bool type::function##TC(csRef<iThreadReturn> ret, bool sync, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)
    01450
    01451 #define THREADED_CALLABLE_IMPL11(type, function, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11) \
    01452   bool type::function##TC(csRef<iThreadReturn> ret, bool sync, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11)
    01453
    01454 #define THREADED_CALLABLE_IMPL12(type, function, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12) \
    01455   bool type::function##TC(csRef<iThreadReturn> ret, bool sync, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12)
    01456
    01457 #define THREADED_CALLABLE_IMPL13(type, function, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13) \
    01458   bool type::function##TC(csRef<iThreadReturn> ret, bool sync, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13)
    01459
    01460 #define THREADED_CALLABLE_IMPL14(type, function, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14) \
    01461   bool type::function##TC(csRef<iThreadReturn> ret, bool sync, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14)
    01462
    01463 #define THREADED_CALLABLE_IMPL15(type, function, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15) \
    01464   bool type::function##TC(csRef<iThreadReturn> ret, bool sync, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15)
    01465
    01466 #endif // __CS_IUTIL_THREADMANAGER_H__