00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "asyncTaskSequence.h"
00016
00017 TypeHandle AsyncTaskSequence::_type_handle;
00018
00019
00020
00021
00022
00023
00024 AsyncTaskSequence::
00025 AsyncTaskSequence(const string &name) :
00026 AsyncTask(name),
00027 _repeat_count(0),
00028 _task_index(0)
00029 {
00030 }
00031
00032
00033
00034
00035
00036
00037 AsyncTaskSequence::
00038 ~AsyncTaskSequence() {
00039 set_current_task(NULL, true);
00040 }
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 bool AsyncTaskSequence::
00053 is_runnable() {
00054 return (get_num_tasks() > 0);
00055 }
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 AsyncTask::DoneStatus AsyncTaskSequence::
00066 do_task() {
00067
00068 _delay = 0.0;
00069 _has_delay = false;
00070
00071 if (_task_index >= get_num_tasks()) {
00072
00073 set_current_task(NULL, true);
00074 _task_index = 0;
00075 if (_task_index >= get_num_tasks()) {
00076 return DS_done;
00077 }
00078 if (_repeat_count > 0) {
00079 --_repeat_count;
00080 }
00081 if (_repeat_count != 0) {
00082 return DS_cont;
00083 }
00084 return DS_done;
00085 }
00086
00087 AsyncTask *task = get_task(_task_index);
00088 set_current_task(task, true);
00089 nassertr(_current_task != (AsyncTask *)NULL, DS_exit);
00090
00091 DoneStatus result = _current_task->do_task();
00092 switch (result) {
00093 case DS_again:
00094 case DS_pause:
00095
00096 {
00097 double now = _manager->_clock->get_frame_time();
00098 _current_task->_start_time = now + _current_task->_delay;
00099
00100 _delay = _current_task->_delay;
00101 _has_delay = _current_task->_has_delay;
00102
00103 if (result == DS_pause) {
00104
00105 ++_task_index;
00106 }
00107 }
00108 return DS_again;
00109
00110 case DS_done:
00111
00112 ++_task_index;
00113 return DS_cont;
00114
00115 case DS_cont:
00116 case DS_pickup:
00117 case DS_exit:
00118 case DS_interrupt:
00119
00120 return result;
00121 }
00122
00123
00124 nassertr(false, DS_exit);
00125 return DS_exit;
00126 }
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 void AsyncTaskSequence::
00139 upon_birth(AsyncTaskManager *manager) {
00140 AsyncTask::upon_birth(manager);
00141 _task_index = 0;
00142 set_current_task(NULL, true);
00143 }
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 void AsyncTaskSequence::
00166 upon_death(AsyncTaskManager *manager, bool clean_exit) {
00167 AsyncTask::upon_death(manager, clean_exit);
00168 set_current_task(NULL, clean_exit);
00169 }
00170
00171
00172
00173
00174
00175
00176
00177 void AsyncTaskSequence::
00178 set_current_task(AsyncTask *task, bool clean_exit) {
00179 if (_current_task == task) {
00180 return;
00181 }
00182
00183 if (_current_task != (AsyncTask *)NULL) {
00184 nassertv(_current_task->_state == S_active_nested);
00185 nassertv(_current_task->_manager == _manager || _manager == NULL);
00186 _current_task->_state = S_inactive;
00187 _current_task->_manager = NULL;
00188 _current_task->upon_death(_manager, clean_exit);
00189 }
00190
00191 _current_task = task;
00192
00193 if (_current_task != (AsyncTask *)NULL) {
00194 nassertv(_current_task->_state == S_inactive);
00195 nassertv(_current_task->_manager == NULL);
00196 _current_task->upon_birth(_manager);
00197 nassertv(_current_task->_state == S_inactive);
00198 nassertv(_current_task->_manager == NULL);
00199 _current_task->_manager = _manager;
00200 _current_task->_state = S_active_nested;
00201
00202 double now = _manager->_clock->get_frame_time();
00203 task->_start_time = now;
00204 task->_start_frame = _manager->_clock->get_frame_count();
00205 }
00206 }