Panda3D

asyncTaskManager.h

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
 All Classes Functions Variables Enumerations