diff --git a/panda/src/event/asyncTask.cxx b/panda/src/event/asyncTask.cxx index 815b07a1f1..96fed2670a 100644 --- a/panda/src/event/asyncTask.cxx +++ b/panda/src/event/asyncTask.cxx @@ -349,6 +349,21 @@ unlock_and_do_task() { return status; } +//////////////////////////////////////////////////////////////////// +// Function: AsyncTask::is_runnable +// Access: Protected, Virtual +// Description: Override this function to return true if the task can +// be successfully executed, false if it cannot. Mainly +// intended as a sanity check when attempting to add the +// task to a task manager. +// +// This function is called with the lock held. +//////////////////////////////////////////////////////////////////// +bool AsyncTask:: +is_runnable() { + return true; +} + //////////////////////////////////////////////////////////////////// // Function: AsyncTask::do_task // Access: Protected, Virtual diff --git a/panda/src/event/asyncTask.h b/panda/src/event/asyncTask.h index 2463e69b1c..91f6c51ed2 100644 --- a/panda/src/event/asyncTask.h +++ b/panda/src/event/asyncTask.h @@ -111,6 +111,7 @@ protected: void jump_to_task_chain(AsyncTaskManager *manager); DoneStatus unlock_and_do_task(); + virtual bool is_runnable(); virtual DoneStatus do_task(); virtual void upon_birth(); virtual void upon_death(bool clean_exit); diff --git a/panda/src/event/asyncTaskManager.cxx b/panda/src/event/asyncTaskManager.cxx index 53936f7fd1..bdc0084079 100644 --- a/panda/src/event/asyncTaskManager.cxx +++ b/panda/src/event/asyncTaskManager.cxx @@ -167,6 +167,8 @@ remove_task_chain(const string &name) { //////////////////////////////////////////////////////////////////// void AsyncTaskManager:: add(AsyncTask *task) { + nassertv(task->is_runnable()); + MutexHolder holder(_lock); if (task_cat.is_debug()) { diff --git a/panda/src/event/pythonTask.cxx b/panda/src/event/pythonTask.cxx index 53da1c5044..328f048481 100644 --- a/panda/src/event/pythonTask.cxx +++ b/panda/src/event/pythonTask.cxx @@ -79,7 +79,7 @@ set_function(PyObject *function) { _function = function; Py_INCREF(_function); - if (!PyCallable_Check(_function)) { + if (_function != Py_None && !PyCallable_Check(_function)) { nassert_raise("Invalid function passed to PythonTask"); } } @@ -306,6 +306,21 @@ __getattr__(const string &attr_name) const { } } +//////////////////////////////////////////////////////////////////// +// Function: PythonTask::is_runnable +// Access: Protected, Virtual +// Description: Override this function to return true if the task can +// be successfully executed, false if it cannot. Mainly +// intended as a sanity check when attempting to add the +// task to a task manager. +// +// This function is called with the lock held. +//////////////////////////////////////////////////////////////////// +bool PythonTask:: +is_runnable() { + return _function != Py_None; +} + //////////////////////////////////////////////////////////////////// // Function: PythonTask::do_task // Access: Protected, Virtual diff --git a/panda/src/event/pythonTask.h b/panda/src/event/pythonTask.h index 9d3e48d364..13526e85a5 100644 --- a/panda/src/event/pythonTask.h +++ b/panda/src/event/pythonTask.h @@ -27,7 +27,7 @@ //////////////////////////////////////////////////////////////////// class EXPCL_PANDA_PIPELINE PythonTask : public AsyncTask { PUBLISHED: - PythonTask(PyObject *function, const string &name = string()); + PythonTask(PyObject *function = Py_None, const string &name = string()); virtual ~PythonTask(); ALLOC_DELETED_CHAIN(PythonTask); @@ -48,6 +48,7 @@ PUBLISHED: PyObject *__getattr__(const string &attr_name) const; protected: + virtual bool is_runnable(); virtual DoneStatus do_task(); DoneStatus do_python_task(); virtual void upon_birth();