Panda3D
|
00001 // Filename: asyncTaskManager.h 00002 // Created by: drose (23Aug06) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #ifndef ASYNCTASKMANAGER_H 00016 #define ASYNCTASKMANAGER_H 00017 00018 #include "pandabase.h" 00019 00020 #include "asyncTask.h" 00021 #include "asyncTaskCollection.h" 00022 #include "asyncTaskChain.h" 00023 #include "typedReferenceCount.h" 00024 #include "thread.h" 00025 #include "pmutex.h" 00026 #include "mutexHolder.h" 00027 #include "conditionVarFull.h" 00028 #include "pvector.h" 00029 #include "pdeque.h" 00030 #include "pStatCollector.h" 00031 #include "clockObject.h" 00032 #include "ordered_vector.h" 00033 #include "indirectCompareNames.h" 00034 00035 //////////////////////////////////////////////////////////////////// 00036 // Class : AsyncTaskManager 00037 // Description : A class to manage a loose queue of isolated tasks, 00038 // which can be performed either synchronously (in the 00039 // foreground thread) or asynchronously (by a background 00040 // thread). 00041 // 00042 // The AsyncTaskManager is actually a collection of 00043 // AsyncTaskChains, each of which maintains a list of 00044 // tasks. Each chain can be either foreground or 00045 // background (it may run only in the main thread, or it 00046 // may be serviced by one or more background threads). 00047 // See AsyncTaskChain for more information. 00048 // 00049 // If you do not require background processing, it is 00050 // perfectly acceptable to create only one 00051 // AsyncTaskChain, which runs in the main thread. This 00052 // is a common configuration. 00053 //////////////////////////////////////////////////////////////////// 00054 class EXPCL_PANDA_EVENT AsyncTaskManager : public TypedReferenceCount, public Namable { 00055 PUBLISHED: 00056 AsyncTaskManager(const string &name); 00057 BLOCKING virtual ~AsyncTaskManager(); 00058 00059 BLOCKING void cleanup(); 00060 00061 INLINE void set_clock(ClockObject *clock); 00062 INLINE ClockObject *get_clock(); 00063 00064 int get_num_task_chains() const; 00065 AsyncTaskChain *get_task_chain(int n) const; 00066 MAKE_SEQ(get_task_chains, get_num_task_chains, get_task_chain); 00067 AsyncTaskChain *make_task_chain(const string &name); 00068 AsyncTaskChain *find_task_chain(const string &name); 00069 BLOCKING bool remove_task_chain(const string &name); 00070 00071 void add(AsyncTask *task); 00072 bool has_task(AsyncTask *task) const; 00073 00074 AsyncTask *find_task(const string &name) const; 00075 AsyncTaskCollection find_tasks(const string &name) const; 00076 AsyncTaskCollection find_tasks_matching(const GlobPattern &pattern) const; 00077 00078 bool remove(AsyncTask *task); 00079 int remove(const AsyncTaskCollection &tasks); 00080 00081 BLOCKING void wait_for_tasks(); 00082 BLOCKING void stop_threads(); 00083 void start_threads(); 00084 00085 INLINE int get_num_tasks() const; 00086 00087 AsyncTaskCollection get_tasks() const; 00088 AsyncTaskCollection get_active_tasks() const; 00089 AsyncTaskCollection get_sleeping_tasks() const; 00090 00091 void poll(); 00092 double get_next_wake_time() const; 00093 00094 virtual void output(ostream &out) const; 00095 virtual void write(ostream &out, int indent_level = 0) const; 00096 00097 INLINE static AsyncTaskManager *get_global_ptr(); 00098 00099 protected: 00100 AsyncTaskChain *do_make_task_chain(const string &name); 00101 AsyncTaskChain *do_find_task_chain(const string &name); 00102 00103 INLINE void add_task_by_name(AsyncTask *task); 00104 void remove_task_by_name(AsyncTask *task); 00105 00106 bool do_has_task(AsyncTask *task) const; 00107 00108 virtual void do_output(ostream &out) const; 00109 00110 private: 00111 static void make_global_ptr(); 00112 00113 protected: 00114 class AsyncTaskSortName { 00115 public: 00116 bool operator () (AsyncTask *a, AsyncTask *b) const { 00117 return a->get_name() < b->get_name(); 00118 } 00119 }; 00120 00121 typedef pmultiset<AsyncTask *, AsyncTaskSortName> TasksByName; 00122 00123 // Protects all the following members. This same lock is also used 00124 // to protect all of our AsyncTaskChain members. 00125 Mutex _lock; 00126 00127 typedef ov_set<PT(AsyncTaskChain), IndirectCompareNames<AsyncTaskChain> > TaskChains; 00128 TaskChains _task_chains; 00129 00130 int _num_tasks; 00131 TasksByName _tasks_by_name; 00132 PT(ClockObject) _clock; 00133 00134 ConditionVarFull _frame_cvar; // Signalled when the clock ticks. 00135 00136 static PT(AsyncTaskManager) _global_ptr; 00137 00138 public: 00139 static TypeHandle get_class_type() { 00140 return _type_handle; 00141 } 00142 static void init_type() { 00143 TypedReferenceCount::init_type(); 00144 register_type(_type_handle, "AsyncTaskManager", 00145 TypedReferenceCount::get_class_type()); 00146 } 00147 virtual TypeHandle get_type() const { 00148 return get_class_type(); 00149 } 00150 virtual TypeHandle force_init_type() {init_type(); return get_class_type();} 00151 00152 private: 00153 static TypeHandle _type_handle; 00154 00155 friend class AsyncTaskChain; 00156 friend class AsyncTaskChain::AsyncTaskChainThread; 00157 friend class AsyncTask; 00158 friend class AsyncTaskSequence; 00159 }; 00160 00161 INLINE ostream &operator << (ostream &out, const AsyncTaskManager &manager) { 00162 manager.output(out); 00163 return out; 00164 }; 00165 00166 #include "asyncTaskManager.I" 00167 00168 #endif