mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-29 08:15:18 -04:00
event: use the persistent python wrapper when appending task object (#1681)
This commit is contained in:
parent
fc394e4c59
commit
cfe3885c0e
@ -174,9 +174,15 @@ get_args() {
|
|||||||
PyTuple_SET_ITEM(with_task, i, Py_NewRef(item));
|
PyTuple_SET_ITEM(with_task, i, Py_NewRef(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
this->ref();
|
// Check whether we have a Python wrapper. This is not the case if the
|
||||||
PyObject *self = DTool_CreatePyInstance(this, Dtool_PythonTask, true, false);
|
// object has been created by C++ and never been exposed to Python code.
|
||||||
PyTuple_SET_ITEM(with_task, num_args, self);
|
if (__self__ == nullptr) {
|
||||||
|
// A __self__ instance does not exist, let's create one now.
|
||||||
|
this->ref();
|
||||||
|
__self__ = DTool_CreatePyInstance(this, Dtool_PythonTask, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyTuple_SET_ITEM(with_task, num_args, Py_NewRef(__self__));
|
||||||
return with_task;
|
return with_task;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1004,11 +1010,16 @@ call_owner_method(const char *method_name) {
|
|||||||
void PythonTask::
|
void PythonTask::
|
||||||
call_function(PyObject *function) {
|
call_function(PyObject *function) {
|
||||||
if (function != Py_None) {
|
if (function != Py_None) {
|
||||||
this->ref();
|
// Check whether we have a Python wrapper. This is not the case if the
|
||||||
PyObject *self = DTool_CreatePyInstance(this, Dtool_PythonTask, true, false);
|
// object has been created by C++ and never been exposed to Python code.
|
||||||
PyObject *result = PyObject_CallOneArg(function, self);
|
if (__self__ == nullptr) {
|
||||||
|
// A __self__ instance does not exist, let's create one now.
|
||||||
|
this->ref();
|
||||||
|
__self__ = DTool_CreatePyInstance(this, Dtool_PythonTask, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *result = PyObject_CallOneArg(function, __self__);
|
||||||
Py_XDECREF(result);
|
Py_XDECREF(result);
|
||||||
Py_DECREF(self);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from panda3d.core import PythonTask
|
from panda3d.core import AsyncTaskManager, PythonTask
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
import pytest
|
import pytest
|
||||||
import types
|
import types
|
||||||
@ -115,3 +115,39 @@ def test_pythontask_cycle():
|
|||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
pytest.fail('not found in garbage')
|
pytest.fail('not found in garbage')
|
||||||
|
|
||||||
|
def test_task_persistent_wrapper():
|
||||||
|
task_mgr = AsyncTaskManager.get_global_ptr()
|
||||||
|
task_chain = task_mgr.make_task_chain("test_task_persistent_wrapper")
|
||||||
|
|
||||||
|
# Create a subclass of PythonTask
|
||||||
|
class PythonTaskSubclassTest(PythonTask):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def task_main(task):
|
||||||
|
# Set our result to be the input task we got into this function
|
||||||
|
task.set_result(task)
|
||||||
|
# Verify we got the subclass
|
||||||
|
assert isinstance(task, PythonTaskSubclassTest)
|
||||||
|
return task.done
|
||||||
|
|
||||||
|
done_callback_reached = False
|
||||||
|
|
||||||
|
def done_callback(task):
|
||||||
|
# Verify we got the subclass
|
||||||
|
assert isinstance(task, PythonTaskSubclassTest)
|
||||||
|
nonlocal done_callback_reached
|
||||||
|
done_callback_reached = True
|
||||||
|
|
||||||
|
task = PythonTaskSubclassTest(task_main)
|
||||||
|
task.set_task_chain(task_chain.name)
|
||||||
|
task.set_upon_death(done_callback)
|
||||||
|
task_mgr.add(task)
|
||||||
|
task_chain.wait_for_tasks()
|
||||||
|
|
||||||
|
assert task.done()
|
||||||
|
assert not task.cancelled()
|
||||||
|
# Verify the task passed into the function is the same task we created
|
||||||
|
assert task.result() is task
|
||||||
|
# Verify the done callback worked and was tested
|
||||||
|
assert done_callback_reached
|
||||||
|
Loading…
x
Reference in New Issue
Block a user