Moving the deprecation messages to a separate header, and adding a few helpers
allow us to write much more detailed deprecation messages, without needlessly
making the code look incredibly messy.
This also updates most of the deprecation messages to be much more helpful, and
provide hints at how to fix the warnings produced by them.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Rearranged a little, so deprecation is a section, and we can put other things,
notes, into the document. With the rearrangement, added a section about the new
plugin API, and explained the API version bump too.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Due to the plugin API redesign, plugins that migrate may want to ensure they are
compiled against a recent enough Kaleidoscope. Others may opt to provide
separate implementations for each version. For this to work, we need to bump the
API version.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Fixed a conditional so that the event handlers of old-style plugins will be
called. Without this, they don't, and old-style plugins that install event
handlers, would not work.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
With this redesign, we introduce a new way to create plugins, which is easier to
extend with new hook points, provides a better interface, uses less memory, less
program space, and is a tiny bit faster too.
It all begins with `kaleidoscope::Plugin` being the base class, which provides
the hook methods plugins can implement. Plugins should be declared with
`KALEIDOSCOPE_INIT_PLUGINS` instead of `Kaleidoscope.use()`. Behind this macro
is a bit of magic (see the in-code documentation) that allows us to unroll the
hook method calls, avoid vtables, and so on. It creates an override for
`kaleidoscope::Hooks::*` methods, each of which will call the respective methods
of each initialized plugin.
With the new API come new names: all of the methods plugins can implement
received new, more descriptive names that all follow a similar pattern.
The old (dubbed V1) API still remains in place, although deprecated. One can
turn it off by setting the `KALEIDOSCOPE_ENABLE_V1_PLUGIN_API` define to zero,
while compiling the firmware.
This work is based on #276, written by @noseglasses. @obra and @algernon did
some cleaning up and applied a little naming treatment.
Signed-off-by: noseglasses <shinynoseglasses@gmail.com>
Signed-off-by: Jesse Vincent <jesse@keyboard.io>
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
This can be used to see the effect of changes on the core firmware alone,
without any plugins or the like.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Use a timeout calculation method that is not affected by overflow, and also
requires 16 bits less.
This likely fixes#8.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Ticks depend on the speed of the main loop, and as such, are not a reliable way
to time animations. For this reason, use proper timers instead.
The update delay is set to 40ms, which appears to be a slow, relaxing animation,
and should be roughly in the ballpark the tick-based timing was, before speeding
up the main loop considerably.
Fixes#3.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Based on #306, with slightly improved text. Thanks to Ross Donaldson
(@Gastove) for the original pull request!
Closes#306.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
With the previous algorithm, once every 65 seconds, there would be a significant jump in
the brightness of the "breathing" LEDs as the 16-bit value recorded from `millis()`
overflowed. Instead of dividing by 12, I changed it to a bit shift (4 bits; equivalent to
division by 16), so when the integer overflow occurs, the next value is what it should be.
This is a somewhat unwieldy fix for all the out of bounds (attempted) array addressing at
both ends. When `pos` goes out of bounds in either direction, the test is the same because
it's an unsigned integer. However, after the change of direction, the trailing LED will
still be out of bounds, so we check that every time we call `setCrgbAt()` for `pos2`.
It's rather ugly, but it does ensure that we don't call `setCrgbAt()` with an
out-of-bounds address.
This prevents an insignificant error, but it is more correct to handle the integer
overflow instead of ignoring it. I've also changed syncTimer from a 32-bit to 16-bit
integer, which results in a smaller code size, and changed the computation of the timeout
slightly, so the LED update interval is always the same (we add `syncDelay` to the
previous update's start time, not it's end time), rather than varying based on when
LEDControl's `loopHook()` function is called relative to the last timeout.
There already exist 2 rainbow LED effects, this adds a third, using
the LED-Stalker effect.
When you press a key, the LED on that key will cycle through all the
colors of the rainbow, independent of the colors of other keys.
We no longer have a `KaleidoscopePlugins` namespace, and have to use
`kaleidoscope` instead - lets do that.
Noticed by Jordihs on the Keyboardio forums, thank you!
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Since keyboardio/Kaleidoscope-Hardware-Model01#23 we do not call
`handleKeyswitchEvent` for keys that are idle. Document this in the comments.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
When a keyswitch has been off in the previous cycle and is still off now, do not
call `handleKeyswitchEvent` on it. As an extension, when the whole column is
idle, skip the whole thing.
In practice, handling fully idle keys is not useful. There are many plugins
which explicitly look for this case and return early, because it isn't an
interesting event. As such, not calling the event handler in this case makes
sense, as we save not only a few needless checks in plugins, but our performance
improves greatly too.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
In `actOnMatrixScan`, there is no need to use temporary variables, we can just
pass the data directly to `actOnHalfRow`, and doing so makes the code easier to
follow.
In `actOnHalfRow`, we can further optimize things if instead of reading the Nth
bit, we always read the first, and shift the byte at the end.
All of these optimizations were done by @obra, I just wrote the commit message.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
When there are no state changes, and no keys pressed on a row, instead of
iterating through a byte bit-by-bit, just fire idle events without checking the
bits. In all other cases, do the bit-walking like we did before.
The reason this is useful is because bit-walking is costly, and slow. If we can
avoid that, we win quite a lot of performance. Since rows being idle is the most
common case on a keyboard, this is a huge net win. Even in the worst case, where
no rows are idle, this is just one byte comparison and a branch slower than our
previous implementation.
As part of this optimization, `actOnHalfRow` was lifted out into its own
function, to reduce code duplication.
Many thanks to @gedankenexperimenter for the original idea!
Signed-off-by: Gergely Nagy <algernon@keyboard.io>