Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Macros: Rebuild with a completely different architecture #1094

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,33 +25,6 @@ namespace plugin {
uint16_t DynamicMacros::storage_base_;
uint16_t DynamicMacros::storage_size_;
uint16_t DynamicMacros::map_[];
Key DynamicMacros::active_macro_keys_[];

// =============================================================================
// It might be possible to use Macros instead of reproducing it
void DynamicMacros::press(Key key) {
Runtime.handleKeyEvent(KeyEvent(KeyAddr::none(), IS_PRESSED | INJECTED, key));
for (Key &mkey : active_macro_keys_) {
if (mkey == Key_NoKey) {
mkey = key;
break;
}
}
}

void DynamicMacros::release(Key key) {
for (Key &mkey : active_macro_keys_) {
if (mkey == key) {
mkey = Key_NoKey;
}
}
Runtime.handleKeyEvent(KeyEvent(KeyAddr::none(), WAS_PRESSED | INJECTED, key));
}

void DynamicMacros::tap(Key key) {
Runtime.handleKeyEvent(KeyEvent(KeyAddr::none(), IS_PRESSED | INJECTED, key));
Runtime.handleKeyEvent(KeyEvent(KeyAddr::none(), WAS_PRESSED | INJECTED, key));
}

void DynamicMacros::updateDynamicMacroCache() {
uint16_t pos = storage_base_;
Expand Down Expand Up @@ -118,92 +91,29 @@ void DynamicMacros::updateDynamicMacroCache() {
}

// public
void DynamicMacros::play(uint8_t macro_id) {
macro_t macro = MACRO_ACTION_END;
uint8_t interval = 0;
uint16_t pos;
Key key;

pos = storage_base_ + map_[macro_id];
void DynamicMacros::setup(uint16_t storage_size) {
Macros::readMacroByte = &DynamicMacros::readMacroByte;

while (true) {
switch (macro = Runtime.storage().read(pos++)) {
case MACRO_ACTION_STEP_EXPLICIT_REPORT:
case MACRO_ACTION_STEP_IMPLICIT_REPORT:
case MACRO_ACTION_STEP_SEND_REPORT:
break;

case MACRO_ACTION_STEP_INTERVAL:
interval = Runtime.storage().read(pos++);
break;
case MACRO_ACTION_STEP_WAIT: {
uint8_t wait = Runtime.storage().read(pos++);
delay(wait);
break;
}

case MACRO_ACTION_STEP_KEYDOWN:
key.setFlags(Runtime.storage().read(pos++));
key.setKeyCode(Runtime.storage().read(pos++));
press(key);
break;
case MACRO_ACTION_STEP_KEYUP:
key.setFlags(Runtime.storage().read(pos++));
key.setKeyCode(Runtime.storage().read(pos++));
release(key);
break;
case MACRO_ACTION_STEP_TAP:
key.setFlags(Runtime.storage().read(pos++));
key.setKeyCode(Runtime.storage().read(pos++));
tap(key);
break;
reserve_storage(storage_size);
}

case MACRO_ACTION_STEP_KEYCODEDOWN:
key.setFlags(0);
key.setKeyCode(Runtime.storage().read(pos++));
press(key);
break;
case MACRO_ACTION_STEP_KEYCODEUP:
key.setFlags(0);
key.setKeyCode(Runtime.storage().read(pos++));
release(key);
break;
case MACRO_ACTION_STEP_TAPCODE:
key.setFlags(0);
key.setKeyCode(Runtime.storage().read(pos++));
tap(key);
break;
uint8_t DynamicMacros::readMacroByteFromEEPROM(const macro_t *ptr, uint8_t source) {
int idx = (int)*(ptr++);
return Runtime.storage().read(idx);
}

case MACRO_ACTION_STEP_TAP_SEQUENCE: {
while (true) {
key.setFlags(0);
key.setKeyCode(pgm_read_byte(pos++));
if (key == Key_NoKey)
break;
tap(key);
delay(interval);
}
break;
}
case MACRO_ACTION_STEP_TAP_CODE_SEQUENCE: {
while (true) {
key.setFlags(0);
key.setKeyCode(pgm_read_byte(pos++));
if (key.getKeyCode() == 0)
break;
tap(key);
delay(interval);
}
break;
}
uint8_t DynamicMacros::readMacroByte(const macro_t *ptr, uint8_t source) {
if (source == MACRO_SOURCE_PROGMEM) {
return Macros::readMacroByteFromPROGMEM(ptr, source);
} else {
return readMacroByteFromEEPROM(ptr, source);
}
}

case MACRO_ACTION_END:
default:
return;
}
void DynamicMacros::play(uint8_t macro_id) {
uint16_t pos = storage_base_ + map_[macro_id];

delay(interval);
}
::Macros.play((const macro_t *)&pos, MACRO_SOURCE_EEPROM);
}

bool isDynamicMacrosKey(Key key) {
Expand All @@ -220,9 +130,7 @@ EventHandlerResult DynamicMacros::onKeyEvent(KeyEvent &event) {
uint8_t macro_id = event.key.getRaw() - ranges::DYNAMIC_MACRO_FIRST;
play(macro_id);
} else {
for (Key key : active_macro_keys_) {
release(key);
}
::Macros.release(event.key);
}

return EventHandlerResult::EVENT_CONSUMED;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,11 @@

#include "kaleidoscope/Runtime.h"
#include <Kaleidoscope-EEPROM-Settings.h>
#include <Kaleidoscope-Macros.h>
#include <Kaleidoscope-Ranges.h>

#include "kaleidoscope/plugin/Macros/MacroSteps.h"

#define DM(n) Key(kaleidoscope::ranges::DYNAMIC_MACRO_FIRST + n)

#define MAX_CONCURRENT_DYNAMIC_MACRO_KEYS 8
#define MACRO_SOURCE_EEPROM 1

namespace kaleidoscope {
namespace plugin {
Expand All @@ -36,18 +34,18 @@ class DynamicMacros : public kaleidoscope::Plugin {
EventHandlerResult onFocusEvent(const char *command);

static void reserve_storage(uint16_t size);
static void setup(uint16_t storage_size);

void play(uint8_t seq_id);

static uint8_t readMacroByteFromEEPROM(const macro_t *ptr, uint8_t source);
static uint8_t readMacroByte(const macro_t *ptr, uint8_t source);

private:
static uint16_t storage_base_;
static uint16_t storage_size_;
static uint16_t map_[31];
static void updateDynamicMacroCache();
static Key active_macro_keys_[MAX_CONCURRENT_DYNAMIC_MACRO_KEYS];
static void press(Key key);
static void release(Key key);
static void tap(Key key);
};

} // namespace plugin
Expand Down
31 changes: 16 additions & 15 deletions plugins/Kaleidoscope-Macros/src/kaleidoscope/plugin/Macros.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ constexpr uint8_t release_state = WAS_PRESSED | INJECTED;

// Initialized to zeroes (i.e. `Key_NoKey`)
Key Macros::active_macro_keys_[];
Macros::readMacroByteFunction Macros::readMacroByte = &Macros::readMacroByteFromPROGMEM;

#ifndef NDEPRECATED
#pragma GCC diagnostic push
Expand Down Expand Up @@ -106,7 +107,7 @@ void Macros::tap(Key key) const {
Runtime.handleKeyEvent(KeyEvent{KeyAddr::none(), release_state, key});
}

void Macros::play(const macro_t *macro_p) {
void Macros::play(const macro_t *macro_p, uint8_t source) {
macro_t macro = MACRO_ACTION_END;
uint8_t interval = 0;
Key key;
Expand All @@ -115,7 +116,7 @@ void Macros::play(const macro_t *macro_p) {
return;

while (true) {
switch (macro = pgm_read_byte(macro_p++)) {
switch (macro = readMacroByte(macro_p, source)) {
// These are unlikely to be useful now that we have KeyEvent. I think the
// whole `explicit_report` came about as a result of scan-order bugs.
case MACRO_ACTION_STEP_EXPLICIT_REPORT:
Expand All @@ -126,50 +127,50 @@ void Macros::play(const macro_t *macro_p) {

// Timing
case MACRO_ACTION_STEP_INTERVAL:
interval = pgm_read_byte(macro_p++);
interval = readMacroByte(macro_p, source);
break;
case MACRO_ACTION_STEP_WAIT: {
uint8_t wait = pgm_read_byte(macro_p++);
uint8_t wait = readMacroByte(macro_p, source);
delay(wait);
break;
}

case MACRO_ACTION_STEP_KEYDOWN:
key.setFlags(pgm_read_byte(macro_p++));
key.setKeyCode(pgm_read_byte(macro_p++));
key.setFlags(readMacroByte(macro_p, source));
key.setKeyCode(readMacroByte(macro_p, source));
press(key);
break;
case MACRO_ACTION_STEP_KEYUP:
key.setFlags(pgm_read_byte(macro_p++));
key.setKeyCode(pgm_read_byte(macro_p++));
key.setFlags(readMacroByte(macro_p, source));
key.setKeyCode(readMacroByte(macro_p, source));
release(key);
break;
case MACRO_ACTION_STEP_TAP:
key.setFlags(pgm_read_byte(macro_p++));
key.setKeyCode(pgm_read_byte(macro_p++));
key.setFlags(readMacroByte(macro_p, source));
key.setKeyCode(readMacroByte(macro_p, source));
tap(key);
break;

case MACRO_ACTION_STEP_KEYCODEDOWN:
key.setFlags(0);
key.setKeyCode(pgm_read_byte(macro_p++));
key.setKeyCode(readMacroByte(macro_p, source));
press(key);
break;
case MACRO_ACTION_STEP_KEYCODEUP:
key.setFlags(0);
key.setKeyCode(pgm_read_byte(macro_p++));
key.setKeyCode(readMacroByte(macro_p, source));
release(key);
break;
case MACRO_ACTION_STEP_TAPCODE:
key.setFlags(0);
key.setKeyCode(pgm_read_byte(macro_p++));
key.setKeyCode(readMacroByte(macro_p, source));
tap(key);
break;

case MACRO_ACTION_STEP_TAP_SEQUENCE: {
while (true) {
key.setFlags(0);
key.setKeyCode(pgm_read_byte(macro_p++));
key.setKeyCode(readMacroByte(macro_p, source));
if (key == Key_NoKey)
break;
tap(key);
Expand All @@ -180,7 +181,7 @@ void Macros::play(const macro_t *macro_p) {
case MACRO_ACTION_STEP_TAP_CODE_SEQUENCE: {
while (true) {
key.setFlags(0);
key.setKeyCode(pgm_read_byte(macro_p++));
key.setKeyCode(readMacroByte(macro_p, source));
if (key.getKeyCode() == 0)
break;
tap(key);
Expand Down
11 changes: 10 additions & 1 deletion plugins/Kaleidoscope-Macros/src/kaleidoscope/plugin/Macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ struct MacroKeyEvent {
#define MAX_CONCURRENT_MACRO_KEYS 8
#endif

#define MACRO_SOURCE_PROGMEM 0

namespace kaleidoscope {
namespace plugin {

Expand Down Expand Up @@ -126,7 +128,14 @@ class Macros : public kaleidoscope::Plugin {
void tap(Key key) const;

/// Play a macro sequence of key events
void play(const macro_t* macro_ptr);
void play(const macro_t* macro_ptr, uint8_t source = MACRO_SOURCE_PROGMEM);

typedef uint8_t (*readMacroByteFunction)(const macro_t *ptr, uint8_t source);
static readMacroByteFunction readMacroByte;

static uint8_t readMacroByteFromPROGMEM(const macro_t *ptr, uint8_t source) {
return pgm_read_byte(ptr++);
}

// Templates provide a `type()` function that takes a variable number of
// `char*` (string) arguments, in the form of a list of strings stored in
Expand Down