Browse Source

event: AsyncFuture::set_result() behavior changes:
* Passing a Python subclass of a C++ class now works, the extra Python stuff isn't just discarded
* EventParameter objects are no longer automagically unwrapped - there's no more reason to pass an EventParameter to this method anyway, and it might be unexpected if it is treated specially.

rdb 4 years ago
parent
commit
050d86dadb
2 changed files with 19 additions and 21 deletions
  1. 16 18
      panda/src/event/asyncFuture_ext.cxx
  2. 3 3
      tests/event/test_futures.py

+ 16 - 18
panda/src/event/asyncFuture_ext.cxx

@@ -13,7 +13,6 @@
 
 
 #include "asyncFuture_ext.h"
 #include "asyncFuture_ext.h"
 #include "asyncTaskSequence.h"
 #include "asyncTaskSequence.h"
-#include "eventParameter.h"
 #include "paramValue.h"
 #include "paramValue.h"
 #include "paramPyObject.h"
 #include "paramPyObject.h"
 #include "pythonTask.h"
 #include "pythonTask.h"
@@ -24,7 +23,6 @@
 
 
 #ifndef CPPPARSER
 #ifndef CPPPARSER
 extern struct Dtool_PyTypedObject Dtool_AsyncFuture;
 extern struct Dtool_PyTypedObject Dtool_AsyncFuture;
-extern struct Dtool_PyTypedObject Dtool_EventParameter;
 extern struct Dtool_PyTypedObject Dtool_ParamValueBase;
 extern struct Dtool_PyTypedObject Dtool_ParamValueBase;
 extern struct Dtool_PyTypedObject Dtool_TypedObject;
 extern struct Dtool_PyTypedObject Dtool_TypedObject;
 extern struct Dtool_PyTypedObject Dtool_TypedReferenceCount;
 extern struct Dtool_PyTypedObject Dtool_TypedReferenceCount;
@@ -174,22 +172,22 @@ set_result(PyObject *result) {
     return;
     return;
   }
   }
   else if (DtoolInstance_Check(result)) {
   else if (DtoolInstance_Check(result)) {
-    void *ptr;
-    if ((ptr = DtoolInstance_UPCAST(result, Dtool_EventParameter))) {
-      _this->set_result(*(const EventParameter *)ptr);
-      return;
-    }
-    if ((ptr = DtoolInstance_UPCAST(result, Dtool_TypedWritableReferenceCount))) {
-      _this->set_result((TypedWritableReferenceCount *)ptr);
-      return;
-    }
-    if ((ptr = DtoolInstance_UPCAST(result, Dtool_TypedReferenceCount))) {
-      _this->set_result((TypedReferenceCount *)ptr);
-      return;
-    }
-    if ((ptr = DtoolInstance_UPCAST(result, Dtool_TypedObject))) {
-      _this->set_result((TypedObject *)ptr);
-      return;
+    // If this is a Python subclass of a C++ type, fall through to below, since
+    // we don't want to lose that extra information.
+    if (Py_TYPE(result) == (PyTypeObject *)DtoolInstance_TYPE(result)) {
+      void *ptr;
+      if ((ptr = DtoolInstance_UPCAST(result, Dtool_TypedWritableReferenceCount))) {
+        _this->set_result((TypedWritableReferenceCount *)ptr);
+        return;
+      }
+      if ((ptr = DtoolInstance_UPCAST(result, Dtool_TypedReferenceCount))) {
+        _this->set_result((TypedReferenceCount *)ptr);
+        return;
+      }
+      if ((ptr = DtoolInstance_UPCAST(result, Dtool_TypedObject))) {
+        _this->set_result((TypedObject *)ptr);
+        return;
+      }
     }
     }
   }
   }
   else if (PyUnicode_Check(result)) {
   else if (PyUnicode_Check(result)) {

+ 3 - 3
tests/event/test_futures.py

@@ -200,12 +200,12 @@ def test_future_result():
     fut = None
     fut = None
     assert tex.get_ref_count() == rc
     assert tex.get_ref_count() == rc
 
 
-    # Store EventParameter (gets unwrapped)
+    # Store EventParameter (no longer gets unwrapped)
     ep = core.EventParameter(0.5)
     ep = core.EventParameter(0.5)
     fut = core.AsyncFuture()
     fut = core.AsyncFuture()
     fut.set_result(ep)
     fut.set_result(ep)
-    assert fut.result() == 0.5
-    assert fut.result() == 0.5
+    assert fut.result() is ep
+    assert fut.result() is ep
 
 
     # Store TypedObject
     # Store TypedObject
     dg = core.Datagram(b"test")
     dg = core.Datagram(b"test")