]> sigrok.org Git - libsigrokdecode.git/blobdiff - decoders/ir_irmp/irmp_library.py
ir_irmp: Python binding, support instance locking and context manager
[libsigrokdecode.git] / decoders / ir_irmp / irmp_library.py
index d542a1d8b780351fc2bb7f0a619a56a10ab17160..a1bc2583df82fb6b8b4a4437350732b91b1d0604 100644 (file)
@@ -2,6 +2,7 @@
 ## This file is part of the libsigrokdecode project.
 ##
 ## Copyright (C) 2019 Rene Staffen
+## Copyright (C) 2020-2021 Gerhard Sittig <gerhard.sittig@gmx.net>
 ##
 ## This program is free software; you can redistribute it and/or modify
 ## it under the terms of the GNU General Public License as published by
@@ -29,6 +30,8 @@ class IrmpLibrary:
     Library instance for an infrared protocol detector.
     '''
 
+    __usable_instance = None
+
     class ResultData(ctypes.Structure):
         _fields_ = [
             ( 'protocol', ctypes.c_uint32, ),
@@ -54,18 +57,29 @@ class IrmpLibrary:
             return 'libirmp.dylib'
         return 'irmp.dll'
 
-    def __init__(self):
+    def _library_setup_api(self):
         '''
-        Create a library instance.
+        Lookup the C library's API routines. Declare their prototypes.
         '''
 
-        # Load the library. Lookup routines, declare their prototypes.
-        filename = self._library_filename()
-        self._lib = ctypes.cdll.LoadLibrary(filename)
-
         self._lib.irmp_get_sample_rate.restype = ctypes.c_uint32
         self._lib.irmp_get_sample_rate.argtypes = []
 
+        self._lib.irmp_instance_alloc.restype = ctypes.c_void_p
+        self._lib.irmp_instance_alloc.argtypes = []
+
+        self._lib.irmp_instance_free.restype = None
+        self._lib.irmp_instance_free.argtypes = [ ctypes.c_void_p, ]
+
+        self._lib.irmp_instance_id.restype = ctypes.c_size_t
+        self._lib.irmp_instance_id.argtypes = [ ctypes.c_void_p, ]
+
+        self._lib.irmp_instance_lock.restype = ctypes.c_int
+        self._lib.irmp_instance_lock.argtypes = [ ctypes.c_void_p, ctypes.c_int, ]
+
+        self._lib.irmp_instance_unlock.restype = None
+        self._lib.irmp_instance_unlock.argtypes = [ ctypes.c_void_p, ]
+
         self._lib.irmp_reset_state.restype = None
         self._lib.irmp_reset_state.argtypes = []
 
@@ -84,6 +98,48 @@ class IrmpLibrary:
 
         # Create a result buffer that's local to the library instance.
         self._data = self.ResultData()
+        self._inst = None
+
+        return True
+
+    def __init__(self):
+        '''
+        Create a library instance.
+        '''
+
+        filename = self._library_filename()
+        self._lib = ctypes.cdll.LoadLibrary(filename)
+        self._library_setup_api()
+
+    def __del__(self):
+        '''
+        Release a disposed library instance.
+        '''
+
+        if self._inst:
+            self._lib.irmp_instance_free(self._inst)
+        self._inst = None
+
+    def __enter__(self):
+        '''
+        Enter a context (lock management).
+        '''
+
+        if self._inst is None:
+            self._inst = self._lib.irmp_instance_alloc()
+        self._lib.irmp_instance_lock(self._inst, 1)
+        return self
+
+    def __exit__(self, extype, exvalue, trace):
+        '''
+        Leave a context (lock management).
+        '''
+
+        self._lib.irmp_instance_unlock(self._inst)
+        return False
+
+    def client_id(self):
+        return self._lib.irmp_instance_id(self._inst)
 
     def get_sample_rate(self):
         return self._lib.irmp_get_sample_rate()
@@ -98,7 +154,9 @@ class IrmpLibrary:
         return True
 
     def get_result_data(self):
-        data = {
+        if not self._data:
+            return None
+        return {
             'proto_nr': self._data.protocol,
             'proto_name': self._data.protocol_name.decode('UTF-8', 'ignore'),
             'address': self._data.address,
@@ -108,4 +166,3 @@ class IrmpLibrary:
             'start': self._data.start_sample,
             'end': self._data.end_sample,
         }
-        return data