runtimepy 5.15.3__tar.gz → 5.15.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {runtimepy-5.15.3/runtimepy.egg-info → runtimepy-5.15.5}/PKG-INFO +7 -7
- {runtimepy-5.15.3 → runtimepy-5.15.5}/README.md +2 -2
- {runtimepy-5.15.3 → runtimepy-5.15.5}/pyproject.toml +1 -1
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/__init__.py +2 -2
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/channel/environment/base.py +5 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/channel/environment/command/processor.py +11 -1
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/channel/environment/file.py +4 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/css/bootstrap_extra.css +4 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/css/main.css +8 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/dummy_load.yaml +47 -17
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/js/classes/ChannelTable.js +4 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/js/classes/TabInterface.js +13 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/js/classes/WorkerInterface.js +1 -1
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/js/init.js +4 -2
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/js/sample.js +1 -1
- runtimepy-5.15.5/runtimepy/data/schemas/Button.yaml +17 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/schemas/ClientConnectionConfig.yaml +2 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/schemas/ConnectionArbiterConfig.yaml +1 -8
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/schemas/PeerProcessConfig.yaml +1 -0
- runtimepy-5.15.5/runtimepy/data/schemas/TwoTupleArray.yaml +9 -0
- runtimepy-5.15.5/runtimepy/data/schemas/has_buttons.yaml +6 -0
- runtimepy-5.15.5/runtimepy/data/schemas/has_views.yaml +4 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/arbiter/base.py +20 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/arbiter/config/__init__.py +3 -1
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/arbiter/factory/connection.py +9 -1
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/server/app/env/tab/base.py +11 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/server/app/env/tab/html.py +10 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/server/app/env/widgets.py +25 -9
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/server/websocket/__init__.py +1 -1
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/requirements.txt +1 -1
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/struct/__init__.py +3 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/task/basic/periodic.py +3 -0
- runtimepy-5.15.5/runtimepy/ui/button.py +76 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5/runtimepy.egg-info}/PKG-INFO +7 -7
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy.egg-info/SOURCES.txt +5 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy.egg-info/requires.txt +4 -4
- {runtimepy-5.15.3 → runtimepy-5.15.5}/LICENSE +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/__main__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/app.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/channel/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/channel/environment/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/channel/environment/array.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/channel/environment/command/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/channel/environment/command/parser.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/channel/environment/command/result.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/channel/environment/create.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/channel/environment/sample.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/channel/environment/telemetry.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/channel/event/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/channel/event/header.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/channel/registry.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/codec/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/codec/protocol/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/codec/protocol/base.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/codec/protocol/json.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/codec/protocol/receiver.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/codec/system/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/commands/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/commands/all.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/commands/arbiter.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/commands/common.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/commands/mtu.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/commands/server.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/commands/task.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/commands/tftp.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/commands/tui.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/control/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/control/env/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/control/source.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/control/step.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/404.md +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/base.yaml +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/browser.yaml +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/css/font.css +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/factories.yaml +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/favicon.ico +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/js/DataConnection.js +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/js/JsonConnection.js +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/js/audio.js +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/js/classes/App.js +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/js/classes/DataConnection.js +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/js/classes/JsonConnection.js +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/js/classes/OverlayManager.js +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/js/classes/Plot.js +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/js/classes/PlotDrawer.js +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/js/classes/PlotManager.js +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/js/classes/PlotModalManager.js +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/js/classes/PointBuffer.js +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/js/classes/PointManager.js +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/js/classes/TabFilter.js +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/js/classes/UnitSystem.js +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/js/classes/WindowHashManager.js +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/js/events.js +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/js/main.js +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/js/markdown_page.js +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/js/tab/env.js +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/js/tab/sound.js +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/js/third-party/webgl-debug.js +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/js/unused/pyodide.js +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/js/util.js +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/js/worker.js +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/md/Connection.md +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/md/PeriodicTask.md +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/md/RuntimeStruct.md +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/md/RuntimepyPeer.md +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/md/SinusoidTask.md +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/sample_telemetry.yaml +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/schemas/BitFields.yaml +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/schemas/Channel.yaml +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/schemas/ChannelCommand.yaml +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/schemas/ChannelRegistry.yaml +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/schemas/EnumRegistry.yaml +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/schemas/FindFile.yaml +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/schemas/RuntimeEnum.yaml +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/schemas/ServerConnectionConfig.yaml +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/schemas/StructConfig.yaml +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/schemas/TaskConfig.yaml +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/schemas/channel_controls.yaml +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/schemas/has_config.yaml +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/schemas/has_factory.yaml +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/schemas/has_markdown.yaml +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/schemas/has_name.yaml +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/schemas/has_request_flag.yaml +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/server.yaml +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/server_base.yaml +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/server_dev.yaml +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/static/css/bootstrap-icons.min.css +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/static/css/bootstrap.min.css +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/static/css/fonts/bootstrap-icons.woff +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/static/css/fonts/bootstrap-icons.woff2 +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/static/js/bootstrap.bundle.min.js +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/static/js/webglplot.umd.min.js +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/static/png/chip-circle-bootstrap/1024x1024.png +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/static/png/chip-circle-bootstrap/128x128.png +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/static/png/chip-circle-bootstrap/16x16.png +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/static/png/chip-circle-bootstrap/1920x1920.png +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/static/png/chip-circle-bootstrap/24x24.png +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/static/png/chip-circle-bootstrap/256x256.png +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/static/png/chip-circle-bootstrap/32x32.png +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/static/png/chip-circle-bootstrap/512x512.png +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/static/png/chip-circle-bootstrap/64x64.png +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/static/svg/chip-circle-bootstrap.svg +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/static/svg/outline-dark.svg +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/static/svg/outline-light.svg +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/static/woff2/CascadiaCode-Bold.woff2 +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/static/woff2/CascadiaCode-BoldItalic.woff2 +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/static/woff2/CascadiaCode-Italic.woff2 +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/static/woff2/CascadiaCode-Regular.woff2 +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/static/woff2/CascadiaMono-Bold.woff2 +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/static/woff2/CascadiaMono-BoldItalic.woff2 +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/static/woff2/CascadiaMono-Italic.woff2 +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/static/woff2/CascadiaMono-Regular.woff2 +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/static/woff2/README.md +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/data/tftp_server.yaml +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/dev_requirements.txt +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/entry.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/enum/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/enum/registry.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/enum/types.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/mapping.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/message/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/message/handlers.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/message/interface.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/message/types.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/metrics/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/metrics/channel.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/metrics/connection.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/metrics/task.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/mixins/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/mixins/async_command.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/mixins/enum.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/mixins/environment.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/mixins/finalize.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/mixins/logging.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/mixins/psutil.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/mixins/regex.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/mixins/trig.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/apps/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/arbiter/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/arbiter/config/codec.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/arbiter/config/util.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/arbiter/factory/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/arbiter/factory/task.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/arbiter/housekeeping/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/arbiter/imports/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/arbiter/imports/util.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/arbiter/info.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/arbiter/result.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/arbiter/struct/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/arbiter/task.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/arbiter/tcp/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/arbiter/tcp/json.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/arbiter/udp.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/arbiter/websocket.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/backoff.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/connection.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/factories/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/html/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/html/arbiter.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/html/bootstrap/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/html/bootstrap/elements.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/html/bootstrap/tabs.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/http/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/http/common.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/http/header.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/http/request_target.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/http/response.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/http/state.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/http/version.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/manager.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/mixin.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/mtu.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/server/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/server/app/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/server/app/base.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/server/app/create.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/server/app/elements.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/server/app/env/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/server/app/env/modal.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/server/app/env/settings.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/server/app/env/tab/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/server/app/env/tab/controls.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/server/app/env/tab/message.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/server/app/files.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/server/app/landing_page.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/server/app/placeholder.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/server/app/pyodide.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/server/app/sound.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/server/app/tab.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/server/html.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/server/json.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/server/markdown.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/server/mux.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/server/struct/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/server/websocket/state.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/ssl.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/stream/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/stream/base.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/stream/json/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/stream/string.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/tcp/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/tcp/connection.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/tcp/create.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/tcp/http/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/tcp/protocol.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/tcp/scpi/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/tcp/telnet/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/tcp/telnet/codes.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/tcp/telnet/np_05b.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/udp/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/udp/connection.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/udp/create.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/udp/protocol.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/udp/queue.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/udp/tftp/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/udp/tftp/base.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/udp/tftp/endpoint.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/udp/tftp/enums.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/udp/tftp/io.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/util.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/websocket/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/net/websocket/connection.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/noise/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/primitives/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/primitives/array/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/primitives/base.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/primitives/bool.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/primitives/byte_order.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/primitives/evaluation.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/primitives/field/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/primitives/field/fields.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/primitives/field/manager/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/primitives/field/manager/base.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/primitives/float.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/primitives/int.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/primitives/scaling.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/primitives/serializable/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/primitives/serializable/base.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/primitives/serializable/fixed.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/primitives/serializable/framer.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/primitives/serializable/prefixed.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/primitives/string.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/primitives/types/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/primitives/types/base.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/primitives/types/bool.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/primitives/types/bounds.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/primitives/types/float.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/primitives/types/int.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/py.typed +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/registry/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/registry/bool.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/registry/item.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/registry/name.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/sample/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/sample/peer.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/sample/program.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/schemas.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/subprocess/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/subprocess/interface.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/subprocess/peer.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/subprocess/program.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/subprocess/protocol.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/task/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/task/asynchronous.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/task/basic/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/task/basic/manager.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/task/sample.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/task/trig/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/telemetry/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/telemetry/sample.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/tui/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/tui/channels/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/tui/cursor.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/tui/mixin.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/tui/mock.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/tui/task.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/ui/__init__.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/ui/controls.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy/util.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy.egg-info/dependency_links.txt +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy.egg-info/entry_points.txt +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/runtimepy.egg-info/top_level.txt +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/setup.cfg +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/setup.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/tests/test_entry.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/tests/test_mapping.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/tests/test_resources.py +0 -0
- {runtimepy-5.15.3 → runtimepy-5.15.5}/tests/test_util.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: runtimepy
|
|
3
|
-
Version: 5.15.
|
|
3
|
+
Version: 5.15.5
|
|
4
4
|
Summary: A framework for implementing Python services.
|
|
5
5
|
Home-page: https://github.com/libre-embedded/runtimepy
|
|
6
6
|
Author: Libre Embedded
|
|
@@ -17,11 +17,11 @@ Classifier: Development Status :: 5 - Production/Stable
|
|
|
17
17
|
Requires-Python: >=3.12
|
|
18
18
|
Description-Content-Type: text/markdown
|
|
19
19
|
License-File: LICENSE
|
|
20
|
-
Requires-Dist: websockets
|
|
21
|
-
Requires-Dist: vcorelib>=3.6.3
|
|
22
|
-
Requires-Dist: svgen>=0.8.0
|
|
23
|
-
Requires-Dist: aiofiles
|
|
24
20
|
Requires-Dist: psutil
|
|
21
|
+
Requires-Dist: aiofiles
|
|
22
|
+
Requires-Dist: svgen>=0.8.0
|
|
23
|
+
Requires-Dist: websockets
|
|
24
|
+
Requires-Dist: vcorelib>=3.6.4
|
|
25
25
|
Provides-Extra: test
|
|
26
26
|
Requires-Dist: pylint; extra == "test"
|
|
27
27
|
Requires-Dist: flake8; extra == "test"
|
|
@@ -51,11 +51,11 @@ Dynamic: requires-python
|
|
|
51
51
|
=====================================
|
|
52
52
|
generator=datazen
|
|
53
53
|
version=3.2.3
|
|
54
|
-
hash=
|
|
54
|
+
hash=fd0e57419cf9437a64c4f82cae3625f0
|
|
55
55
|
=====================================
|
|
56
56
|
-->
|
|
57
57
|
|
|
58
|
-
# runtimepy ([5.15.
|
|
58
|
+
# runtimepy ([5.15.5](https://pypi.org/project/runtimepy/))
|
|
59
59
|
|
|
60
60
|
[](https://pypi.org/project/runtimepy/)
|
|
61
61
|

|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
=====================================
|
|
3
3
|
generator=datazen
|
|
4
4
|
version=3.2.3
|
|
5
|
-
hash=
|
|
5
|
+
hash=fd0e57419cf9437a64c4f82cae3625f0
|
|
6
6
|
=====================================
|
|
7
7
|
-->
|
|
8
8
|
|
|
9
|
-
# runtimepy ([5.15.
|
|
9
|
+
# runtimepy ([5.15.5](https://pypi.org/project/runtimepy/))
|
|
10
10
|
|
|
11
11
|
[](https://pypi.org/project/runtimepy/)
|
|
12
12
|

|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# =====================================
|
|
2
2
|
# generator=datazen
|
|
3
3
|
# version=3.2.3
|
|
4
|
-
# hash=
|
|
4
|
+
# hash=8ce7abe0f8c0e64d9afc0b5e4de6e2ad
|
|
5
5
|
# =====================================
|
|
6
6
|
|
|
7
7
|
"""
|
|
@@ -10,7 +10,7 @@ Useful defaults and other package metadata.
|
|
|
10
10
|
|
|
11
11
|
DESCRIPTION = "A framework for implementing Python services."
|
|
12
12
|
PKG_NAME = "runtimepy"
|
|
13
|
-
VERSION = "5.15.
|
|
13
|
+
VERSION = "5.15.5"
|
|
14
14
|
|
|
15
15
|
# runtimepy-specific content.
|
|
16
16
|
METRICS_NAME = "metrics"
|
|
@@ -54,6 +54,7 @@ class BaseChannelEnvironment(_NamespaceMixin, FinalizeMixin):
|
|
|
54
54
|
fields: _Iterable[_BitFields] = None,
|
|
55
55
|
namespace: Namespace = None,
|
|
56
56
|
namespace_delim: str = DEFAULT_DELIM,
|
|
57
|
+
views: dict[str, str] = None,
|
|
57
58
|
) -> None:
|
|
58
59
|
"""Initialize this channel environment."""
|
|
59
60
|
|
|
@@ -105,6 +106,10 @@ class BaseChannelEnvironment(_NamespaceMixin, FinalizeMixin):
|
|
|
105
106
|
if values is not None:
|
|
106
107
|
self.apply(values)
|
|
107
108
|
|
|
109
|
+
if not views:
|
|
110
|
+
views = {}
|
|
111
|
+
self.views = views
|
|
112
|
+
|
|
108
113
|
def __setitem__(self, key: _RegistryKey, value: ChannelValue) -> None:
|
|
109
114
|
"""Mapping-set interface."""
|
|
110
115
|
return self.set(key, value)
|
|
@@ -20,6 +20,7 @@ from runtimepy.channel.environment.command.result import SUCCESS, CommandResult
|
|
|
20
20
|
from runtimepy.mixins.environment import ChannelEnvironmentMixin
|
|
21
21
|
from runtimepy.primitives.bool import Bool
|
|
22
22
|
from runtimepy.primitives.field import BitField
|
|
23
|
+
from runtimepy.ui.button import ActionButton
|
|
23
24
|
|
|
24
25
|
CommandHook = Callable[[Namespace, Optional[FieldOrChannel]], None]
|
|
25
26
|
|
|
@@ -33,7 +34,11 @@ class ChannelCommandProcessor(ChannelEnvironmentMixin):
|
|
|
33
34
|
"""A command processing interface for channel environments."""
|
|
34
35
|
|
|
35
36
|
def __init__(
|
|
36
|
-
self,
|
|
37
|
+
self,
|
|
38
|
+
env: ChannelEnvironment,
|
|
39
|
+
logger: LoggerType,
|
|
40
|
+
buttons: list[ActionButton] = None,
|
|
41
|
+
**kwargs,
|
|
37
42
|
) -> None:
|
|
38
43
|
"""Initialize this instance."""
|
|
39
44
|
|
|
@@ -49,6 +54,11 @@ class ChannelCommandProcessor(ChannelEnvironmentMixin):
|
|
|
49
54
|
|
|
50
55
|
self.parser.initialize()
|
|
51
56
|
|
|
57
|
+
# Action buttons.
|
|
58
|
+
if buttons is None:
|
|
59
|
+
buttons = []
|
|
60
|
+
self.buttons: list[ActionButton] = buttons
|
|
61
|
+
|
|
52
62
|
def register_custom_commands(
|
|
53
63
|
self, *custom_commands: CustomCommand
|
|
54
64
|
) -> None:
|
|
@@ -42,6 +42,8 @@ ENUMS_FILE = f"{ENUMS_KEY}.json"
|
|
|
42
42
|
VALUES_FILE = f"{VALUES_KEY}.json"
|
|
43
43
|
FIELDS_FILE = f"{FIELDS_KEY}.json"
|
|
44
44
|
NAMES_FILE = f"{NAMES_KEY}.json"
|
|
45
|
+
VIEWS_KEY = "views"
|
|
46
|
+
# VIEWS_FILE = f"{VIEWS_KEY}.json"
|
|
45
47
|
|
|
46
48
|
|
|
47
49
|
class FileChannelEnvironment(_BaseChannelEnvironment):
|
|
@@ -64,6 +66,7 @@ class FileChannelEnvironment(_BaseChannelEnvironment):
|
|
|
64
66
|
VALUES_KEY: _cast(
|
|
65
67
|
_JsonObject, self.values(resolve_enum=resolve_enum)
|
|
66
68
|
),
|
|
69
|
+
VIEWS_KEY: _cast(_JsonObject, self.views),
|
|
67
70
|
}
|
|
68
71
|
|
|
69
72
|
def export(
|
|
@@ -143,6 +146,7 @@ class FileChannelEnvironment(_BaseChannelEnvironment):
|
|
|
143
146
|
enums=enum_reg,
|
|
144
147
|
values=_cast(_Optional[_ValueMap], data.get(VALUES_KEY)),
|
|
145
148
|
fields=_fields_from_dict(data[FIELDS_KEY]),
|
|
149
|
+
views=_cast(dict[str, str], data.get(VIEWS_KEY, {})),
|
|
146
150
|
)
|
|
147
151
|
|
|
148
152
|
# Typically, externally loaded environments should be final at load
|
|
@@ -110,6 +110,10 @@ select:hover {
|
|
|
110
110
|
background-image: linear-gradient(to bottom, var(--bs-tertiary-bg), rgba(var(--bs-tertiary-bg-rgb), 0), var(--bs-tertiary-bg));
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
+
.bg-gradient-tertiary-left-right {
|
|
114
|
+
background-image: linear-gradient(to right, var(--bs-tertiary-bg), rgba(var(--bs-tertiary-bg-rgb), 0), var(--bs-tertiary-bg));
|
|
115
|
+
}
|
|
116
|
+
|
|
113
117
|
.border-start-info-subtle {
|
|
114
118
|
border-left: var(--bs-border-width) var(--bs-border-style) var(--bs-info-border-subtle);
|
|
115
119
|
}
|
|
@@ -1,4 +1,42 @@
|
|
|
1
1
|
---
|
|
2
|
+
# UDP JSON clients.
|
|
3
|
+
clients:
|
|
4
|
+
- factory: udp_json
|
|
5
|
+
name: udp_json_client
|
|
6
|
+
defer: true
|
|
7
|
+
kwargs:
|
|
8
|
+
remote_addr: [localhost, "$udp_json"]
|
|
9
|
+
views:
|
|
10
|
+
- [metrics, metrics]
|
|
11
|
+
- [transmit, tx]
|
|
12
|
+
- [receive, rx]
|
|
13
|
+
buttons: &buttons
|
|
14
|
+
- icon: tux
|
|
15
|
+
key: test
|
|
16
|
+
payload: {}
|
|
17
|
+
- icon: tux
|
|
18
|
+
key: test
|
|
19
|
+
text: asdf
|
|
20
|
+
payload: {}
|
|
21
|
+
- icon: tux
|
|
22
|
+
key: test
|
|
23
|
+
payload: {}
|
|
24
|
+
outline: false
|
|
25
|
+
- icon: tux
|
|
26
|
+
key: test
|
|
27
|
+
text: asdf
|
|
28
|
+
payload: {}
|
|
29
|
+
outline: false
|
|
30
|
+
markdown: |
|
|
31
|
+
# `udp_json_client`
|
|
32
|
+
|
|
33
|
+
Connects to `udp_json_server`.
|
|
34
|
+
|
|
35
|
+
- factory: udp_json
|
|
36
|
+
name: udp_json_server
|
|
37
|
+
kwargs:
|
|
38
|
+
local_addr: [localhost, "$udp_json"]
|
|
39
|
+
|
|
2
40
|
# Add some sample tasks.
|
|
3
41
|
tasks:
|
|
4
42
|
# Chaos.
|
|
@@ -9,6 +47,10 @@ tasks:
|
|
|
9
47
|
a: 1
|
|
10
48
|
b: 2
|
|
11
49
|
c: 3
|
|
50
|
+
buttons: *buttons
|
|
51
|
+
views:
|
|
52
|
+
- [zero, "\\.0\\."]
|
|
53
|
+
- [one, "\\.1\\."]
|
|
12
54
|
markdown: |
|
|
13
55
|
# This is a Test
|
|
14
56
|
|
|
@@ -29,6 +71,9 @@ tasks:
|
|
|
29
71
|
- name: wave3
|
|
30
72
|
factory: sinusoid
|
|
31
73
|
period_s: 0.03
|
|
74
|
+
config:
|
|
75
|
+
views:
|
|
76
|
+
- [trig, sin cos]
|
|
32
77
|
markdown: |
|
|
33
78
|
# Markdown for wave3
|
|
34
79
|
|
|
@@ -43,23 +88,6 @@ tasks:
|
|
|
43
88
|
# Drive interactions with runtime entities that won't otherwise be polled.
|
|
44
89
|
- {name: app, factory: SampleApp, period_s: 0.25}
|
|
45
90
|
|
|
46
|
-
# UDP JSON clients.
|
|
47
|
-
clients:
|
|
48
|
-
- factory: udp_json
|
|
49
|
-
name: udp_json_client
|
|
50
|
-
defer: true
|
|
51
|
-
kwargs:
|
|
52
|
-
remote_addr: [localhost, "$udp_json"]
|
|
53
|
-
markdown: |
|
|
54
|
-
# `udp_json_client`
|
|
55
|
-
|
|
56
|
-
Connects to `udp_json_server`.
|
|
57
|
-
|
|
58
|
-
- factory: udp_json
|
|
59
|
-
name: udp_json_server
|
|
60
|
-
kwargs:
|
|
61
|
-
local_addr: [localhost, "$udp_json"]
|
|
62
|
-
|
|
63
91
|
# Add some sample structs.
|
|
64
92
|
structs:
|
|
65
93
|
- name: example.struct1
|
|
@@ -70,6 +98,8 @@ structs:
|
|
|
70
98
|
b: 2
|
|
71
99
|
c: 3
|
|
72
100
|
|
|
101
|
+
buttons: *buttons
|
|
102
|
+
|
|
73
103
|
markdown: |
|
|
74
104
|
# Docs for `example.struct1`
|
|
75
105
|
|
|
@@ -56,6 +56,10 @@ class ChannelTable {
|
|
|
56
56
|
|
|
57
57
|
if (Number.isInteger(val)) {
|
|
58
58
|
/* Handle integer formatting. */
|
|
59
|
+
} else if (typeof val == "boolean") {
|
|
60
|
+
/* Use glyphs for booleans. */
|
|
61
|
+
val = val ? '<i class="bi bi-circle-fill"></i>'
|
|
62
|
+
: '<i class="bi bi-circle"></i>';
|
|
59
63
|
} else {
|
|
60
64
|
/* Handle floating-point numbers. */
|
|
61
65
|
let checkFloat = Number.parseFloat(val);
|
|
@@ -263,6 +263,19 @@ class TabInterface {
|
|
|
263
263
|
this.updateChannelStyles(this.channelFilter.value);
|
|
264
264
|
};
|
|
265
265
|
}
|
|
266
|
+
|
|
267
|
+
/* Initialize channel view dropdown. */
|
|
268
|
+
let channelView = this.query("#filter-view");
|
|
269
|
+
if (channelView) {
|
|
270
|
+
channelView.onchange = () => {
|
|
271
|
+
if (!channelView.value || channelView.value == '-') {
|
|
272
|
+
this.channelFilter.value = "";
|
|
273
|
+
} else {
|
|
274
|
+
this.channelFilter.value = channelView.value;
|
|
275
|
+
}
|
|
276
|
+
this.updateChannelStyles(this.channelFilter.value);
|
|
277
|
+
};
|
|
278
|
+
}
|
|
266
279
|
}
|
|
267
280
|
|
|
268
281
|
setHandler(elem) {
|
|
@@ -10,7 +10,7 @@ class WorkerInterface {
|
|
|
10
10
|
|
|
11
11
|
command(data) { this.send({kind : "command", value : data}); }
|
|
12
12
|
|
|
13
|
-
bus(data) { this.worker.postMessage({bus : data}); }
|
|
13
|
+
bus(key, data) { this.worker.postMessage({key : key, bus : data}); }
|
|
14
14
|
|
|
15
15
|
toWorker(data, param) { return this.send({"worker" : data}, param); }
|
|
16
16
|
}
|
|
@@ -53,8 +53,10 @@ function isModifierKeyEvent(event) {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
function ignoreFilterKeyEvent(event) {
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
return isModifierKeyEvent(event) || event.key == "Tab" ||
|
|
57
|
+
(event.key.startsWith("F") && event.key.length > 1) ||
|
|
58
|
+
event.key.startsWith("Del") || event.key == "Home" ||
|
|
59
|
+
event.key == "End" || event.key == "PageUp" || event.key == "PageDown";
|
|
58
60
|
}
|
|
59
61
|
|
|
60
62
|
function globalKeyEvent(event) {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
console.log(`sample.js included (${tab.name})`);
|
|
2
|
-
// tab.worker.bus({a: 1, b: 2, c: 3});
|
|
2
|
+
// tab.worker.bus("test", {a: 1, b: 2, c: 3});
|
|
@@ -27,14 +27,7 @@ properties:
|
|
|
27
27
|
$ref: package://runtimepy/schemas/StructConfig.yaml
|
|
28
28
|
|
|
29
29
|
commands:
|
|
30
|
-
|
|
31
|
-
items:
|
|
32
|
-
type: array
|
|
33
|
-
minItems: 2
|
|
34
|
-
maxItems: 2
|
|
35
|
-
items:
|
|
36
|
-
- type: string
|
|
37
|
-
- type: string
|
|
30
|
+
$ref: package://runtimepy/schemas/TwoTupleArray.yaml
|
|
38
31
|
|
|
39
32
|
tasks:
|
|
40
33
|
type: array
|
|
@@ -47,6 +47,7 @@ from runtimepy.net.manager import ConnectionManager as _ConnectionManager
|
|
|
47
47
|
from runtimepy.net.server import RuntimepyServerConnection
|
|
48
48
|
from runtimepy.subprocess.peer import RuntimepyPeer as _RuntimepyPeer
|
|
49
49
|
from runtimepy.tui.mixin import CursesWindow, TuiMixin
|
|
50
|
+
from runtimepy.ui.button import ActionButton
|
|
50
51
|
|
|
51
52
|
ServerTask = _Awaitable[None]
|
|
52
53
|
RuntimeProcessTask = tuple[
|
|
@@ -147,6 +148,8 @@ class BaseConnectionArbiter(_NamespaceMixin, _LoggerMixin, TuiMixin):
|
|
|
147
148
|
self._ports: dict[str, int] = {}
|
|
148
149
|
|
|
149
150
|
self._commands: list[tuple[str, str]] = []
|
|
151
|
+
self._views: dict[str, dict[str, str]] = {}
|
|
152
|
+
self._buttons: dict[str, list[ActionButton]] = {}
|
|
150
153
|
|
|
151
154
|
self._init()
|
|
152
155
|
|
|
@@ -156,6 +159,16 @@ class BaseConnectionArbiter(_NamespaceMixin, _LoggerMixin, TuiMixin):
|
|
|
156
159
|
def _register_connection(self, connection: _Connection, name: str) -> None:
|
|
157
160
|
"""Perform connection registration."""
|
|
158
161
|
|
|
162
|
+
# Handle views.
|
|
163
|
+
if name in self._views:
|
|
164
|
+
connection.env.views.update(self._views[name])
|
|
165
|
+
del self._views[name]
|
|
166
|
+
|
|
167
|
+
# Handle buttons.
|
|
168
|
+
if name in self._buttons:
|
|
169
|
+
connection.command.buttons.extend(self._buttons[name])
|
|
170
|
+
del self._buttons[name]
|
|
171
|
+
|
|
159
172
|
self._connections[name] = connection
|
|
160
173
|
self.manager.queue.put_nowait(connection)
|
|
161
174
|
connection.logger.info("Registered as '%s'.", name)
|
|
@@ -165,6 +178,8 @@ class BaseConnectionArbiter(_NamespaceMixin, _LoggerMixin, TuiMixin):
|
|
|
165
178
|
connection: _Union[_Connection, _Awaitable[_Connection]],
|
|
166
179
|
*names: str,
|
|
167
180
|
delim: str = None,
|
|
181
|
+
views: dict[str, str] = None,
|
|
182
|
+
buttons: list[ActionButton] = None,
|
|
168
183
|
) -> bool:
|
|
169
184
|
"""Attempt to register a connection object."""
|
|
170
185
|
|
|
@@ -173,6 +188,11 @@ class BaseConnectionArbiter(_NamespaceMixin, _LoggerMixin, TuiMixin):
|
|
|
173
188
|
with self.names_pushed(*names):
|
|
174
189
|
name = self.namespace(delim=delim)
|
|
175
190
|
|
|
191
|
+
if views:
|
|
192
|
+
self._views[name] = views
|
|
193
|
+
if buttons:
|
|
194
|
+
self._buttons[name] = buttons
|
|
195
|
+
|
|
176
196
|
if (
|
|
177
197
|
name not in self._connections
|
|
178
198
|
and name not in self._deferred_connections
|
|
@@ -170,7 +170,6 @@ class ConfigConnectionArbiter(_ImportConnectionArbiter):
|
|
|
170
170
|
kwargs = dict_resolve_env_vars(
|
|
171
171
|
client.get("kwargs", {}), env=self._ports # type: ignore
|
|
172
172
|
)
|
|
173
|
-
kwargs.setdefault("markdown", client.get("markdown"))
|
|
174
173
|
|
|
175
174
|
assert await self.factory_client(
|
|
176
175
|
factory,
|
|
@@ -179,6 +178,9 @@ class ConfigConnectionArbiter(_ImportConnectionArbiter):
|
|
|
179
178
|
defer=client["defer"],
|
|
180
179
|
# Perform some known fixes for common keyword arguments.
|
|
181
180
|
**fix_kwargs(kwargs),
|
|
181
|
+
views=client.get("views"),
|
|
182
|
+
markdown=client.get("markdown"),
|
|
183
|
+
buttons=client.get("buttons", []),
|
|
182
184
|
), f"Couldn't register client '{name}' ({factory})!"
|
|
183
185
|
|
|
184
186
|
# Register servers.
|
|
@@ -16,6 +16,7 @@ from runtimepy.net.arbiter.base import (
|
|
|
16
16
|
from runtimepy.net.arbiter.base import ServerTask as _ServerTask
|
|
17
17
|
from runtimepy.net.connection import Connection as _Connection
|
|
18
18
|
from runtimepy.net.manager import ConnectionManager as _ConnectionManager
|
|
19
|
+
from runtimepy.ui.button import ActionButton
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
class ConnectionFactory:
|
|
@@ -89,12 +90,19 @@ class FactoryConnectionArbiter(_BaseConnectionArbiter):
|
|
|
89
90
|
if factory in self._conn_factories:
|
|
90
91
|
factory_inst = self._conn_factories[factory]
|
|
91
92
|
|
|
93
|
+
views = kwargs.pop("views", {})
|
|
94
|
+
buttons = ActionButton.from_top_level(kwargs.pop("buttons", []))
|
|
95
|
+
|
|
92
96
|
conn = factory_inst.client(name, *args, **kwargs)
|
|
93
97
|
if not defer:
|
|
94
98
|
conn = await conn # type: ignore
|
|
95
99
|
|
|
96
100
|
result = self.register_connection(
|
|
97
|
-
conn,
|
|
101
|
+
conn,
|
|
102
|
+
*self._conn_names[factory_inst],
|
|
103
|
+
name,
|
|
104
|
+
views=views,
|
|
105
|
+
buttons=buttons,
|
|
98
106
|
)
|
|
99
107
|
|
|
100
108
|
return result
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
A module implementing a channel-environment tab HTML interface.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
# built-in
|
|
6
|
+
from io import StringIO
|
|
7
|
+
|
|
5
8
|
# third-party
|
|
6
9
|
from vcorelib.io.markdown import MarkdownMixin
|
|
7
10
|
from vcorelib.logging import LoggerMixin
|
|
@@ -39,3 +42,11 @@ class ChannelEnvironmentTabBase(Tab, LoggerMixin, MarkdownMixin):
|
|
|
39
42
|
# Logging.
|
|
40
43
|
LoggerMixin.__init__(self, logger=self.command.logger)
|
|
41
44
|
self.log_limiter = RateLimiter.from_s(1.0)
|
|
45
|
+
|
|
46
|
+
def _action_markdown(self) -> str:
|
|
47
|
+
"""Get action-button markdown."""
|
|
48
|
+
|
|
49
|
+
with StringIO() as stream:
|
|
50
|
+
for button in self.command.buttons:
|
|
51
|
+
button.element().encode(stream)
|
|
52
|
+
return stream.getvalue()
|
|
@@ -289,6 +289,16 @@ class ChannelEnvironmentTabHtml(ChannelEnvironmentTabControls):
|
|
|
289
289
|
)
|
|
290
290
|
logs.booleans.add("readonly")
|
|
291
291
|
|
|
292
|
+
if self.command.buttons:
|
|
293
|
+
centered_markdown(
|
|
294
|
+
vert_container,
|
|
295
|
+
self._action_markdown(),
|
|
296
|
+
"border-start",
|
|
297
|
+
"border-bottom",
|
|
298
|
+
"border-end",
|
|
299
|
+
"bg-gradient-tertiary-left-right",
|
|
300
|
+
)
|
|
301
|
+
|
|
292
302
|
self.channel_table(vert_container)
|
|
293
303
|
|
|
294
304
|
centered_markdown(
|
|
@@ -80,6 +80,22 @@ def enum_dropdown(
|
|
|
80
80
|
TABLE_BUTTON_CLASSES = ("border-top-0", "border-bottom-0")
|
|
81
81
|
|
|
82
82
|
|
|
83
|
+
def views_dropdown(parent: Element, command: ChannelCommandProcessor) -> None:
|
|
84
|
+
"""Dropdown menu for channel environment views."""
|
|
85
|
+
|
|
86
|
+
select = select_element(
|
|
87
|
+
parent=div(
|
|
88
|
+
tag="th", parent=parent, class_str="p-0 channel-views-min-width"
|
|
89
|
+
),
|
|
90
|
+
id="filter-view",
|
|
91
|
+
title="Canonical channel filters.",
|
|
92
|
+
).add_class("border-end-0", "w-100")
|
|
93
|
+
div(tag="option", value="", text="-", parent=select)
|
|
94
|
+
div(tag="option", value="^$", text="hide", parent=select)
|
|
95
|
+
for text, value in command.env.views.items():
|
|
96
|
+
div(tag="option", value=value, text=text, parent=select)
|
|
97
|
+
|
|
98
|
+
|
|
83
99
|
def channel_table_header(
|
|
84
100
|
parent: Element, command: ChannelCommandProcessor
|
|
85
101
|
) -> None:
|
|
@@ -105,7 +121,11 @@ def channel_table_header(
|
|
|
105
121
|
).add_class(*TABLE_BUTTON_CLASSES)
|
|
106
122
|
|
|
107
123
|
_, label, box = input_box(
|
|
108
|
-
div(
|
|
124
|
+
div(
|
|
125
|
+
tag="th",
|
|
126
|
+
parent=ctl_row,
|
|
127
|
+
class_str="p-0 border-end-0 channel-filter-min-width",
|
|
128
|
+
),
|
|
109
129
|
description="Channel name filter.",
|
|
110
130
|
pattern=".* ! @ $",
|
|
111
131
|
label="filter",
|
|
@@ -114,7 +134,9 @@ def channel_table_header(
|
|
|
114
134
|
spellcheck="false",
|
|
115
135
|
)
|
|
116
136
|
label.add_class("border-top-0", "border-bottom-0")
|
|
117
|
-
box.add_class("border-top-0", "border-bottom-0")
|
|
137
|
+
box.add_class("border-top-0", "border-bottom-0", "border-end-0")
|
|
138
|
+
|
|
139
|
+
views_dropdown(ctl_row, command)
|
|
118
140
|
|
|
119
141
|
cell = flex(
|
|
120
142
|
parent=div(tag="th", parent=ctl_row, colspan="2", class_str="p-0")
|
|
@@ -124,7 +146,6 @@ def channel_table_header(
|
|
|
124
146
|
select = select_element(
|
|
125
147
|
parent=cell, id="custom-commands", title="Custom command selector."
|
|
126
148
|
)
|
|
127
|
-
select.add_class("border-start-0")
|
|
128
149
|
|
|
129
150
|
if command.custom_commands:
|
|
130
151
|
for key in command.custom_commands:
|
|
@@ -141,12 +162,7 @@ def channel_table_header(
|
|
|
141
162
|
tooltip="Send selected command (left dropdown).",
|
|
142
163
|
).add_class(*TABLE_BUTTON_CLASSES)
|
|
143
164
|
else:
|
|
144
|
-
div(
|
|
145
|
-
tag="option",
|
|
146
|
-
parent=select,
|
|
147
|
-
value="noop",
|
|
148
|
-
text="no custom commands",
|
|
149
|
-
)
|
|
165
|
+
div(tag="option", parent=select, value="noop", text="-")
|
|
150
166
|
select.booleans.add("disabled")
|
|
151
167
|
|
|
152
168
|
# Button for 'reset all defaults' if this tab has more than one channel
|
|
@@ -21,6 +21,7 @@ from runtimepy.channel.environment.command.processor import (
|
|
|
21
21
|
from runtimepy.mixins.async_command import AsyncCommandProcessingMixin
|
|
22
22
|
from runtimepy.mixins.environment import ChannelEnvironmentMixin
|
|
23
23
|
from runtimepy.mixins.logging import LoggerMixinLevelControl
|
|
24
|
+
from runtimepy.ui.button import ActionButton
|
|
24
25
|
|
|
25
26
|
|
|
26
27
|
class RuntimeStructBase(
|
|
@@ -45,10 +46,12 @@ class RuntimeStructBase(
|
|
|
45
46
|
self.set_markdown(config=config, markdown=markdown, package=PKG_NAME)
|
|
46
47
|
LoggerMixinLevelControl.__init__(self, logger=_getLogger(self.name))
|
|
47
48
|
ChannelEnvironmentMixin.__init__(self)
|
|
49
|
+
self.env.views.update(config.get("views", {})) # type: ignore
|
|
48
50
|
if self.log_level_channel:
|
|
49
51
|
self.setup_level_channel(self.env)
|
|
50
52
|
self.command = ChannelCommandProcessor(self.env, self.logger)
|
|
51
53
|
self.config = config
|
|
54
|
+
self.command.buttons.extend(ActionButton.from_top_level(self.config))
|
|
52
55
|
|
|
53
56
|
async def poll(args: Namespace, __: Optional[FieldOrChannel]) -> None:
|
|
54
57
|
"""Handle a test command."""
|