-
-
Notifications
You must be signed in to change notification settings - Fork 7
Description
In the existing hardware data classes, Keyboard is more accurately MaybeKeyboard, because it is the base class for Board and Shield, either of which could be the main PCB for a keyboard or just one component of one.
To better model the function of each piece of hardware, we should refactor the classes to something like this:
classDiagram
Hardware <|-- Interconnect
Hardware <|-- KeyboardComponent
KeyboardComponent <|-- Board
KeyboardComponent <|-- Shield
Keyboard *-- Board
Keyboard *-- Shield
class Hardware {
+str type
+str id
+str name
+str|None file_format
+str|None url
+str|None description
+str|None manufacturer
+str|None version
$from_dict(data)
}
class KeyboardComponent {
+list[str] siblings
+list[str] exposes
+list[Feature] features
+list[Variant] variants
+bool has_keys()
}
class Board {
+str|None arch
+list[Output] outputs
+list[str] revisions
+str|None default_revision
}
class Shield {
+list[str] requires
}
class Interconnect {
+dict[str, str] node_labels
+str|None design_guideline
}
note for Keyboard "get_build_items() returns
one item per combination
of board/shield siblings,
with revision+qualifiers, e.g.
- board=foo
- shield=bar,baz
- board_revision=2
- board_qualifiers=a,b
with bar having siblings
returns:
- 'foo@2/a/b', 'bar_left baz'
- 'foo@2/a/b', 'bar_right baz'"
note for Keyboard "is_complete is true when
board is set and at least
one item in boards/shields
has the 'keys' feature."
class Keyboard {
+Board|None board
+list[Shield] shields
+Board|Shield|None keys_component
+str|None board_revision
+list[str] board_qualifiers
+bool is_complete
+list[str] exposes
+list[str] requires
+bool requirements_satisfied
+list[Revision] revisions
+Revision|None default_revision
+list[BuildItem] get_build_items()
}
class Revision {
+constructor(value)
+str str()
}
class BuildItem {
+str board
+str|None shield
+str|None snippet
+str|None cmake_args
+str|None artifact_name
}
Keyboard -- BuildItem
Keyboard -- Revision
Hardware remains the base class for all hardware descriptions, and Interconnect remains a class that describes a hardware interface but not a specific component of a keyboard. The base class of Board and Shield is renamed to KeyboardComponent, which gets a new has_keys() helper function to differentiate between keyboard and controller boards and between keyboard and peripheral shields.
A new Keyboard class then represents the combination of a Board with zero or more Shields to form a keyboard. The zmk keyboard add command can then create a Keyboard instance and progressively populate it instead of having local variables for each of keyboard, controller, and revision.
The following properties on Keyboard would be computed from the board and shields fields:
keys_component- The first item out of[board, *shields]which has the "keys" feature, orNoneis_complete- True if the keyboard has aboardand akeys_componentexposes- Set of allexposesvalues in[board, *shields]requires- Set of allrequiresvalues inshieldsrequirements_satisfied- True if all values inrequiresare present inexposes(some interconnects may support different numbers of peripherals attached to them, but that would be very difficult to model properly, and it probably wouldn't be that useful information anyways)revisions- Pass through toboard.revisionswith values wrapped inRevisionclass. Empty list if board not set.default_revision- Pass through toboard.default_revisionwith value wrapped inRevisionclass. None if board not set or board has no default revision.
Keyboard.get_build_items() will return a separate BuildItem for every combination of siblings defined for each of the boards and shields. This will replace _get_build_items() from add.py.
A new Revision class can be added to simplify comparing revisions with different formats. For example, Revision("2") should compare equal to Revision("2.0.0"). This would allow for things like revision in keyboard.revisions without needing to manually normalize all the revision strings first.