summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjaseg <git@jaseg.net>2017-05-10 18:25:31 +0200
committerjaseg <git@jaseg.net>2017-05-10 18:29:41 +0200
commitc47bd2a2c603c57c2c86474450056f21492cce48 (patch)
tree7a492e4be1ddd0cedfbe102016fc548f2b9b0711
parent303eedbb3b2fe8ddd0229c49d5d961f06fd39208 (diff)
downloadpython-mpv-c47bd2a2c603c57c2c86474450056f21492cce48.tar.gz
python-mpv-c47bd2a2c603c57c2c86474450056f21492cce48.tar.bz2
python-mpv-c47bd2a2c603c57c2c86474450056f21492cce48.zip
BREAKING: Move property observation API to NODE format
-rwxr-xr-xmpv-test.py2
-rw-r--r--mpv.py67
2 files changed, 25 insertions, 44 deletions
diff --git a/mpv-test.py b/mpv-test.py
index fb1c370..b2bea2e 100755
--- a/mpv-test.py
+++ b/mpv-test.py
@@ -151,7 +151,7 @@ class ObservePropertyTest(unittest.TestCase):
m.loop = 'no'
m.loop = 'inf'
m.terminate() # needed for synchronization of event thread
- handler.assert_has_calls([mock.call('no'), mock.call('inf')])
+ handler.assert_has_calls([mock.call('loop', False), mock.call('loop', 'inf')])
class TestLifecycle(unittest.TestCase):
diff --git a/mpv.py b/mpv.py
index fcf8efd..7145ff3 100644
--- a/mpv.py
+++ b/mpv.py
@@ -228,17 +228,13 @@ class MpvEventProperty(Structure):
_fields_ = [('name', c_char_p),
('format', MpvFormat),
('data', c_void_p)]
- def as_dict(self):
- if self.format.value == MpvFormat.STRING:
- proptype, _access = ALL_PROPERTIES.get(self.name, (str, None))
- return {'name': self.name.decode('utf-8'),
- 'format': self.format,
- 'data': self.data,
- 'value': proptype(cast(self.data, POINTER(c_char_p)).contents.value.decode('utf-8'))}
- else:
- return {'name': self.name.decode('utf-8'),
- 'format': self.format,
- 'data': self.data}
+ def as_dict(self, decode_str=False):
+ proptype, _access = ALL_PROPERTIES.get(self.name, (str, None))
+ value = MpvNode.node_cast_value(self.data, self.format.value, decode_str or proptype in (str, _commalist))
+ return {'name': self.name.decode('utf-8'),
+ 'format': self.format,
+ 'data': self.data,
+ 'value': value}
class MpvEventLogMessage(Structure):
_fields_ = [('prefix', c_char_p),
@@ -394,21 +390,10 @@ def _event_loop(event_handle, playback_cond, event_callbacks, message_handlers,
playback_cond.notify_all()
if eid == MpvEventID.PROPERTY_CHANGE:
pc = devent['event']
- name = pc['name']
-
- if 'value' in pc:
- proptype, _access = ALL_PROPERTIES[name]
- if proptype is bytes:
- args = (pc['value'],)
- else:
- args = (proptype(_ensure_encoding(pc['value'])),)
- elif pc['format'] == MpvFormat.NONE:
- args = (None,)
- else:
- args = (pc['data'], pc['format'])
+ name, value = pc['name'], pc['value']
for handler in property_handlers[name]:
- handler(*args)
+ handler(name, value)
if eid == MpvEventID.LOG_MESSAGE and log_handler is not None:
ev = devent['event']
log_handler(ev['level'], ev['prefix'], ev['text'])
@@ -479,7 +464,7 @@ class MPV(object):
```idle_active``` indicating the player is done with regular playback
and just idling around """
sema = threading.Semaphore(value=0)
- def observer(val):
+ def observer(name, val):
if cond(val):
sema.release()
self.observe_property(name, observer)
@@ -655,37 +640,33 @@ class MPV(object):
""" Mapped mpv seek command, see man mpv(1). """
self.command('script_message_to', target, *args)
- def observe_property(self, name, handler=None):
- """ Register an observer on the named property. An observer is a
- function that is called with the new property value every time the
- property's value is changed. The basic function signature is
- ```fun(new_value)``` with new_value being the decoded property value as
- a python object. This function can be used as a function decorator if
- no handler is given.
+ def observe_property(self, name, handler):
+ """ Register an observer on the named property. An observer is a function that is called with the new property
+ value every time the property's value is changed. The basic function signature is ```fun(property_name,
+ new_value)``` with new_value being the decoded property value as a python object. This function can be used as a
+ function decorator if no handler is given.
To uunregister the observer, call either of ```mpv.unobserve_property(name, handler)```,
```mpv.unobserve_all_properties(handler)``` or the handler's ```unregister_mpv_properties``` attribute:
```
@player.observe_property('volume')
- def my_handler(new_volume):
+ def my_handler(new_volume, *):
print("It's loud!", volume)
my_handler.unregister_mpv_properties()
``` """
- if handler is None:
- def wrapper(fun):
- self._observe_property_internal(name, handler)
- return fun
- return wrapper
- else:
- self._observe_property_internal(name, handler)
-
- def _observe_property_internal(self, name, handler):
handler.observed_mpv_properties = getattr(handler, 'observed_mpv_properties', []) + [name]
handler.unregister_mpv_properties = lambda: self.unobserve_property(None, handler)
self._property_handlers[name].append(handler)
- _mpv_observe_property(self._event_handle, hash(name)&0xffffffffffffffff, name.encode('utf-8'), MpvFormat.STRING)
+ _mpv_observe_property(self._event_handle, hash(name)&0xffffffffffffffff, name.encode('utf-8'), MpvFormat.NODE)
+
+ def property_observer(self, name):
+ """ Function decorator to register a property observer. See ```MPV.observe_property``` for details. """
+ def wrapper(fun):
+ self.observe_property(name, fun)
+ return fun
+ return wrapper
def unobserve_property(self, name, handler):
""" Unregister a property observer. This requires both the observed property's name and the handler function