[libcamera-devel,v2,18/19] py: Generate bindings for properties
diff mbox series

Message ID 20220524114610.41848-19-tomi.valkeinen@ideasonboard.com
State Accepted
Headers show
Series
  • More misc Python patches
Related show

Commit Message

Tomi Valkeinen May 24, 2022, 11:46 a.m. UTC
Generate bindings for properties in a very similar way as done for
controls. We do need to distinguish between the two, and thus I added
--properties flag to gen-py-controls.py.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
 src/py/libcamera/gen-py-controls.py           | 27 +++++++++++------
 src/py/libcamera/meson.build                  | 12 ++++++++
 .../libcamera/py_properties_generated.cpp.in  | 30 +++++++++++++++++++
 3 files changed, 60 insertions(+), 9 deletions(-)
 create mode 100644 src/py/libcamera/py_properties_generated.cpp.in

Comments

Tomi Valkeinen May 27, 2022, 6:56 a.m. UTC | #1
On 24/05/2022 14:46, Tomi Valkeinen wrote:
> Generate bindings for properties in a very similar way as done for
> controls. We do need to distinguish between the two, and thus I added
> --properties flag to gen-py-controls.py.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
> ---
>   src/py/libcamera/gen-py-controls.py           | 27 +++++++++++------
>   src/py/libcamera/meson.build                  | 12 ++++++++
>   .../libcamera/py_properties_generated.cpp.in  | 30 +++++++++++++++++++
>   3 files changed, 60 insertions(+), 9 deletions(-)
>   create mode 100644 src/py/libcamera/py_properties_generated.cpp.in
> 
> diff --git a/src/py/libcamera/gen-py-controls.py b/src/py/libcamera/gen-py-controls.py
> index e3e1e178..a9264777 100755
> --- a/src/py/libcamera/gen-py-controls.py
> +++ b/src/py/libcamera/gen-py-controls.py
> @@ -21,17 +21,19 @@ def find_common_prefix(strings):
>       return prefix
>   
>   
> -def generate_py(controls):
> +def generate_py(controls, prop_mode):
>       out = ''
>   
> +    mode_name = "properties" if prop_mode else "controls"
> +
>       for ctrl in controls:
>           name, ctrl = ctrl.popitem()
>   
>           if ctrl.get('draft'):
> -            ns = 'libcamera::controls::draft::'
> +            ns = 'libcamera::{}::draft::'.format(mode_name)
>               container = "draft"
>           else:
> -            ns = 'libcamera::controls::'
> +            ns = 'libcamera::{}::'.format(mode_name)
>               container = "controls"
>   
>           cpp_enum = name + 'Enum'
> @@ -44,12 +46,17 @@ def generate_py(controls):
>   
>           out += '\tpy::enum_<{}{}>({}, \"{}\")\n'.format(ns, cpp_enum, container, cpp_enum)
>   
> -        if name == 'LensShadingMapMode':
> -            prefix = 'LensShadingMapMode'
> -        elif name == 'SceneFlicker':
> -            # If we strip the prefix, we would get '50Hz', which is illegal name
> -            prefix = ''
> +        if not prop_mode:
> +            # Adjustments for controls
> +            if name == 'LensShadingMapMode':
> +                prefix = 'LensShadingMapMode'
> +            elif name == 'SceneFlicker':
> +                # If we strip the prefix, we would get '50Hz', which is illegal name
> +                prefix = ''
> +            else:
> +                prefix = find_common_prefix([e['name'] for e in enum])
>           else:
> +            # Adjustments for properties
>               prefix = find_common_prefix([e['name'] for e in enum])
>   
>           for entry in enum:
> @@ -79,12 +86,14 @@ def main(argv):
>                           help='Input file name.')
>       parser.add_argument('template', type=str,
>                           help='Template file name.')
> +    parser.add_argument('--properties', action='store_true', default=False,
> +                        help='Generate bindings for properties instead of controls')
>       args = parser.parse_args(argv[1:])
>   
>       data = open(args.input, 'rb').read()
>       controls = yaml.safe_load(data)['controls']
>   
> -    data = generate_py(controls)
> +    data = generate_py(controls, prop_mode=args.properties)
>   
>       data = fill_template(args.template, data)
>   
> diff --git a/src/py/libcamera/meson.build b/src/py/libcamera/meson.build
> index e8010846..e0010353 100644
> --- a/src/py/libcamera/meson.build
> +++ b/src/py/libcamera/meson.build
> @@ -32,6 +32,18 @@ pycamera_sources += custom_target('py_gen_controls',
>                                     output : ['py_controls_generated.cpp'],
>                                     command : [gen_py_controls, '-o', '@OUTPUT@', '@INPUT@'])
>   
> +# Generate properties
> +
> +gen_py_property_enums_input_files = files([
> +    '../../libcamera/property_ids.yaml',
> +    'py_properties_generated.cpp.in',
> +])
> +
> +pycamera_sources += custom_target('py_gen_properties',
> +                                  input : gen_py_property_enums_input_files,
> +                                  output : ['py_properties_generated.cpp'],
> +                                  command : [gen_py_controls, '--properties', '-o', '@OUTPUT@', '@INPUT@'])
> +
>   # Generate formats
>   
>   gen_py_formats_input_files = files([
> diff --git a/src/py/libcamera/py_properties_generated.cpp.in b/src/py/libcamera/py_properties_generated.cpp.in
> new file mode 100644
> index 00000000..044b2b2a
> --- /dev/null
> +++ b/src/py/libcamera/py_properties_generated.cpp.in
> @@ -0,0 +1,30 @@
> +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> +/*
> + * Copyright (C) 2022, Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
> + *
> + * Python bindings - Auto-generated properties
> + *
> + * This file is auto-generated. Do not edit.
> + */
> +
> +#include <libcamera/property_ids.h>
> +
> +#include <pybind11/smart_holder.h>
> +
> +namespace py = pybind11;
> +
> +class PyProperties
> +{
> +};
> +
> +class PyDraftProperties
> +{
> +};
> +
> +void init_py_properties_generated(py::module& m)
> +{
> +	auto controls = py::class_<PyProperties>(m, "properties");
> +	auto draft = py::class_<PyDraftProperties>(controls, "draft");
> +
> +${controls}
> +}

Well. This was well tested. I never actually call 
init_py_properties_generated()...

  Tomi
Laurent Pinchart May 27, 2022, 11:03 a.m. UTC | #2
Hi Tomi,

Thank you for the patch.

On Tue, May 24, 2022 at 02:46:09PM +0300, Tomi Valkeinen wrote:
> Generate bindings for properties in a very similar way as done for
> controls. We do need to distinguish between the two, and thus I added
> --properties flag to gen-py-controls.py.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
> ---
>  src/py/libcamera/gen-py-controls.py           | 27 +++++++++++------
>  src/py/libcamera/meson.build                  | 12 ++++++++
>  .../libcamera/py_properties_generated.cpp.in  | 30 +++++++++++++++++++
>  3 files changed, 60 insertions(+), 9 deletions(-)
>  create mode 100644 src/py/libcamera/py_properties_generated.cpp.in
> 
> diff --git a/src/py/libcamera/gen-py-controls.py b/src/py/libcamera/gen-py-controls.py
> index e3e1e178..a9264777 100755
> --- a/src/py/libcamera/gen-py-controls.py
> +++ b/src/py/libcamera/gen-py-controls.py
> @@ -21,17 +21,19 @@ def find_common_prefix(strings):
>      return prefix
>  
>  
> -def generate_py(controls):
> +def generate_py(controls, prop_mode):
>      out = ''
>  
> +    mode_name = "properties" if prop_mode else "controls"

s/"/'/g where applicable.

> +
>      for ctrl in controls:
>          name, ctrl = ctrl.popitem()
>  
>          if ctrl.get('draft'):
> -            ns = 'libcamera::controls::draft::'
> +            ns = 'libcamera::{}::draft::'.format(mode_name)
>              container = "draft"
>          else:
> -            ns = 'libcamera::controls::'
> +            ns = 'libcamera::{}::'.format(mode_name)
>              container = "controls"
>  
>          cpp_enum = name + 'Enum'
> @@ -44,12 +46,17 @@ def generate_py(controls):
>  
>          out += '\tpy::enum_<{}{}>({}, \"{}\")\n'.format(ns, cpp_enum, container, cpp_enum)
>  
> -        if name == 'LensShadingMapMode':
> -            prefix = 'LensShadingMapMode'
> -        elif name == 'SceneFlicker':
> -            # If we strip the prefix, we would get '50Hz', which is illegal name
> -            prefix = ''
> +        if not prop_mode:
> +            # Adjustments for controls
> +            if name == 'LensShadingMapMode':
> +                prefix = 'LensShadingMapMode'
> +            elif name == 'SceneFlicker':
> +                # If we strip the prefix, we would get '50Hz', which is illegal name
> +                prefix = ''
> +            else:
> +                prefix = find_common_prefix([e['name'] for e in enum])
>          else:
> +            # Adjustments for properties
>              prefix = find_common_prefix([e['name'] for e in enum])
>  
>          for entry in enum:
> @@ -79,12 +86,14 @@ def main(argv):
>                          help='Input file name.')
>      parser.add_argument('template', type=str,
>                          help='Template file name.')
> +    parser.add_argument('--properties', action='store_true', default=False,
> +                        help='Generate bindings for properties instead of controls')

I'm tempted to instead add a --mode argument that wouldtake either
'controls' or 'properties' as a value, and pass the mode name to
generate_py(). I don't mind too much, so either way,

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

>      args = parser.parse_args(argv[1:])
>  
>      data = open(args.input, 'rb').read()
>      controls = yaml.safe_load(data)['controls']
>  
> -    data = generate_py(controls)
> +    data = generate_py(controls, prop_mode=args.properties)
>  
>      data = fill_template(args.template, data)
>  
> diff --git a/src/py/libcamera/meson.build b/src/py/libcamera/meson.build
> index e8010846..e0010353 100644
> --- a/src/py/libcamera/meson.build
> +++ b/src/py/libcamera/meson.build
> @@ -32,6 +32,18 @@ pycamera_sources += custom_target('py_gen_controls',
>                                    output : ['py_controls_generated.cpp'],
>                                    command : [gen_py_controls, '-o', '@OUTPUT@', '@INPUT@'])
>  
> +# Generate properties
> +
> +gen_py_property_enums_input_files = files([
> +    '../../libcamera/property_ids.yaml',
> +    'py_properties_generated.cpp.in',
> +])
> +
> +pycamera_sources += custom_target('py_gen_properties',
> +                                  input : gen_py_property_enums_input_files,
> +                                  output : ['py_properties_generated.cpp'],
> +                                  command : [gen_py_controls, '--properties', '-o', '@OUTPUT@', '@INPUT@'])
> +
>  # Generate formats
>  
>  gen_py_formats_input_files = files([
> diff --git a/src/py/libcamera/py_properties_generated.cpp.in b/src/py/libcamera/py_properties_generated.cpp.in
> new file mode 100644
> index 00000000..044b2b2a
> --- /dev/null
> +++ b/src/py/libcamera/py_properties_generated.cpp.in
> @@ -0,0 +1,30 @@
> +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> +/*
> + * Copyright (C) 2022, Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
> + *
> + * Python bindings - Auto-generated properties
> + *
> + * This file is auto-generated. Do not edit.
> + */
> +
> +#include <libcamera/property_ids.h>
> +
> +#include <pybind11/smart_holder.h>
> +
> +namespace py = pybind11;
> +
> +class PyProperties
> +{
> +};
> +
> +class PyDraftProperties
> +{
> +};
> +
> +void init_py_properties_generated(py::module& m)
> +{
> +	auto controls = py::class_<PyProperties>(m, "properties");
> +	auto draft = py::class_<PyDraftProperties>(controls, "draft");
> +
> +${controls}
> +}

Patch
diff mbox series

diff --git a/src/py/libcamera/gen-py-controls.py b/src/py/libcamera/gen-py-controls.py
index e3e1e178..a9264777 100755
--- a/src/py/libcamera/gen-py-controls.py
+++ b/src/py/libcamera/gen-py-controls.py
@@ -21,17 +21,19 @@  def find_common_prefix(strings):
     return prefix
 
 
-def generate_py(controls):
+def generate_py(controls, prop_mode):
     out = ''
 
+    mode_name = "properties" if prop_mode else "controls"
+
     for ctrl in controls:
         name, ctrl = ctrl.popitem()
 
         if ctrl.get('draft'):
-            ns = 'libcamera::controls::draft::'
+            ns = 'libcamera::{}::draft::'.format(mode_name)
             container = "draft"
         else:
-            ns = 'libcamera::controls::'
+            ns = 'libcamera::{}::'.format(mode_name)
             container = "controls"
 
         cpp_enum = name + 'Enum'
@@ -44,12 +46,17 @@  def generate_py(controls):
 
         out += '\tpy::enum_<{}{}>({}, \"{}\")\n'.format(ns, cpp_enum, container, cpp_enum)
 
-        if name == 'LensShadingMapMode':
-            prefix = 'LensShadingMapMode'
-        elif name == 'SceneFlicker':
-            # If we strip the prefix, we would get '50Hz', which is illegal name
-            prefix = ''
+        if not prop_mode:
+            # Adjustments for controls
+            if name == 'LensShadingMapMode':
+                prefix = 'LensShadingMapMode'
+            elif name == 'SceneFlicker':
+                # If we strip the prefix, we would get '50Hz', which is illegal name
+                prefix = ''
+            else:
+                prefix = find_common_prefix([e['name'] for e in enum])
         else:
+            # Adjustments for properties
             prefix = find_common_prefix([e['name'] for e in enum])
 
         for entry in enum:
@@ -79,12 +86,14 @@  def main(argv):
                         help='Input file name.')
     parser.add_argument('template', type=str,
                         help='Template file name.')
+    parser.add_argument('--properties', action='store_true', default=False,
+                        help='Generate bindings for properties instead of controls')
     args = parser.parse_args(argv[1:])
 
     data = open(args.input, 'rb').read()
     controls = yaml.safe_load(data)['controls']
 
-    data = generate_py(controls)
+    data = generate_py(controls, prop_mode=args.properties)
 
     data = fill_template(args.template, data)
 
diff --git a/src/py/libcamera/meson.build b/src/py/libcamera/meson.build
index e8010846..e0010353 100644
--- a/src/py/libcamera/meson.build
+++ b/src/py/libcamera/meson.build
@@ -32,6 +32,18 @@  pycamera_sources += custom_target('py_gen_controls',
                                   output : ['py_controls_generated.cpp'],
                                   command : [gen_py_controls, '-o', '@OUTPUT@', '@INPUT@'])
 
+# Generate properties
+
+gen_py_property_enums_input_files = files([
+    '../../libcamera/property_ids.yaml',
+    'py_properties_generated.cpp.in',
+])
+
+pycamera_sources += custom_target('py_gen_properties',
+                                  input : gen_py_property_enums_input_files,
+                                  output : ['py_properties_generated.cpp'],
+                                  command : [gen_py_controls, '--properties', '-o', '@OUTPUT@', '@INPUT@'])
+
 # Generate formats
 
 gen_py_formats_input_files = files([
diff --git a/src/py/libcamera/py_properties_generated.cpp.in b/src/py/libcamera/py_properties_generated.cpp.in
new file mode 100644
index 00000000..044b2b2a
--- /dev/null
+++ b/src/py/libcamera/py_properties_generated.cpp.in
@@ -0,0 +1,30 @@ 
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2022, Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+ *
+ * Python bindings - Auto-generated properties
+ *
+ * This file is auto-generated. Do not edit.
+ */
+
+#include <libcamera/property_ids.h>
+
+#include <pybind11/smart_holder.h>
+
+namespace py = pybind11;
+
+class PyProperties
+{
+};
+
+class PyDraftProperties
+{
+};
+
+void init_py_properties_generated(py::module& m)
+{
+	auto controls = py::class_<PyProperties>(m, "properties");
+	auto draft = py::class_<PyDraftProperties>(controls, "draft");
+
+${controls}
+}