Skip to content

Commit 6e4ba0c

Browse files
authored
wip (#323)
* wip * ui dev * a lot of ui dev * more features working * more development * remove redundant css rules * update bootstrap deps * more dev * a lot of new stuff * add markdown background gradients * attempt to set initial focus * minor border tweaks * auto focus channel filter when changing tab * focus channel table when toggling * auto focus tab filter on open * more focus scenarios * use browser's suggestion for 'passive' * more features * add title to checkbox * wip * sa fixes * comment * fixes for firefox * minor fixes * use new vcorelib def and fifo * fix minor issue for touch interface * remove source mapping lines * add websocket restarting * upgrades for markdown dir stuff * fix markdown page gradients * finish unit testing * sa
1 parent c7f80e7 commit 6e4ba0c

File tree

123 files changed

+1814
-486
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

123 files changed

+1814
-486
lines changed

.github/workflows/python-package.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ jobs:
7878
7979
- run: |
8080
mk python-release owner=libre-embedded \
81-
repo=runtimepy version=5.14.2
81+
repo=runtimepy version=5.15.0
8282
if: |
8383
matrix.python-version == '3.12'
8484
&& matrix.system == 'ubuntu-latest'

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
=====================================
33
generator=datazen
44
version=3.2.3
5-
hash=d3dcde1ba35cb14decfc6881b6a2d4e6
5+
hash=db8f45762873863c99d4d7d8f996d2fb
66
=====================================
77
-->
88

9-
# runtimepy ([5.14.2](https://pypi.org/project/runtimepy/))
9+
# runtimepy ([5.15.0](https://pypi.org/project/runtimepy/))
1010

1111
[![python](https://img.shields.io/pypi/pyversions/runtimepy.svg)](https://pypi.org/project/runtimepy/)
1212
![Build Status](https://github.com/libre-embedded/runtimepy/workflows/Python%20Package/badge.svg)

ifgen.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
includes:
3+
- config/python/ifgen/settings.yaml
4+
- config/python/ifgen/sample.yaml
5+
- package://ifgen/plugins/struct_receiver.yaml
6+
7+
cpp_dir: []
8+
python_dir: [tests]
9+
namespace: [tests]

local/configs/package.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ time_command: true
88

99
requirements:
1010
- aiofiles
11-
- vcorelib>=3.6.0
12-
- svgen>=0.7.12
11+
- vcorelib>=3.6.2
12+
- svgen>=0.8.0
1313
- websockets
1414
- psutil
1515
- "windows-curses; sys_platform == 'win32' and python_version < '3.12'"

local/variables/package.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
22
major: 5
3-
minor: 14
4-
patch: 2
3+
minor: 15
4+
patch: 0
55
entry: runtimepy

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta:__legacy__"
44

55
[project]
66
name = "runtimepy"
7-
version = "5.14.2"
7+
version = "5.15.0"
88
description = "A framework for implementing Python services."
99
readme = "README.md"
1010
requires-python = ">=3.12"

runtimepy/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# =====================================
22
# generator=datazen
33
# version=3.2.3
4-
# hash=f2469e97ed5a3a48c5347357f12c3554
4+
# hash=58f166da9bc0561c671ef04c334d585d
55
# =====================================
66

77
"""
@@ -10,7 +10,7 @@
1010

1111
DESCRIPTION = "A framework for implementing Python services."
1212
PKG_NAME = "runtimepy"
13-
VERSION = "5.14.2"
13+
VERSION = "5.15.0"
1414

1515
# runtimepy-specific content.
1616
METRICS_NAME = "metrics"

runtimepy/channel/__init__.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,7 @@
2929
from runtimepy.primitives.int import Uint64 as _Uint64
3030
from runtimepy.primitives.types import AnyPrimitiveType as _AnyPrimitiveType
3131
from runtimepy.registry.item import RegistryItem as _RegistryItem
32-
33-
Literal = int | float | bool
34-
Default = _Optional[Literal]
35-
Controls = dict[str, Literal | dict[str, Literal]]
32+
from runtimepy.ui.controls import Controls, Default
3633

3734

3835
class Channel(_RegistryItem, _EnumMixin, _Generic[_T]):

runtimepy/channel/environment/__init__.py

Lines changed: 93 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
"""
44

55
# built-in
6+
from contextlib import ExitStack as _ExitStack
67
from typing import Iterator as _Iterator
8+
from typing import Optional
9+
from typing import cast as _cast
710

811
# internal
9-
from runtimepy.channel import Default as _Default
1012
from runtimepy.channel.environment.array import (
1113
ArrayChannelEnvironment as _ArrayChannelEnvironment,
1214
)
@@ -19,6 +21,23 @@
1921
from runtimepy.channel.environment.telemetry import (
2022
TelemetryChannelEnvironment as _TelemetryChannelEnvironment,
2123
)
24+
from runtimepy.codec.protocol import Protocol as _Protocol
25+
from runtimepy.codec.protocol.base import FieldSpec as _FieldSpec
26+
from runtimepy.primitives import AnyPrimitive
27+
from runtimepy.ui.controls import Controls, Default, bit_slider
28+
29+
30+
def regular_channel_controls(
31+
primitive: AnyPrimitive, commandable: bool
32+
) -> Optional[Controls]:
33+
"""Get channel controls for a regular primitive."""
34+
35+
controls = None
36+
37+
if commandable and primitive.kind.is_integer and primitive.kind.bits <= 32:
38+
controls = bit_slider(primitive.kind.bits, primitive.kind.signed)
39+
40+
return controls
2241

2342

2443
class ChannelEnvironment(
@@ -29,13 +48,85 @@ class ChannelEnvironment(
2948
):
3049
"""A class integrating channel and enumeration registries."""
3150

51+
def register_protocol(
52+
self, protocol: _Protocol, commandable: bool
53+
) -> None:
54+
"""Register protocol elements as named channels and fields."""
55+
56+
# Register any new enumerations.
57+
self.enums.register_from_other(protocol.enum_registry)
58+
59+
# need to handle defaults
60+
61+
for item in protocol.build:
62+
# Handle regular primitive fields.
63+
if isinstance(item, _FieldSpec):
64+
if item.is_array():
65+
assert item.array_length is not None
66+
with self.names_pushed(item.name):
67+
for idx in range(item.array_length):
68+
primitive = protocol.get_primitive(
69+
item.name, index=idx
70+
)
71+
self.channel(
72+
str(idx),
73+
kind=primitive,
74+
commandable=commandable,
75+
enum=item.enum,
76+
controls=regular_channel_controls(
77+
primitive, commandable
78+
),
79+
)
80+
else:
81+
primitive = protocol.get_primitive(item.name)
82+
self.channel(
83+
item.name,
84+
kind=primitive,
85+
commandable=commandable,
86+
enum=item.enum,
87+
controls=regular_channel_controls(
88+
primitive, commandable
89+
),
90+
)
91+
92+
# Handle nested protocols.
93+
elif isinstance(item[0], str):
94+
name = item[0]
95+
candidates = protocol.serializables[name]
96+
if isinstance(candidates[0], _Protocol):
97+
with self.names_pushed(name):
98+
for idx, candidate in enumerate(candidates):
99+
with _ExitStack() as stack:
100+
# Enter array-index namespace if applicable.
101+
if len(candidates) > 1:
102+
stack.enter_context(
103+
self.names_pushed(str(idx))
104+
)
105+
106+
self.register_protocol(
107+
_cast(_Protocol, candidate), commandable
108+
)
109+
110+
# Handle bit fields.
111+
elif isinstance(item[0], int):
112+
fields = protocol.get_fields(item[0])
113+
for field in fields.fields.values():
114+
field.commandable = commandable
115+
# add sliders for non enum non bool (check enum fields too)
116+
self.add_fields(
117+
item[1],
118+
fields,
119+
commandable=commandable,
120+
controls=bit_slider(fields.raw.kind.bits, False),
121+
)
122+
32123
def search_names(
33124
self, pattern: str, exact: bool = False
34125
) -> _Iterator[str]:
35126
"""Search for names belonging to this environment."""
36127
yield from self.channels.names.search(pattern, exact=exact)
37128

38-
def set_default(self, key: str, default: _Default) -> None:
129+
def set_default(self, key: str, default: Default) -> None:
39130
"""Set a new default value for a channel."""
40131

41132
chan, _ = self[key]

runtimepy/channel/environment/create.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
from runtimepy.mapping import EnumMappingData as _EnumMappingData
2929
from runtimepy.primitives import ChannelScaling, Primitive
3030
from runtimepy.primitives import Primitivelike as _Primitivelike
31+
from runtimepy.primitives.field.fields import BitFields as _BitFields
3132
from runtimepy.registry.name import RegistryKey as _RegistryKey
3233

3334

@@ -74,10 +75,22 @@ def channel(
7475

7576
# Keep track of any new enum channels.
7677
if enum is not None:
77-
self.channel_enums[result] = self.enums[enum]
78+
runtime = self.enums[enum]
79+
self.channel_enums[result] = runtime
80+
if runtime.default:
81+
self[name] = runtime.default
7882

7983
return self[name]
8084

85+
def add_fields(
86+
self, name: str, fields: _BitFields, **channel_kwargs
87+
) -> None:
88+
"""Add bit fields to this channel environment."""
89+
90+
self.channel(name, kind=fields.raw, **channel_kwargs)
91+
with self.names_pushed(name):
92+
self.fields.add(fields, namespace=self._namespace, track=True)
93+
8194
def int_channel(
8295
self,
8396
name: str,
@@ -171,6 +184,7 @@ def enum(
171184
items: _EnumMappingData = None,
172185
namespace: _Namespace = None,
173186
primitive: str = DEFAULT_ENUM_PRIMITIVE,
187+
**kwargs,
174188
) -> _RuntimeEnum:
175189
"""Create a new enum from the environment."""
176190

@@ -179,6 +193,7 @@ def enum(
179193
kind=kind,
180194
items=items,
181195
primitive=primitive,
196+
**kwargs,
182197
)
183198
assert result is not None, f"Can't create enum '{name}'!"
184199
return result

runtimepy/channel/environment/sample.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ def sample_int_enum(
3333
"nine": 9,
3434
"ten": 10,
3535
},
36+
default="three",
3637
)
3738

3839

@@ -99,6 +100,7 @@ def sample_fields(env: ChannelEnvironment, enum: str = "SampleEnum") -> None:
99100
1,
100101
commandable=True,
101102
description="Sample bit flag.",
103+
default=True,
102104
)
103105
)
104106
env.add_field(
@@ -109,13 +111,19 @@ def sample_fields(env: ChannelEnvironment, enum: str = "SampleEnum") -> None:
109111
2,
110112
enum=enum if enum else None,
111113
commandable=True,
114+
default="three" if enum else 3,
112115
description="Sample bit field.",
113116
)
114117
)
115118
env.add_field(
116119
BitField(
117-
env.namespace(name="field2"), prim, 4, 4, commandable=True
118-
)
120+
env.namespace(name="field2"),
121+
prim,
122+
4,
123+
4,
124+
default=0,
125+
commandable=True,
126+
).set_slider()
119127
)
120128

121129

runtimepy/channel/registry.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
# internal
1717
from runtimepy.channel import AnyChannel as _AnyChannel
1818
from runtimepy.channel import Channel as _Channel
19-
from runtimepy.channel import Default as _Default
2019
from runtimepy.channel.event.header import PrimitiveEventHeader
2120
from runtimepy.codec.protocol import Protocol
2221
from runtimepy.mapping import DEFAULT_PATTERN
@@ -29,7 +28,7 @@
2928
from runtimepy.registry import Registry as _Registry
3029
from runtimepy.registry.name import NameRegistry as _NameRegistry
3130
from runtimepy.registry.name import RegistryKey as _RegistryKey
32-
from runtimepy.ui.controls import Controlslike, normalize_controls
31+
from runtimepy.ui.controls import Controlslike, Default, normalize_controls
3332

3433

3534
class ChannelNameRegistry(_NameRegistry):
@@ -92,7 +91,7 @@ def channel(
9291
enum: _RegistryKey = None,
9392
scaling: ChannelScaling = None,
9493
description: str = None,
95-
default: _Default = None,
94+
default: Default = None,
9695
controls: Controlslike = None,
9796
**kwargs,
9897
) -> _Optional[_AnyChannel]:

0 commit comments

Comments
 (0)