Panda3D
|
00001 // Filename: asyncTask.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 ASYNCTASK_H 00016 #define ASYNCTASK_H 00017 00018 #include "pandabase.h" 00019 00020 #include "asyncTaskBase.h" 00021 #include "pmutex.h" 00022 #include "conditionVar.h" 00023 #include "pStatCollector.h" 00024 00025 #ifdef HAVE_PYTHON 00026 00027 #undef HAVE_LONG_LONG // NSPR and Python both define this. 00028 #undef _POSIX_C_SOURCE 00029 #include <Python.h> 00030 00031 #endif // HAVE_PYTHON 00032 00033 class AsyncTaskManager; 00034 class AsyncTaskChain; 00035 00036 //////////////////////////////////////////////////////////////////// 00037 // Class : AsyncTask 00038 // Description : This class represents a concrete task performed by an 00039 // AsyncManager. Normally, you would subclass from this 00040 // class, and override do_task(), to define the 00041 // functionality you wish to have the task perform. 00042 //////////////////////////////////////////////////////////////////// 00043 class EXPCL_PANDA_EVENT AsyncTask : public AsyncTaskBase { 00044 public: 00045 AsyncTask(const string &name = string()); 00046 ALLOC_DELETED_CHAIN(AsyncTask); 00047 00048 PUBLISHED: 00049 virtual ~AsyncTask(); 00050 00051 enum DoneStatus { 00052 DS_done, // normal task completion 00053 DS_cont, // run task again next epoch 00054 DS_again, // start the task over from the beginning 00055 DS_pickup, // run task again this frame, if frame budget allows 00056 DS_exit, // stop the enclosing sequence 00057 DS_pause, // pause, then exit (useful within a sequence) 00058 DS_interrupt, // interrupt the task manager, but run task again 00059 }; 00060 00061 enum State { 00062 S_inactive, 00063 S_active, 00064 S_servicing, 00065 S_servicing_removed, // Still servicing, but wants removal from manager. 00066 S_sleeping, 00067 S_active_nested, // active within a sequence. 00068 }; 00069 00070 INLINE State get_state() const; 00071 INLINE bool is_alive() const; 00072 INLINE AsyncTaskManager *get_manager() const; 00073 00074 void remove(); 00075 00076 INLINE void set_delay(double delay); 00077 INLINE void clear_delay(); 00078 INLINE bool has_delay() const; 00079 INLINE double get_delay() const; 00080 double get_wake_time() const; 00081 void recalc_wake_time(); 00082 00083 INLINE double get_start_time() const; 00084 double get_elapsed_time() const; 00085 INLINE int get_start_frame() const; 00086 int get_elapsed_frames() const; 00087 00088 void set_name(const string &name); 00089 INLINE void clear_name(); 00090 string get_name_prefix() const; 00091 00092 INLINE AtomicAdjust::Integer get_task_id() const; 00093 00094 void set_task_chain(const string &chain_name); 00095 INLINE const string &get_task_chain() const; 00096 00097 void set_sort(int sort); 00098 INLINE int get_sort() const; 00099 00100 void set_priority(int priority); 00101 INLINE int get_priority() const; 00102 00103 INLINE void set_done_event(const string &done_event); 00104 INLINE const string &get_done_event() const; 00105 00106 #ifdef HAVE_PYTHON 00107 INLINE void set_python_object(PyObject *python_object); 00108 INLINE PyObject *get_python_object() const; 00109 #endif // HAVE_PYTHON 00110 00111 INLINE double get_dt() const; 00112 INLINE double get_max_dt() const; 00113 INLINE double get_average_dt() const; 00114 00115 virtual void output(ostream &out) const; 00116 00117 protected: 00118 void jump_to_task_chain(AsyncTaskManager *manager); 00119 DoneStatus unlock_and_do_task(); 00120 00121 virtual bool is_runnable(); 00122 virtual DoneStatus do_task(); 00123 virtual void upon_birth(AsyncTaskManager *manager); 00124 virtual void upon_death(AsyncTaskManager *manager, bool clean_exit); 00125 00126 protected: 00127 AtomicAdjust::Integer _task_id; 00128 string _chain_name; 00129 double _delay; 00130 bool _has_delay; 00131 double _wake_time; 00132 int _sort; 00133 int _priority; 00134 string _done_event; 00135 00136 State _state; 00137 Thread *_servicing_thread; 00138 AsyncTaskManager *_manager; 00139 AsyncTaskChain *_chain; 00140 00141 double _start_time; 00142 int _start_frame; 00143 00144 double _dt; 00145 double _max_dt; 00146 double _total_dt; 00147 int _num_frames; 00148 00149 static AtomicAdjust::Integer _next_task_id; 00150 00151 static PStatCollector _show_code_pcollector; 00152 PStatCollector _task_pcollector; 00153 00154 private: 00155 #ifdef HAVE_PYTHON 00156 PyObject *_python_object; 00157 #endif // HAVE_PYTHON 00158 00159 public: 00160 static TypeHandle get_class_type() { 00161 return _type_handle; 00162 } 00163 static void init_type() { 00164 AsyncTaskBase::init_type(); 00165 register_type(_type_handle, "AsyncTask", 00166 AsyncTaskBase::get_class_type()); 00167 } 00168 virtual TypeHandle get_type() const { 00169 return get_class_type(); 00170 } 00171 virtual TypeHandle force_init_type() {init_type(); return get_class_type();} 00172 00173 private: 00174 static TypeHandle _type_handle; 00175 00176 friend class AsyncTaskManager; 00177 friend class AsyncTaskChain; 00178 friend class AsyncTaskSequence; 00179 }; 00180 00181 INLINE ostream &operator << (ostream &out, const AsyncTask &task) { 00182 task.output(out); 00183 return out; 00184 }; 00185 00186 #include "asyncTask.I" 00187 00188 #endif