Browse Source

Merge branch 'release/1.10.x'

rdb 4 months ago
parent
commit
9a2da04573

+ 10 - 5
panda/src/collide/collisionBox.cxx

@@ -343,7 +343,8 @@ test_intersection_from_line(const CollisionEntry &entry) const {
   const CollisionLine *line;
   DCAST_INTO_R(line, entry.get_from(), nullptr);
 
-  const LMatrix4 &wrt_mat = entry.get_wrt_mat();
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  const LMatrix4 &wrt_mat = wrt_space->get_mat();
 
   LPoint3 from_origin = line->get_origin() * wrt_mat;
   LVector3 from_direction = line->get_direction() * wrt_mat;
@@ -386,7 +387,8 @@ PT(CollisionEntry) CollisionBox::
 test_intersection_from_ray(const CollisionEntry &entry) const {
   const CollisionRay *ray;
   DCAST_INTO_R(ray, entry.get_from(), nullptr);
-  const LMatrix4 &wrt_mat = entry.get_wrt_mat();
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  const LMatrix4 &wrt_mat = wrt_space->get_mat();
 
   LPoint3 from_origin = ray->get_origin() * wrt_mat;
   LVector3 from_direction = ray->get_direction() * wrt_mat;
@@ -511,7 +513,8 @@ PT(CollisionEntry) CollisionBox::
 test_intersection_from_segment(const CollisionEntry &entry) const {
   const CollisionSegment *seg;
   DCAST_INTO_R(seg, entry.get_from(), nullptr);
-  const LMatrix4 &wrt_mat = entry.get_wrt_mat();
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  const LMatrix4 &wrt_mat = wrt_space->get_mat();
 
   LPoint3 from_origin = seg->get_point_a() * wrt_mat;
   LPoint3 from_extent = seg->get_point_b() * wrt_mat;
@@ -566,7 +569,8 @@ test_intersection_from_capsule(const CollisionEntry &entry) const {
   const CollisionCapsule *capsule;
   DCAST_INTO_R(capsule, entry.get_from(), nullptr);
 
-  const LMatrix4 &wrt_mat = entry.get_wrt_mat();
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  const LMatrix4 &wrt_mat = wrt_space->get_mat();
 
   LPoint3 from_a = capsule->get_point_a() * wrt_mat;
   LPoint3 from_b = capsule->get_point_b() * wrt_mat;
@@ -711,7 +715,8 @@ test_intersection_from_box(const CollisionEntry &entry) const {
   const CollisionBox *box;
   DCAST_INTO_R(box, entry.get_from(), nullptr);
 
-  const LMatrix4 &wrt_mat = entry.get_wrt_mat();
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  const LMatrix4 &wrt_mat = wrt_space->get_mat();
 
   LPoint3 diff = wrt_mat.xform_point_general(box->get_center()) - _center;
   LVector3 from_extents = box->get_dimensions() * 0.5f;

+ 10 - 5
panda/src/collide/collisionCapsule.cxx

@@ -308,7 +308,8 @@ test_intersection_from_line(const CollisionEntry &entry) const {
   const CollisionLine *line;
   DCAST_INTO_R(line, entry.get_from(), nullptr);
 
-  const LMatrix4 &wrt_mat = entry.get_wrt_mat();
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  const LMatrix4 &wrt_mat = wrt_space->get_mat();
 
   LPoint3 from_origin = line->get_origin() * wrt_mat;
   LVector3 from_direction = line->get_direction() * wrt_mat;
@@ -356,7 +357,8 @@ test_intersection_from_ray(const CollisionEntry &entry) const {
   const CollisionRay *ray;
   DCAST_INTO_R(ray, entry.get_from(), nullptr);
 
-  const LMatrix4 &wrt_mat = entry.get_wrt_mat();
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  const LMatrix4 &wrt_mat = wrt_space->get_mat();
 
   LPoint3 from_origin = ray->get_origin() * wrt_mat;
   LVector3 from_direction = ray->get_direction() * wrt_mat;
@@ -417,7 +419,8 @@ test_intersection_from_segment(const CollisionEntry &entry) const {
   const CollisionSegment *segment;
   DCAST_INTO_R(segment, entry.get_from(), nullptr);
 
-  const LMatrix4 &wrt_mat = entry.get_wrt_mat();
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  const LMatrix4 &wrt_mat = wrt_space->get_mat();
 
   LPoint3 from_a = segment->get_point_a() * wrt_mat;
   LPoint3 from_b = segment->get_point_b() * wrt_mat;
@@ -484,7 +487,8 @@ test_intersection_from_capsule(const CollisionEntry &entry) const {
   LPoint3 into_a = _a;
   LVector3 into_direction = _b - into_a;
 
-  const LMatrix4 &wrt_mat = entry.get_wrt_mat();
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  const LMatrix4 &wrt_mat = wrt_space->get_mat();
 
   LPoint3 from_a = capsule->get_point_a() * wrt_mat;
   LPoint3 from_b = capsule->get_point_b() * wrt_mat;
@@ -545,7 +549,8 @@ test_intersection_from_parabola(const CollisionEntry &entry) const {
   const CollisionParabola *parabola;
   DCAST_INTO_R(parabola, entry.get_from(), nullptr);
 
-  const LMatrix4 &wrt_mat = entry.get_wrt_mat();
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  const LMatrix4 &wrt_mat = wrt_space->get_mat();
 
   // Convert the parabola into local coordinate space.
   LParabola local_p(parabola->get_parabola());

+ 6 - 2
panda/src/collide/collisionFloorMesh.cxx

@@ -130,7 +130,9 @@ PT(CollisionEntry) CollisionFloorMesh::
 test_intersection_from_ray(const CollisionEntry &entry) const {
   const CollisionRay *ray;
   DCAST_INTO_R(ray, entry.get_from(), nullptr);
-  LPoint3 from_origin = ray->get_origin() * entry.get_wrt_mat();
+
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  LPoint3 from_origin = ray->get_origin() * wrt_space->get_mat();
 
   double fx = from_origin[0];
   double fy = from_origin[1];
@@ -195,7 +197,9 @@ PT(CollisionEntry) CollisionFloorMesh::
 test_intersection_from_sphere(const CollisionEntry &entry) const {
   const CollisionSphere *sphere;
   DCAST_INTO_R(sphere, entry.get_from(), nullptr);
-  LPoint3 from_origin = sphere->get_center() * entry.get_wrt_mat();
+
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  LPoint3 from_origin = sphere->get_center() * wrt_space->get_mat();
 
   double fx = from_origin[0];
   double fy = from_origin[1];

+ 12 - 6
panda/src/collide/collisionInvSphere.cxx

@@ -97,7 +97,8 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
   const CollisionSphere *sphere;
   DCAST_INTO_R(sphere, entry.get_from(), nullptr);
 
-  const LMatrix4 &wrt_mat = entry.get_wrt_mat();
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  const LMatrix4 &wrt_mat = wrt_space->get_mat();
 
   LPoint3 from_center = sphere->get_center() * wrt_mat;
   LVector3 from_radius_v =
@@ -149,7 +150,8 @@ test_intersection_from_line(const CollisionEntry &entry) const {
   const CollisionLine *line;
   DCAST_INTO_R(line, entry.get_from(), nullptr);
 
-  const LMatrix4 &wrt_mat = entry.get_wrt_mat();
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  const LMatrix4 &wrt_mat = wrt_space->get_mat();
 
   LPoint3 from_origin = line->get_origin() * wrt_mat;
   LVector3 from_direction = line->get_direction() * wrt_mat;
@@ -190,7 +192,8 @@ test_intersection_from_ray(const CollisionEntry &entry) const {
   const CollisionRay *ray;
   DCAST_INTO_R(ray, entry.get_from(), nullptr);
 
-  const LMatrix4 &wrt_mat = entry.get_wrt_mat();
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  const LMatrix4 &wrt_mat = wrt_space->get_mat();
 
   LPoint3 from_origin = ray->get_origin() * wrt_mat;
   LVector3 from_direction = ray->get_direction() * wrt_mat;
@@ -233,7 +236,8 @@ test_intersection_from_segment(const CollisionEntry &entry) const {
   const CollisionSegment *segment;
   DCAST_INTO_R(segment, entry.get_from(), nullptr);
 
-  const LMatrix4 &wrt_mat = entry.get_wrt_mat();
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  const LMatrix4 &wrt_mat = wrt_space->get_mat();
 
   LPoint3 from_a = segment->get_point_a() * wrt_mat;
   LPoint3 from_b = segment->get_point_b() * wrt_mat;
@@ -411,7 +415,8 @@ test_intersection_from_capsule(const CollisionEntry &entry) const {
   const CollisionCapsule *capsule;
   DCAST_INTO_R(capsule, entry.get_from(), nullptr);
 
-  const LMatrix4 &wrt_mat = entry.get_wrt_mat();
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  const LMatrix4 &wrt_mat = wrt_space->get_mat();
 
   LPoint3 from_a = capsule->get_point_a() * wrt_mat;
   LPoint3 from_b = capsule->get_point_b() * wrt_mat;
@@ -466,7 +471,8 @@ test_intersection_from_box(const CollisionEntry &entry) const {
   const CollisionBox *box;
   DCAST_INTO_R(box, entry.get_from(), nullptr);
 
-  const LMatrix4 &wrt_mat = entry.get_wrt_mat();
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  const LMatrix4 &wrt_mat = wrt_space->get_mat();
 
   LPoint3 center = get_center();
   PN_stdfloat radius_sq = get_radius();

+ 14 - 7
panda/src/collide/collisionPlane.cxx

@@ -109,7 +109,8 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
   const CollisionSphere *sphere;
   DCAST_INTO_R(sphere, entry.get_from(), nullptr);
 
-  const LMatrix4 &wrt_mat = entry.get_wrt_mat();
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  const LMatrix4 &wrt_mat = wrt_space->get_mat();
 
   LPoint3 from_center = sphere->get_center() * wrt_mat;
   LVector3 from_radius_v =
@@ -148,7 +149,8 @@ test_intersection_from_line(const CollisionEntry &entry) const {
   const CollisionLine *line;
   DCAST_INTO_R(line, entry.get_from(), nullptr);
 
-  const LMatrix4 &wrt_mat = entry.get_wrt_mat();
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  const LMatrix4 &wrt_mat = wrt_space->get_mat();
 
   LPoint3 from_origin = line->get_origin() * wrt_mat;
   LVector3 from_direction = line->get_direction() * wrt_mat;
@@ -193,7 +195,8 @@ test_intersection_from_ray(const CollisionEntry &entry) const {
   const CollisionRay *ray;
   DCAST_INTO_R(ray, entry.get_from(), nullptr);
 
-  const LMatrix4 &wrt_mat = entry.get_wrt_mat();
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  const LMatrix4 &wrt_mat = wrt_space->get_mat();
 
   LPoint3 from_origin = ray->get_origin() * wrt_mat;
   LVector3 from_direction = ray->get_direction() * wrt_mat;
@@ -245,7 +248,8 @@ test_intersection_from_segment(const CollisionEntry &entry) const {
   const CollisionSegment *segment;
   DCAST_INTO_R(segment, entry.get_from(), nullptr);
 
-  const LMatrix4 &wrt_mat = entry.get_wrt_mat();
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  const LMatrix4 &wrt_mat = wrt_space->get_mat();
 
   LPoint3 from_a = segment->get_point_a() * wrt_mat;
   LPoint3 from_b = segment->get_point_b() * wrt_mat;
@@ -302,7 +306,8 @@ test_intersection_from_capsule(const CollisionEntry &entry) const {
   const CollisionCapsule *capsule;
   DCAST_INTO_R(capsule, entry.get_from(), nullptr);
 
-  const LMatrix4 &wrt_mat = entry.get_wrt_mat();
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  const LMatrix4 &wrt_mat = wrt_space->get_mat();
 
   LPoint3 from_a = capsule->get_point_a() * wrt_mat;
   LPoint3 from_b = capsule->get_point_b() * wrt_mat;
@@ -373,7 +378,8 @@ test_intersection_from_parabola(const CollisionEntry &entry) const {
   const CollisionParabola *parabola;
   DCAST_INTO_R(parabola, entry.get_from(), nullptr);
 
-  const LMatrix4 &wrt_mat = entry.get_wrt_mat();
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  const LMatrix4 &wrt_mat = wrt_space->get_mat();
 
   // Convert the parabola into local coordinate space.
   LParabola local_p(parabola->get_parabola());
@@ -439,7 +445,8 @@ test_intersection_from_box(const CollisionEntry &entry) const {
   const CollisionBox *box;
   DCAST_INTO_R(box, entry.get_from(), nullptr);
 
-  const LMatrix4 &wrt_mat = entry.get_wrt_mat();
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  const LMatrix4 &wrt_mat = wrt_space->get_mat();
 
   LPoint3 from_center = box->get_center() * wrt_mat;
   LVector3 from_extents = box->get_dimensions() * 0.5f;

+ 8 - 4
panda/src/collide/collisionPolygon.cxx

@@ -584,7 +584,8 @@ test_intersection_from_line(const CollisionEntry &entry) const {
   const CollisionLine *line;
   DCAST_INTO_R(line, entry.get_from(), nullptr);
 
-  const LMatrix4 &wrt_mat = entry.get_wrt_mat();
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  const LMatrix4 &wrt_mat = wrt_space->get_mat();
 
   LPoint3 from_origin = line->get_origin() * wrt_mat;
   LVector3 from_direction = line->get_direction() * wrt_mat;
@@ -652,7 +653,8 @@ test_intersection_from_ray(const CollisionEntry &entry) const {
   const CollisionRay *ray;
   DCAST_INTO_R(ray, entry.get_from(), nullptr);
 
-  const LMatrix4 &wrt_mat = entry.get_wrt_mat();
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  const LMatrix4 &wrt_mat = wrt_space->get_mat();
 
   LPoint3 from_origin = ray->get_origin() * wrt_mat;
   LVector3 from_direction = ray->get_direction() * wrt_mat;
@@ -725,7 +727,8 @@ test_intersection_from_segment(const CollisionEntry &entry) const {
   const CollisionSegment *segment;
   DCAST_INTO_R(segment, entry.get_from(), nullptr);
 
-  const LMatrix4 &wrt_mat = entry.get_wrt_mat();
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  const LMatrix4 &wrt_mat = wrt_space->get_mat();
 
   LPoint3 from_a = segment->get_point_a() * wrt_mat;
   LPoint3 from_b = segment->get_point_b() * wrt_mat;
@@ -1047,7 +1050,8 @@ test_intersection_from_parabola(const CollisionEntry &entry) const {
   const CollisionParabola *parabola;
   DCAST_INTO_R(parabola, entry.get_from(), nullptr);
 
-  const LMatrix4 &wrt_mat = entry.get_wrt_mat();
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  const LMatrix4 &wrt_mat = wrt_space->get_mat();
 
   // Convert the parabola into local coordinate space.
   LParabola local_p(parabola->get_parabola());

+ 16 - 9
panda/src/collide/collisionSphere.cxx

@@ -242,7 +242,8 @@ test_intersection_from_line(const CollisionEntry &entry) const {
   const CollisionLine *line;
   DCAST_INTO_R(line, entry.get_from(), nullptr);
 
-  const LMatrix4 &wrt_mat = entry.get_wrt_mat();
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  const LMatrix4 &wrt_mat = wrt_space->get_mat();
 
   LPoint3 from_origin = line->get_origin() * wrt_mat;
   LVector3 from_direction = line->get_direction() * wrt_mat;
@@ -284,10 +285,11 @@ test_intersection_from_box(const CollisionEntry &entry) const {
 
   // Instead of transforming the box into the sphere's coordinate space, we do
   // it the other way around.  It's easier that way.
-  const LMatrix4 &wrt_mat = entry.get_inv_wrt_mat();
+  CPT(TransformState) inv_wrt_space = entry.get_inv_wrt_space();
+  const LMatrix4 &inv_wrt_mat = inv_wrt_space->get_mat();
 
-  LPoint3 center = wrt_mat.xform_point(_center);
-  PN_stdfloat radius_sq = wrt_mat.xform_vec(LVector3(0, 0, _radius)).length_squared();
+  LPoint3 center = inv_wrt_mat.xform_point(_center);
+  PN_stdfloat radius_sq = inv_wrt_mat.xform_vec(LVector3(0, 0, _radius)).length_squared();
 
   LPoint3 box_min = box->get_min();
   LPoint3 box_max = box->get_max();
@@ -336,7 +338,8 @@ test_intersection_from_box(const CollisionEntry &entry) const {
   PT(CollisionEntry) new_entry = new CollisionEntry(entry);
 
   // To get the interior point, clamp the sphere center to the AABB.
-  LPoint3 interior = entry.get_wrt_mat().xform_point(center.fmax(box_min).fmin(box_max));
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  LPoint3 interior = wrt_space->get_mat().xform_point(center.fmax(box_min).fmin(box_max));
   new_entry->set_interior_point(interior);
 
   // Now extrapolate the surface point and normal from that.
@@ -358,7 +361,8 @@ test_intersection_from_ray(const CollisionEntry &entry) const {
   const CollisionRay *ray;
   DCAST_INTO_R(ray, entry.get_from(), nullptr);
 
-  const LMatrix4 &wrt_mat = entry.get_wrt_mat();
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  const LMatrix4 &wrt_mat = wrt_space->get_mat();
 
   LPoint3 from_origin = ray->get_origin() * wrt_mat;
   LVector3 from_direction = ray->get_direction() * wrt_mat;
@@ -405,7 +409,8 @@ test_intersection_from_segment(const CollisionEntry &entry) const {
   const CollisionSegment *segment;
   DCAST_INTO_R(segment, entry.get_from(), nullptr);
 
-  const LMatrix4 &wrt_mat = entry.get_wrt_mat();
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  const LMatrix4 &wrt_mat = wrt_space->get_mat();
 
   LPoint3 from_a = segment->get_point_a() * wrt_mat;
   LPoint3 from_b = segment->get_point_b() * wrt_mat;
@@ -454,7 +459,8 @@ test_intersection_from_capsule(const CollisionEntry &entry) const {
   const CollisionCapsule *capsule;
   DCAST_INTO_R(capsule, entry.get_from(), nullptr);
 
-  const LMatrix4 &wrt_mat = entry.get_wrt_mat();
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  const LMatrix4 &wrt_mat = wrt_space->get_mat();
 
   LPoint3 from_a = capsule->get_point_a() * wrt_mat;
   LPoint3 from_b = capsule->get_point_b() * wrt_mat;
@@ -510,7 +516,8 @@ test_intersection_from_parabola(const CollisionEntry &entry) const {
   const CollisionParabola *parabola;
   DCAST_INTO_R(parabola, entry.get_from(), nullptr);
 
-  const LMatrix4 &wrt_mat = entry.get_wrt_mat();
+  CPT(TransformState) wrt_space = entry.get_wrt_space();
+  const LMatrix4 &wrt_mat = wrt_space->get_mat();
 
   // Convert the parabola into local coordinate space.
   LParabola local_p(parabola->get_parabola());

+ 5 - 23
panda/src/egg2pg/eggSaver.cxx

@@ -1229,34 +1229,16 @@ apply_state_properties(EggRenderMode *egg_render_mode, const RenderState *state)
  */
 bool EggSaver::
 apply_tags(EggGroup *egg_group, PandaNode *node) {
-  std::ostringstream strm;
-  char delimiter = '\n';
-  string delimiter_str(1, delimiter);
-  node->list_tags(strm, delimiter_str);
-
-  string data = strm.str();
-  if (data.empty()) {
-    return false;
-  }
-
   bool any_applied = false;
 
-  size_t p = 0;
-  size_t q = data.find(delimiter);
-  while (q != string::npos) {
-    string tag = data.substr(p, q);
-    if (apply_tag(egg_group, node, tag)) {
+  vector_string keys;
+  node->get_tag_keys(keys);
+
+  for (size_t i = 0; i < keys.size(); ++i) {
+    if (apply_tag(egg_group, node, keys[i])) {
       any_applied = true;
     }
-    p = q + 1;
-    q = data.find(delimiter, p);
   }
-
-  string tag = data.substr(p);
-  if (apply_tag(egg_group, node, tag)) {
-    any_applied = true;
-  }
-
   return any_applied;
 }
 

+ 23 - 2
panda/src/event/asyncFuture_ext.cxx

@@ -145,9 +145,30 @@ static PyObject *gen_next_asyncfuture(PyObject *self) {
   else {
     PyObject *result = get_done_result(future);
     if (result != nullptr) {
-      PyErr_SetObject(PyExc_StopIteration, result);
-      // PyErr_SetObject increased the reference count, so we no longer need our reference.
+      // See python/cpython#101578 - PyErr_SetObject has a special case where
+      // it interprets a tuple specially, so we bypass that by creating the
+      // exception directly.
+#if PY_VERSION_HEX >= 0x030C0000 // 3.12
+      PyObject *exc = PyObject_CallOneArg(PyExc_StopIteration, result);
       Py_DECREF(result);
+      if (LIKELY(exc != nullptr)) {
+        // This function steals a reference to exc.
+        PyErr_SetRaisedException(exc);
+      }
+#else
+      if (PyTuple_Check(result)) {
+        PyObject *exc = PyObject_CallOneArg(PyExc_StopIteration, result);
+        Py_DECREF(result);
+        if (LIKELY(exc != nullptr)) {
+          PyErr_SetObject(PyExc_StopIteration, exc);
+          Py_DECREF(exc);
+        }
+      } else {
+        PyErr_SetObject(PyExc_StopIteration, result);
+        // PyErr_SetObject increased the reference count, so we no longer need our reference.
+        Py_DECREF(result);
+      }
+#endif
     }
     return nullptr;
   }

+ 11 - 0
panda/src/putil/pythonCallbackObject.cxx

@@ -58,7 +58,18 @@ PythonCallbackObject(PyObject *function) {
  */
 PythonCallbackObject::
 ~PythonCallbackObject() {
+  // This may be called from the cull or draw thread, so we have to be sure we
+  // own the GIL.
+#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
+  PyGILState_STATE gstate;
+  gstate = PyGILState_Ensure();
+#endif
+
   Py_DECREF(_function);
+
+#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
+  PyGILState_Release(gstate);
+#endif
 }
 
 /**

+ 12 - 9
panda/src/tinydisplay/tinySDLGraphicsWindow.cxx

@@ -43,7 +43,10 @@ TinySDLGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
   _pitch = 0;
   update_pixel_factor();
 
-  add_input_device(GraphicsWindowInputDevice::pointer_and_keyboard(this, "keyboard_mouse"));
+  PT(GraphicsWindowInputDevice) device =
+    GraphicsWindowInputDevice::pointer_and_keyboard(this, "keyboard_mouse");
+  add_input_device(device);
+  _input = device.p();
 }
 
 /**
@@ -166,35 +169,35 @@ process_events() {
     switch(evt.type) {
     case SDL_KEYDOWN:
       if (evt.key.keysym.unicode) {
-        _input_devices[0]->keystroke(evt.key.keysym.unicode);
+        _input->keystroke(evt.key.keysym.unicode);
       }
       button = get_keyboard_button(evt.key.keysym.sym);
       if (button != ButtonHandle::none()) {
-        _input_devices[0]->button_down(button);
+        _input->button_down(button);
       }
       break;
 
     case SDL_KEYUP:
       button = get_keyboard_button(evt.key.keysym.sym);
       if (button != ButtonHandle::none()) {
-        _input_devices[0]->button_up(button);
+        _input->button_up(button);
       }
       break;
 
     case SDL_MOUSEBUTTONDOWN:
       button = get_mouse_button(evt.button.button);
-      _input_devices[0]->set_pointer_in_window(evt.button.x, evt.button.y);
-      _input_devices[0]->button_down(button);
+      _input->set_pointer_in_window(evt.button.x, evt.button.y);
+      _input->button_down(button);
       break;
 
     case SDL_MOUSEBUTTONUP:
       button = get_mouse_button(evt.button.button);
-      _input_devices[0]->set_pointer_in_window(evt.button.x, evt.button.y);
-      _input_devices[0]->button_up(button);
+      _input->set_pointer_in_window(evt.button.x, evt.button.y);
+      _input->button_up(button);
       break;
 
     case SDL_MOUSEMOTION:
-      _input_devices[0]->set_pointer_in_window(evt.motion.x, evt.motion.y);
+      _input->set_pointer_in_window(evt.motion.x, evt.motion.y);
       break;
 
     case SDL_VIDEORESIZE:

+ 2 - 0
panda/src/tinydisplay/tinySDLGraphicsWindow.h

@@ -63,6 +63,8 @@ private:
   unsigned int _flags;
   unsigned int _pitch;
 
+  GraphicsWindowInputDevice *_input;
+
 public:
   static TypeHandle get_class_type() {
     return _type_handle;

+ 25 - 5
tests/event/test_futures.py

@@ -31,6 +31,21 @@ class MockFuture:
 
         return self._result
 
+def check_result(fut, expected):
+    """Asserts the result of the future is the expected value."""
+
+    if fut.result() != expected:
+        return False
+
+    # Make sure that await also returns the values properly
+    with pytest.raises(StopIteration) as e:
+        next(fut.__await__())
+    if e.value.value != expected:
+        return False
+
+    return True
+
+
 def test_future_cancelled():
     fut = core.AsyncFuture()
 
@@ -462,15 +477,20 @@ def test_future_result():
     ep = core.EventParameter(0.5)
     fut = core.AsyncFuture()
     fut.set_result(ep)
-    assert fut.result() is ep
-    assert fut.result() is ep
+    assert check_result(fut, ep)
+    assert check_result(fut, ep)
 
     # Store TypedObject
     dg = core.Datagram(b"test")
     fut = core.AsyncFuture()
     fut.set_result(dg)
-    assert fut.result() == dg
-    assert fut.result() == dg
+    assert check_result(fut, dg)
+    assert check_result(fut, dg)
+
+    # Store tuple
+    fut = core.AsyncFuture()
+    fut.set_result((1, 2))
+    assert check_result(fut, (1, 2))
 
     # Store arbitrary Python object
     obj = object()
@@ -507,7 +527,7 @@ def test_future_gather():
     assert gather.done()
 
     assert not gather.cancelled()
-    assert tuple(gather.result()) == (1, 2)
+    assert check_result(gather, (1, 2))
 
 
 def test_future_gather_cancel_inner():