Use a timer instead of a loop counter

As loop counters are not a reliable substitute for timers, because they are
unreliable, use proper timers instead.

Fixes #3.

Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
pull/389/head
Gergely Nagy 8 years ago
parent cb732da530
commit db87474e16

@ -86,13 +86,13 @@ The plugin provides the `Leader` object, with the following methods:
### `.timeOut` ### `.timeOut`
> The number of loop iterations to wait before a sequence times out. Once the > The number of milliseconds to wait before a sequence times out. Once the
> sequence timed out, if there is a partial match with an action, that will be > sequence timed out, if there is a partial match with an action, that will be
> performed, otherwise the Leader sequence will simply reset. > performed, otherwise the Leader sequence will simply reset.
> >
> Not strictly a method, it is a variable one can assign a new value to. > Not strictly a method, it is a variable one can assign a new value to.
> >
> Defaults to 20. > Defaults to 1000.
## Further reading ## Further reading

@ -24,8 +24,8 @@ namespace Akela {
// --- state --- // --- state ---
Key Leader::sequence[LEADER_MAX_SEQUENCE_LENGTH + 1]; Key Leader::sequence[LEADER_MAX_SEQUENCE_LENGTH + 1];
uint8_t Leader::sequencePos; uint8_t Leader::sequencePos;
uint8_t Leader::timer; uint32_t Leader::startTime;
uint8_t Leader::timeOut = 20; uint16_t Leader::timeOut = 1000;
const Leader::dictionary_t *Leader::dictionary; const Leader::dictionary_t *Leader::dictionary;
// --- helpers --- // --- helpers ---
@ -89,7 +89,7 @@ namespace Akela {
void void
Leader::reset (void) { Leader::reset (void) {
timer = 0; startTime = 0;
sequencePos = 0; sequencePos = 0;
sequence[0].raw = Key_NoKey.raw; sequence[0].raw = Key_NoKey.raw;
} }
@ -119,6 +119,7 @@ namespace Akela {
if (key_toggled_off (keyState)) { if (key_toggled_off (keyState)) {
// not active, but a leader key = start the sequence on key release! // not active, but a leader key = start the sequence on key release!
startTime = millis ();
sequencePos = 0; sequencePos = 0;
sequence[sequencePos].raw = mappedKey.raw; sequence[sequencePos].raw = mappedKey.raw;
} }
@ -137,7 +138,7 @@ namespace Akela {
return mappedKey; return mappedKey;
} }
timer = 0; startTime = millis ();
sequence[sequencePos].raw = mappedKey.raw; sequence[sequencePos].raw = mappedKey.raw;
actionIndex = lookup (); actionIndex = lookup ();
@ -169,10 +170,7 @@ namespace Akela {
if (!isActive ()) if (!isActive ())
return; return;
if (timer < timeOut) if ((millis () - startTime) >= timeOut)
timer++;
if (timer >= timeOut)
reset (); reset ();
} }
}; };

@ -42,14 +42,14 @@ namespace Akela {
static void configure (const dictionary_t dictionary[]); static void configure (const dictionary_t dictionary[]);
static void reset (void); static void reset (void);
static uint8_t timeOut; static uint16_t timeOut;
void inject (Key key, uint8_t keyState); void inject (Key key, uint8_t keyState);
private: private:
static Key sequence[LEADER_MAX_SEQUENCE_LENGTH + 1]; static Key sequence[LEADER_MAX_SEQUENCE_LENGTH + 1];
static uint8_t sequencePos; static uint8_t sequencePos;
static uint8_t timer; static uint32_t startTime;
static const Leader::dictionary_t *dictionary; static const Leader::dictionary_t *dictionary;
static Key eventHandlerHook (Key mappedKey, byte row, byte col, uint8_t keyState); static Key eventHandlerHook (Key mappedKey, byte row, byte col, uint8_t keyState);

Loading…
Cancel
Save