Unions are a C-reminiscense that are better avoided in modern C++.
They cause specific problems due to their nature of representing
independent types. The way they are used in Kaleidoscope, they
can easily be replaced by a class.
This enables it to properly work with Key objects in constexpr context
where with the old union-based implementation the compiler reported
errors when one Key was constructed based on a key_code/flags pair and
another one through raw-data. In such a case, the compiler assumes that
both Key instances represent something entirely different. This is
because unions were never meant for type conversions and the C++
standard considers their use for that purpose as undefined behavior.
The new class provides accessor methods for raw-data access and for
key_code/flags-data access.
This is a breaking change as it is is not possible to replace direct
member access patterns like
key.raw = 0xFFFF;
based on the raw-accessors.
For the .keyCode and .flags members, proxy objects are used
to enable the generation of suitable deprecations warnings.
All direct access via .raw, .keyCode and .flags have been replaced
throughout Kaleidoscope.
Information on how to upgrade is provided in UPGRADING.md
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
@ -156,6 +156,22 @@ The [FirmwareDump](doc/plugin/FirmwareDump.md) plugin makes it possible to dump
## Breaking changes
## Breaking changes
### Implementation of type Key internally changed from C++ union to class
Type `Key` was originally implemented as a C++ union. For technical reasons
it had to be converted to a C++ class. This implies that the double usage
of the original union, holding either raw data (member `raw`) or key code/key flags
data (members `keyCode` and `flags`) is no more possible.
Direct use of member `raw` will
emit a diagnostic compiler message but will cause the firmware linking
process to fail. For a deprecation
periode `keyCode` and `flags` keep on being supported but will cause
deprecation warnings during compile.
Please see the [relevant upgrade notes](UPGRADING.md##implementation-of-type-key-internally-changed-from-union-to-class)
for information about how to upgrade legacy code.
### The `NumPad` plugin no longer toggles `NumLock`
### The `NumPad` plugin no longer toggles `NumLock`
The `NumPad` plugin used to toggle `NumLock` when switching to the NumPad layer. This caused issues on OSX where `NumLock` is interpreted as `Clear`. For this reason, the plugin no longer does this. As a consequence, everyone's encouraged to update their keymap so that the numpad layer uses normal number keys instead of the keypad numbers. See [Model01-Firmware#79](https://github.com/keyboardio/Model01-Firmware/pull/79) for an example about how to do this.
The `NumPad` plugin used to toggle `NumLock` when switching to the NumPad layer. This caused issues on OSX where `NumLock` is interpreted as `Clear`. For this reason, the plugin no longer does this. As a consequence, everyone's encouraged to update their keymap so that the numpad layer uses normal number keys instead of the keypad numbers. See [Model01-Firmware#79](https://github.com/keyboardio/Model01-Firmware/pull/79) for an example about how to do this.
@ -12,6 +12,7 @@ If any of this does not make sense to you, or you have trouble updating your .in
- [Bidirectional communication for plugins](#bidirectional-communication-for-plugins)
- [Bidirectional communication for plugins](#bidirectional-communication-for-plugins)
- [Consistent timing](#consistent-timing)
- [Consistent timing](#consistent-timing)
+ [Breaking changes](#breaking-changes)
+ [Breaking changes](#breaking-changes)
- [Implementation of type Key internally changed from C++ union to class](#implementation-of-type-key-internally-changed-from-union-to-class)
- [The `RxCy` macros and peeking into the keyswitch state](#the-rxcy-macros-and-peeking-into-the-keyswitch-state)
- [The `RxCy` macros and peeking into the keyswitch state](#the-rxcy-macros-and-peeking-into-the-keyswitch-state)
- [HostOS](#hostos)
- [HostOS](#hostos)
- [MagicCombo](#magiccombo)
- [MagicCombo](#magiccombo)
@ -33,11 +34,11 @@ If any of this does not make sense to you, or you have trouble updating your .in
We are introducing - or rather, replacing - the older hardware plugins, with a system that's much more composable, more extensible, and will allow us to better support new devices, different MCUs, and so on.
We are introducing - or rather, replacing - the older hardware plugins, with a system that's much more composable, more extensible, and will allow us to better support new devices, different MCUs, and so on.
### For end-users
#### For end-users
For end users, this doesn't come with any breaking changes. A few things have been deprecated (`ROWS`, `COLS`, `LED_COUNT`, `KeyboardHardware`), but they still function for the time being.
For end users, this doesn't come with any breaking changes. A few things have been deprecated (`ROWS`, `COLS`, `LED_COUNT`, `KeyboardHardware`), but they still function for the time being.
### For developers
#### For developers
For those wishing to port Kaleidoscope to devices it doesn't support yet, the new API should make most things considerably easier. Please see the (work in progress) documentation in [doc/device-apis.md](doc/device-apis.md).
For those wishing to port Kaleidoscope to devices it doesn't support yet, the new API should make most things considerably easier. Please see the (work in progress) documentation in [doc/device-apis.md](doc/device-apis.md).
@ -313,6 +314,45 @@ As a developer, one can continue using `millis()`, but migrating to `Kaleidoscop
## Breaking changes
## Breaking changes
### Implementation of type Key internally changed from C++ union to class
#### For end-users
This is a breaking change only if your code accesses the member `raw` of
type `Key` directly, for instance in a construct like
```cpp
Key k;
k.raw = Key_A.raw;
```
This can easily be fixed by replacing read access to `Key::raw` with `Key::getRaw()`
and write access with `Key::setRaw(...)`.
```cpp
Key k;
k.setRaw(Key_A.getRaw());
```
Moreover, the compiler will still emit warnings in places of the code where
members `keyCode` and `flags` of the original type `Key` are used, like e.g.
```cpp
Key k;
k.keyCode = Key_A.keyCode;
k.flags = Key_A.flags;
```
These warnings can be also resolved by using the appropriate accessor methods
`Key::getKeyCode()`/`Key::setKeyCode()` and `Key::getFlags()`/`Key::setKlags()`
instead.
```cpp
Key k;
k.setKeyCode(Key_A.getKeyCode());
k.setFlags(Key_A.getFlags());
```
### The `RxCy` macros and peeking into the keyswitch state
### The `RxCy` macros and peeking into the keyswitch state
The `RxCy` macros changed from being indexes into a per-hand bitmap to being an
The `RxCy` macros changed from being indexes into a per-hand bitmap to being an