add TaskManager- events

This commit is contained in:
David Rose 2008-10-11 14:49:10 +00:00
parent bf6c574747
commit 7683d94100
10 changed files with 98 additions and 41 deletions

View File

@ -445,6 +445,11 @@ do_task() {
////////////////////////////////////////////////////////////////////
void AsyncTask::
upon_birth() {
// Throw a generic add event for the manager.
string add_name = _manager->get_name() + "-addTask";
PT_Event event = new Event(add_name);
event->add_parameter(EventParameter(this));
throw_event(event);
}
////////////////////////////////////////////////////////////////////
@ -455,7 +460,10 @@ upon_birth() {
// parameter clean_exit is true if the task has been
// removed because it exited normally (returning
// DS_done), or false if it was removed for some other
// reason (e.g. AsyncTaskManager::remove()).
// reason (e.g. AsyncTaskManager::remove()). By the
// time this method is called, _manager has been
// cleared, so the parameter manager indicates the
// original AsyncTaskManager that owned this task.
//
// The normal behavior is to throw the done_event only
// if clean_exit is true.
@ -463,10 +471,18 @@ upon_birth() {
// This function is called with the lock *not* held.
////////////////////////////////////////////////////////////////////
void AsyncTask::
upon_death(bool clean_exit) {
upon_death(AsyncTaskManager *manager, bool clean_exit) {
if (clean_exit && !_done_event.empty()) {
PT_Event event = new Event(_done_event);
event->add_parameter(EventParameter(this));
throw_event(event);
}
// Also throw a generic remove event for the manager.
if (manager != (AsyncTaskManager *)NULL) {
string remove_name = manager->get_name() + "-removeTask";
PT_Event event = new Event(remove_name);
event->add_parameter(EventParameter(this));
throw_event(event);
}
}

View File

@ -119,7 +119,7 @@ protected:
virtual bool is_runnable();
virtual DoneStatus do_task();
virtual void upon_birth();
virtual void upon_death(bool clean_exit);
virtual void upon_death(AsyncTaskManager *manager, bool clean_exit);
protected:
AtomicAdjust::Integer _task_id;

View File

@ -645,7 +645,7 @@ do_cleanup() {
// Now go back and call the upon_death functions.
_manager->_lock.release();
for (ti = dead.begin(); ti != dead.end(); ++ti) {
(*ti)->upon_death(false);
(*ti)->upon_death(_manager, false);
}
_manager->_lock.lock();
@ -843,7 +843,7 @@ cleanup_task(AsyncTask *task, bool upon_death, bool clean_exit) {
if (upon_death) {
_manager->_lock.release();
task->upon_death(clean_exit);
task->upon_death(_manager, clean_exit);
_manager->_lock.lock();
}
}

View File

@ -15,8 +15,6 @@
#include "asyncTaskManager.h"
#include "event.h"
#include "pt_Event.h"
#include "throw_event.h"
#include "eventParameter.h"
#include "mutexHolder.h"
#include "indent.h"
#include "pStatClient.h"
@ -375,7 +373,7 @@ remove(const AsyncTaskCollection &tasks) {
}
if (task->_chain->do_remove(task)) {
_lock.release();
task->upon_death(false);
task->upon_death(this, false);
_lock.lock();
++num_removed;
} else {
@ -727,5 +725,5 @@ void AsyncTaskManager::
make_global_ptr() {
nassertv(_global_ptr == (AsyncTaskManager *)NULL);
_global_ptr = new AsyncTaskManager("taskMgr");
_global_ptr = new AsyncTaskManager("TaskManager");
}

View File

@ -146,7 +146,10 @@ upon_birth() {
// parameter clean_exit is true if the task has been
// removed because it exited normally (returning
// DS_done), or false if it was removed for some other
// reason (e.g. AsyncTaskManager::remove()).
// reason (e.g. AsyncTaskManager::remove()). By the
// time this method is called, _manager has been
// cleared, so the parameter manager indicates the
// original AsyncTaskManager that owned this task.
//
// The normal behavior is to throw the done_event only
// if clean_exit is true.
@ -156,8 +159,8 @@ upon_birth() {
// return with it held.
////////////////////////////////////////////////////////////////////
void AsyncTaskSequence::
upon_death(bool clean_exit) {
AsyncTask::upon_death(clean_exit);
upon_death(AsyncTaskManager *manager, bool clean_exit) {
AsyncTask::upon_death(manager, clean_exit);
set_current_task(NULL, clean_exit);
}
@ -177,7 +180,7 @@ set_current_task(AsyncTask *task, bool clean_exit) {
nassertv(_current_task->_state == S_active_nested);
nassertv(_current_task->_manager == _manager || _manager == NULL);
_current_task->_state = S_inactive;
_current_task->upon_death(clean_exit);
_current_task->upon_death(_manager, clean_exit);
_current_task->_manager = NULL;
}

View File

@ -49,7 +49,7 @@ protected:
virtual bool is_runnable();
virtual DoneStatus do_task();
virtual void upon_birth();
virtual void upon_death(bool clean_exit);
virtual void upon_death(AsyncTaskManager *manager, bool clean_exit);
private:
void set_current_task(AsyncTask *task, bool clean_exit);

View File

@ -101,7 +101,10 @@ upon_birth() {
// parameter clean_exit is true if the task has been
// removed because it exited normally (returning
// DS_done), or false if it was removed for some other
// reason (e.g. AsyncTaskManager::remove()).
// reason (e.g. AsyncTaskManager::remove()). By the
// time this method is called, _manager has been
// cleared, so the parameter manager indicates the
// original AsyncTaskManager that owned this task.
//
// The normal behavior is to throw the done_event only
// if clean_exit is true.
@ -109,8 +112,8 @@ upon_birth() {
// This function is called with the lock *not* held.
////////////////////////////////////////////////////////////////////
void GenericAsyncTask::
upon_death(bool clean_exit) {
AsyncTask::upon_death(clean_exit);
upon_death(AsyncTaskManager *manager, bool clean_exit) {
AsyncTask::upon_death(manager, clean_exit);
if (_upon_death != NULL) {
(*_upon_death)(this, clean_exit, _user_data);

View File

@ -51,7 +51,7 @@ protected:
virtual bool is_runnable();
virtual DoneStatus do_task();
virtual void upon_birth();
virtual void upon_death(bool clean_exit);
virtual void upon_death(AsyncTaskManager *manager, bool clean_exit);
private:
TaskFunc *_function;

View File

@ -205,7 +205,7 @@ get_upon_death() {
void PythonTask::
set_owner(PyObject *owner) {
if (_owner != NULL && _owner != Py_None && _state != S_inactive) {
upon_death(false);
unregister_from_owner();
}
Py_XDECREF(_owner);
@ -213,7 +213,7 @@ set_owner(PyObject *owner) {
Py_INCREF(_owner);
if (_owner != Py_None && _state != S_inactive) {
upon_birth();
register_to_owner();
}
}
@ -477,7 +477,54 @@ do_python_task() {
void PythonTask::
upon_birth() {
AsyncTask::upon_birth();
register_to_owner();
}
////////////////////////////////////////////////////////////////////
// Function: PythonTask::upon_death
// Access: Protected, Virtual
// Description: Override this function to do something useful when the
// task has been removed from the active queue. The
// parameter clean_exit is true if the task has been
// removed because it exited normally (returning
// DS_done), or false if it was removed for some other
// reason (e.g. AsyncTaskManager::remove()). By the
// time this method is called, _manager has been
// cleared, so the parameter manager indicates the
// original AsyncTaskManager that owned this task.
//
// The normal behavior is to throw the done_event only
// if clean_exit is true.
//
// This function is called with the lock *not* held.
////////////////////////////////////////////////////////////////////
void PythonTask::
upon_death(AsyncTaskManager *manager, bool clean_exit) {
AsyncTask::upon_death(manager, clean_exit);
if (_upon_death != Py_None) {
#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
// Use PyGILState to protect this asynchronous call.
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
#endif
call_function(_upon_death);
#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
PyGILState_Release(gstate);
#endif
}
unregister_from_owner();
}
////////////////////////////////////////////////////////////////////
// Function: PythonTask::register_to_owner
// Access: Private
// Description: Tells the owner we are now his task.
////////////////////////////////////////////////////////////////////
void PythonTask::
register_to_owner() {
if (_owner != Py_None) {
#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
// Use PyGILState to protect this asynchronous call.
@ -494,25 +541,13 @@ upon_birth() {
}
////////////////////////////////////////////////////////////////////
// Function: PythonTask::upon_death
// Access: Protected, Virtual
// Description: Override this function to do something useful when the
// task has been removed from the active queue. The
// parameter clean_exit is true if the task has been
// removed because it exited normally (returning
// DS_done), or false if it was removed for some other
// reason (e.g. AsyncTaskManager::remove()).
//
// The normal behavior is to throw the done_event only
// if clean_exit is true.
//
// This function is called with the lock *not* held.
// Function: PythonTask::unregister_from_owner
// Access: Private
// Description: Tells the owner we are no longer his task.
////////////////////////////////////////////////////////////////////
void PythonTask::
upon_death(bool clean_exit) {
AsyncTask::upon_death(clean_exit);
if (_owner != Py_None && _upon_death != Py_None) {
unregister_from_owner() {
if (_owner != Py_None) {
#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
// Use PyGILState to protect this asynchronous call.
PyGILState_STATE gstate;
@ -520,7 +555,6 @@ upon_death(bool clean_exit) {
#endif
call_owner_method("_clearTask");
call_function(_upon_death);
#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
PyGILState_Release(gstate);
@ -530,7 +564,7 @@ upon_death(bool clean_exit) {
////////////////////////////////////////////////////////////////////
// Function: PythonTask::call_owner_method
// Access: Protected
// Access: Private
// Description: Calls the indicated method name on the given object,
// if defined, passing in the task object as the only
// parameter.
@ -555,7 +589,7 @@ call_owner_method(const char *method_name) {
////////////////////////////////////////////////////////////////////
// Function: PythonTask::call_function
// Access: Protected
// Access: Private
// Description: Calls the indicated Python function, passing in the
// task object as the only parameter.
////////////////////////////////////////////////////////////////////

View File

@ -52,8 +52,11 @@ protected:
virtual DoneStatus do_task();
DoneStatus do_python_task();
virtual void upon_birth();
virtual void upon_death(bool clean_exit);
virtual void upon_death(AsyncTaskManager *manager, bool clean_exit);
private:
void register_to_owner();
void unregister_from_owner();
void call_owner_method(const char *method_name);
void call_function(PyObject *function);