summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMathieu Duponchelle <mathieu@centricular.com>2019-09-02 18:11:56 +0200
committerMathieu Duponchelle <mathieu@centricular.com>2019-09-02 18:42:39 +0200
commitc04bb945b0b95e0f8686f3b9994a3327ccf74863 (patch)
tree9b595c7fd536eded1fdbc9c8a90fa9bad261d4b6
parent34e0e3ce1113a3b6e50ec6e9cd76d4b205c7c100 (diff)
overrides: fix callback setter overrides (bis)
The previous commit broke those by trying to pass weak refs through pygobject, but we should probably have tested the elements beyond instantiation: weakref.WeakMethod returns a callable, but that callable when called only returns the ephemeral bound method, which is the object we want to call, but pygobject has no support for that. Instead, fix the memory leaks we were going after by decoupling the lifecycle of the callback and that of the pad, by passing functors to pygobject.
-rw-r--r--gi/overrides/Gst.py41
1 files changed, 19 insertions, 22 deletions
diff --git a/gi/overrides/Gst.py b/gi/overrides/Gst.py
index 414a0ad..0f5f2be 100644
--- a/gi/overrides/Gst.py
+++ b/gi/overrides/Gst.py
@@ -140,42 +140,39 @@ class Caps(Gst.Caps):
Caps = override(Caps)
__all__.append('Caps')
-class Pad(Gst.Pad):
- def __init__(self, *args, **kwargs):
- self._real_chain_func = None
- self._real_event_func = None
- self._real_query_func = None
- super(Gst.Pad, self).__init__(*args, **kwargs)
+class PadFunc:
+ def __init__(self, func):
+ self.func = func
- def _chain_override(self, pad, parent, buf):
- return self._real_chain_func(pad, buf)
-
- def _event_override(self, pad, parent, event):
- return self._real_event_func(pad, event)
+ def __call__(self, pad, parent, obj):
+ if isinstance(self.func, weakref.WeakMethod):
+ func = self.func()
+ else:
+ func = self.func
- def _query_override(self, pad, parent, query):
try:
- res = self._real_query_func(pad, query)
+ res = func(pad, obj)
except TypeError:
try:
- res = self._real_query_func(pad, parent, query)
+ res = func(pad, parent, obj)
except TypeError:
- raise TypeError("Invalid query method %s, 2 or 3 arguments required"
- % self._real_query_func)
+ raise TypeError("Invalid method %s, 2 or 3 arguments required"
+ % func)
return res
+class Pad(Gst.Pad):
+ def __init__(self, *args, **kwargs):
+ super(Gst.Pad, self).__init__(*args, **kwargs)
+
def set_chain_function(self, func):
- self._real_chain_func = func
- self.set_chain_function_full(weakref.WeakMethod(self._chain_override), None)
+ self.set_chain_function_full(PadFunc(func), None)
def set_event_function(self, func):
- self._real_event_func = func
- self.set_event_function_full(weakref.WeakMethod(func), None)
+ self.set_event_function_full(PadFunc(func), None)
def set_query_function(self, func):
- self._real_query_func = func
- self.set_query_function_full(weakref.WeakMethod(self._query_override), None)
+ self.set_query_function_full(PadFunc(func), None)
def query_caps(self, filter=None):
return Gst.Pad.query_caps(self, filter)