From fe893f6039fbd962a57c6cdfa0991dd92dfcb88d Mon Sep 17 00:00:00 2001 From: Buganini Q Date: Sat, 21 Oct 2023 13:25:40 +0800 Subject: [PATCH 1/8] add parameter dialog --- cpp/modmesh/view/CMakeLists.txt | 2 + cpp/modmesh/view/RManager.cpp | 14 ++++++ cpp/modmesh/view/RParameter.cpp | 79 +++++++++++++++++++++++++++++++++ cpp/modmesh/view/RParameter.hpp | 39 ++++++++++++++++ modmesh/params.py | 63 ++++++++++++++++++++++++++ 5 files changed, 197 insertions(+) create mode 100644 cpp/modmesh/view/RParameter.cpp create mode 100644 cpp/modmesh/view/RParameter.hpp create mode 100644 modmesh/params.py diff --git a/cpp/modmesh/view/CMakeLists.txt b/cpp/modmesh/view/CMakeLists.txt index 83885919..3a026d2c 100644 --- a/cpp/modmesh/view/CMakeLists.txt +++ b/cpp/modmesh/view/CMakeLists.txt @@ -7,6 +7,7 @@ set(MODMESH_VIEW_PYMODHEADERS ${CMAKE_CURRENT_SOURCE_DIR}/R3DWidget.hpp ${CMAKE_CURRENT_SOURCE_DIR}/RWorld.hpp ${CMAKE_CURRENT_SOURCE_DIR}/RManager.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/RParameter.hpp ${CMAKE_CURRENT_SOURCE_DIR}/RAxisMark.hpp ${CMAKE_CURRENT_SOURCE_DIR}/RPythonConsoleDockWidget.hpp ${CMAKE_CURRENT_SOURCE_DIR}/RStaticMesh.hpp @@ -20,6 +21,7 @@ set(MODMESH_VIEW_PYMODSOURCES ${CMAKE_CURRENT_SOURCE_DIR}/R3DWidget.cpp ${CMAKE_CURRENT_SOURCE_DIR}/RWorld.cpp ${CMAKE_CURRENT_SOURCE_DIR}/RManager.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/RParameter.cpp ${CMAKE_CURRENT_SOURCE_DIR}/RAxisMark.cpp ${CMAKE_CURRENT_SOURCE_DIR}/RPythonConsoleDockWidget.cpp ${CMAKE_CURRENT_SOURCE_DIR}/RStaticMesh.cpp diff --git a/cpp/modmesh/view/RManager.cpp b/cpp/modmesh/view/RManager.cpp index 27b82643..ff818873 100644 --- a/cpp/modmesh/view/RManager.cpp +++ b/cpp/modmesh/view/RManager.cpp @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -211,6 +212,19 @@ void RManager::setUpMenu() this->addApplication(QString("linear_wave")); this->addApplication(QString("bad_euler1d")); } + + { + QAction * params = new RAction( + QString("Parameters"), + QString("Runtime parameters"), + []() + { + openParameterView(); + } + ); + m_mainWindow->menuBar()->addAction(params); + + } } void RManager::clearApplications() diff --git a/cpp/modmesh/view/RParameter.cpp b/cpp/modmesh/view/RParameter.cpp new file mode 100644 index 00000000..bdf330b4 --- /dev/null +++ b/cpp/modmesh/view/RParameter.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2023, Buganini Chiu + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include // Must be the first include. + +namespace modmesh +{ + +static int v1 = 5566; +static int v2 = 7788; +static struct param { + const char * key; + int * value; +} params[] = { + {"a.b.foo", &v1}, + {"a.b.bar", &v2}, +}; + +int getter_func(int *ptr) { + return *ptr; +} + +void setter_func(int *ptr, int value) { + std::cout << "C++ set " << value << std::endl; + *ptr = value; +} + +void openParameterView() { + pybind11::module pui_module = pybind11::module::import("PUI"); + auto state = pui_module.attr("StateDict")(); + auto paramsList = pybind11::list(); + + for(int i=0;i + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include // Must be the first include. + +namespace modmesh +{ +void openParameterView(); + +} /* end namespace modmesh */ + +// vim: set ff=unix fenc=utf8 et sw=4 ts=4 sts=4: diff --git a/modmesh/params.py b/modmesh/params.py new file mode 100644 index 00000000..68023f66 --- /dev/null +++ b/modmesh/params.py @@ -0,0 +1,63 @@ +from PUI.PySide6 import * + +class ParametersView(PuiInQt): + class TableAdapter: + def __init__(self, state, data): + self.state = state + self._data = data + + def data(self, row, col): + param = self._data[row] + return [param.key, param.value][col] + + def setData(self, row, col, value): + if col==1: + self._data[row].value = value + + def editable(self, row, col): + return col > 0 + + def columnHeader(self, col): + return ["Key","Value"][col] + + def rowCount(self): + return len(self._data) + + def columnCount(self): + return 2 + + def __init__(self, container, state): + super().__init__(container) + self.state = state + + def content(self): + data = State() + if not self.state.filter: + data.params = self.state.params + else: + data.params = [it for it in self.state.params if self.state.filter in it.key] + with VBox(): + TextField(self.state("filter")) + Table(self.TableAdapter(self.state, data.params)) + +def openParametersView(params): + state = State() + state.buffer = [f"line {i}" for i in range(50)] + state.cmd_edit = "" + state.config_modal = False + state.filter = "" + state.params = params + pv = ParametersView(Window(size=(640, 480)), state) + pv.redraw() + +if __name__=="__main__": + class Example(): + def __init__(self): + self.app = QtWidgets.QApplication([]) + + def run(self): + openParametersView() + self.app.exec() + + root = Example() + root.run() From 13c9a1d413863da45922eea6df0bfe2c8da4c0e9 Mon Sep 17 00:00:00 2001 From: Buganini Q Date: Sat, 21 Oct 2023 13:47:30 +0800 Subject: [PATCH 2/8] RParameter: support int64/double types --- cpp/modmesh/view/RParameter.cpp | 86 ++++++++++++++++++++++++--------- modmesh/params.py | 8 +-- 2 files changed, 66 insertions(+), 28 deletions(-) diff --git a/cpp/modmesh/view/RParameter.cpp b/cpp/modmesh/view/RParameter.cpp index bdf330b4..3d62acc5 100644 --- a/cpp/modmesh/view/RParameter.cpp +++ b/cpp/modmesh/view/RParameter.cpp @@ -31,47 +31,85 @@ namespace modmesh { -static int v1 = 5566; -static int v2 = 7788; -static struct param { - const char * key; - int * value; -} params[] = { - {"a.b.foo", &v1}, - {"a.b.bar", &v2}, -}; +static int int64V = 5566; +static double doubleV = 77.88; -int getter_func(int *ptr) { +int getter_func_i64(int64_t *ptr) { return *ptr; } -void setter_func(int *ptr, int value) { - std::cout << "C++ set " << value << std::endl; +void setter_func_i64(int64_t *ptr, int value) { *ptr = value; } +double getter_func_double(double *ptr) { + return *ptr; +} + +void setter_func_double(double *ptr, double value) { + *ptr = value; +} + +enum DataType { + TYPE_INT64, + TYPE_DOUBLE, +}; + +static struct param { + const char * key; + void * value; + int dtype; +} params[] = { + {"a.b.int64_foo", &int64V, TYPE_INT64}, + {"a.b.double_bar", &doubleV, TYPE_DOUBLE}, +}; + void openParameterView() { pybind11::module pui_module = pybind11::module::import("PUI"); auto state = pui_module.attr("StateDict")(); auto paramsList = pybind11::list(); for(int i=0;i Date: Sat, 21 Oct 2023 15:49:00 +0800 Subject: [PATCH 3/8] RParameter: allow building parameters list at runtime --- cpp/modmesh/view/RManager.cpp | 7 ++- cpp/modmesh/view/RParameter.cpp | 84 +++------------------------------ cpp/modmesh/view/RParameter.hpp | 20 +++++++- 3 files changed, 32 insertions(+), 79 deletions(-) diff --git a/cpp/modmesh/view/RManager.cpp b/cpp/modmesh/view/RManager.cpp index ff818873..bab3884c 100644 --- a/cpp/modmesh/view/RManager.cpp +++ b/cpp/modmesh/view/RManager.cpp @@ -219,7 +219,12 @@ void RManager::setUpMenu() QString("Runtime parameters"), []() { - openParameterView(); + static int64_t int64V = 5566; + static double doubleV = 77.88; + auto params = createParameters(); + addParam(params, "global.a.b.int64_foo", &int64V); + addParam(params, "global.a.b.double_bar", &doubleV); + openParameterView(params); } ); m_mainWindow->menuBar()->addAction(params); diff --git a/cpp/modmesh/view/RParameter.cpp b/cpp/modmesh/view/RParameter.cpp index 3d62acc5..6f6d9d89 100644 --- a/cpp/modmesh/view/RParameter.cpp +++ b/cpp/modmesh/view/RParameter.cpp @@ -30,86 +30,16 @@ namespace modmesh { - -static int int64V = 5566; -static double doubleV = 77.88; - -int getter_func_i64(int64_t *ptr) { - return *ptr; -} - -void setter_func_i64(int64_t *ptr, int value) { - *ptr = value; -} - -double getter_func_double(double *ptr) { - return *ptr; -} - -void setter_func_double(double *ptr, double value) { - *ptr = value; -} - -enum DataType { - TYPE_INT64, - TYPE_DOUBLE, -}; - -static struct param { - const char * key; - void * value; - int dtype; -} params[] = { - {"a.b.int64_foo", &int64V, TYPE_INT64}, - {"a.b.double_bar", &doubleV, TYPE_DOUBLE}, -}; - -void openParameterView() { +pybind11::tuple createParameters(void) { pybind11::module pui_module = pybind11::module::import("PUI"); - auto state = pui_module.attr("StateDict")(); - auto paramsList = pybind11::list(); - - for(int i=0;i +void addParam(pybind11::tuple & params, const char *key, T *ptr) { + params[0][pybind11::str(key)] = *ptr; + auto binding = params[0](key); + binding.attr("bind")( + pybind11::cpp_function([ptr](){ + return *ptr; + }), + pybind11::cpp_function([key, ptr](T value){ + std::cout << "Set " << key << " = " << value << std::endl; + *ptr = value; + }) + ); + static_cast(params[1]).append(binding); +} } /* end namespace modmesh */ From f61a8286d10577a80f3b69c325096bdb1d314c56 Mon Sep 17 00:00:00 2001 From: Buganini Q Date: Sat, 21 Oct 2023 16:01:53 +0800 Subject: [PATCH 4/8] modmesh/params.py: add license --- modmesh/params.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/modmesh/params.py b/modmesh/params.py index 31d0ad5a..b0add3b0 100644 --- a/modmesh/params.py +++ b/modmesh/params.py @@ -1,3 +1,34 @@ +#!/usr/bin/env python +# -*- coding: UTF-8 -*- +# +# Copyright (c) 2023, Buganini Chiu +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# - Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# - Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# - Neither the name of the pstake nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + from PUI.PySide6 import * class ParameterView(PuiInQt): From 73c311f3ec065d202aefb63e5f9f86ac78e97660 Mon Sep 17 00:00:00 2001 From: Buganini Q Date: Sat, 21 Oct 2023 16:06:41 +0800 Subject: [PATCH 5/8] RParameter: clang-format fix --- cpp/modmesh/view/RManager.cpp | 4 +--- cpp/modmesh/view/RParameter.cpp | 9 +++++---- cpp/modmesh/view/RParameter.hpp | 15 +++++++-------- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/cpp/modmesh/view/RManager.cpp b/cpp/modmesh/view/RManager.cpp index bab3884c..2783ab8e 100644 --- a/cpp/modmesh/view/RManager.cpp +++ b/cpp/modmesh/view/RManager.cpp @@ -225,10 +225,8 @@ void RManager::setUpMenu() addParam(params, "global.a.b.int64_foo", &int64V); addParam(params, "global.a.b.double_bar", &doubleV); openParameterView(params); - } - ); + }); m_mainWindow->menuBar()->addAction(params); - } } diff --git a/cpp/modmesh/view/RParameter.cpp b/cpp/modmesh/view/RParameter.cpp index 6f6d9d89..d50a2463 100644 --- a/cpp/modmesh/view/RParameter.cpp +++ b/cpp/modmesh/view/RParameter.cpp @@ -30,14 +30,15 @@ namespace modmesh { -pybind11::tuple createParameters(void) { +pybind11::tuple createParameters(void) +{ pybind11::module pui_module = pybind11::module::import("PUI"); return pybind11::make_tuple( - pui_module.attr("StateDict")(), pybind11::list() - ); + pui_module.attr("StateDict")(), pybind11::list()); } -void openParameterView(pybind11::tuple & params) { +void openParameterView(pybind11::tuple & params) +{ pybind11::module params_module = pybind11::module::import("modmesh.params"); params_module.attr("openParameterView")(params[1]); } diff --git a/cpp/modmesh/view/RParameter.hpp b/cpp/modmesh/view/RParameter.hpp index cce14bfe..2811d0ae 100644 --- a/cpp/modmesh/view/RParameter.hpp +++ b/cpp/modmesh/view/RParameter.hpp @@ -37,18 +37,17 @@ pybind11::tuple createParameters(void); void openParameterView(pybind11::tuple & params); template -void addParam(pybind11::tuple & params, const char *key, T *ptr) { +void addParam(pybind11::tuple & params, const char * key, T * ptr) +{ params[0][pybind11::str(key)] = *ptr; auto binding = params[0](key); binding.attr("bind")( - pybind11::cpp_function([ptr](){ - return *ptr; - }), - pybind11::cpp_function([key, ptr](T value){ + pybind11::cpp_function([ptr]() + { return *ptr; }), + pybind11::cpp_function([key, ptr](T value) + { std::cout << "Set " << key << " = " << value << std::endl; - *ptr = value; - }) - ); + *ptr = value; })); static_cast(params[1]).append(binding); } From 90d4348b61d0589e1fa5eaaf8be8e264bfa90f3c Mon Sep 17 00:00:00 2001 From: Buganini Q Date: Sun, 22 Oct 2023 16:37:46 +0800 Subject: [PATCH 6/8] modmesh/params.py: fix flake8 issue --- modmesh/params.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/modmesh/params.py b/modmesh/params.py index b0add3b0..558678ec 100644 --- a/modmesh/params.py +++ b/modmesh/params.py @@ -29,7 +29,9 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -from PUI.PySide6 import * +from PUI.PySide6 import State, PuiInQt, Window, VBox, Table, TextField +from PySide6 import QtWidgets + class ParameterView(PuiInQt): class TableAdapter: @@ -42,14 +44,14 @@ def data(self, row, col): return [param.key, param.value][col] def setData(self, row, col, value): - if col==1: + if col == 1: self._data[row].value = value def editable(self, row, col): return col > 0 def columnHeader(self, col): - return ["Key","Value"][col] + return ["Key", "Value"][col] def rowCount(self): return len(self._data) @@ -66,13 +68,18 @@ def content(self): if not self.state.filter: data.params = self.state.params else: - data.params = [it for it in self.state.params if self.state.filter in it.key] + data.params = [ + it + for it in self.state.params + if self.state.filter in it.key + ] with VBox(): TextField(self.state("filter")) Table(self.TableAdapter(self.state, data.params)) + def openParameterView(params): - state = State() + state = State() state.buffer = [f"line {i}" for i in range(50)] state.cmd_edit = "" state.config_modal = False @@ -81,7 +88,8 @@ def openParameterView(params): pv = ParameterView(Window(size=(640, 480)), state) pv.redraw() -if __name__=="__main__": + +if __name__ == "__main__": class Example(): def __init__(self): self.app = QtWidgets.QApplication([]) From a4df8fd1522e1adad3e150aed67fa537bb78c0bd Mon Sep 17 00:00:00 2001 From: Buganini Q Date: Sun, 22 Oct 2023 16:39:47 +0800 Subject: [PATCH 7/8] check PUI version --- modmesh/params.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modmesh/params.py b/modmesh/params.py index 558678ec..c238377f 100644 --- a/modmesh/params.py +++ b/modmesh/params.py @@ -29,9 +29,13 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +import PUI from PUI.PySide6 import State, PuiInQt, Window, VBox, Table, TextField from PySide6 import QtWidgets +if tuple([int(x) for x in PUI.__version__.split(".")]) != (0, 3): + raise ValueError("PUI too old") + class ParameterView(PuiInQt): class TableAdapter: From ad3f4ed1a4fa21c2957b7928df5950ac7f18e06d Mon Sep 17 00:00:00 2001 From: Buganini Q Date: Mon, 23 Oct 2023 15:12:38 +0800 Subject: [PATCH 8/8] modmesh/params.py: fix test example --- modmesh/params.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/modmesh/params.py b/modmesh/params.py index c238377f..d59c43e9 100644 --- a/modmesh/params.py +++ b/modmesh/params.py @@ -84,9 +84,6 @@ def content(self): def openParameterView(params): state = State() - state.buffer = [f"line {i}" for i in range(50)] - state.cmd_edit = "" - state.config_modal = False state.filter = "" state.params = params pv = ParameterView(Window(size=(640, 480)), state) @@ -99,7 +96,15 @@ def __init__(self): self.app = QtWidgets.QApplication([]) def run(self): - openParameterView() + from PUI.PySide6 import StateDict + paramsState = StateDict() + paramsState["a.b.foo_int64"] = 5566 + paramsState["a.b.bar_double"] = 77.88 + paramsList = [ + paramsState("a.b.foo_int64"), + paramsState("a.b.bar_double"), + ] + openParameterView(paramsList) self.app.exec() root = Example()