Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit be2dc89

Browse files
committed
refactor(core): Move to stack allocated events.
* Move to local/stack allocated event API that doesn't require dynamic allocation/freeing. * Disable heap, we no longer use alloc/free unless using LVGL. * Tons of refactors all over to account for the new event approach.
1 parent bf11219 commit be2dc89

21 files changed

Lines changed: 155 additions & 129 deletions

app/include/zmk/event_manager.h

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,21 +38,24 @@ struct zmk_event_subscription {
3838
zmk_event_t header; \
3939
struct event_type data; \
4040
}; \
41-
struct event_type##_event *new_##event_type(struct event_type); \
41+
struct event_type##_event new_##event_type(struct event_type); \
42+
int raise_new_##event_type(struct event_type); \
4243
struct event_type *as_##event_type(const zmk_event_t *eh); \
4344
extern const struct zmk_event_type zmk_event_##event_type;
4445

4546
#define ZMK_EVENT_IMPL(event_type) \
4647
const struct zmk_event_type zmk_event_##event_type = {.name = STRINGIFY(event_type)}; \
4748
const struct zmk_event_type *zmk_event_ref_##event_type __used \
4849
__attribute__((__section__(".event_type"))) = &zmk_event_##event_type; \
49-
struct event_type##_event *new_##event_type(struct event_type data) { \
50-
struct event_type##_event *ev = \
51-
(struct event_type##_event *)k_malloc(sizeof(struct event_type##_event)); \
52-
ev->header.event = &zmk_event_##event_type; \
53-
ev->data = data; \
50+
struct event_type##_event new_##event_type(struct event_type data) { \
51+
struct event_type##_event ev = {.data = data}; \
52+
ev.header.event = &zmk_event_##event_type; \
5453
return ev; \
5554
}; \
55+
int raise_new_##event_type(struct event_type data) { \
56+
struct event_type##_event ev = new_##event_type(data); \
57+
return ZMK_EVENT_RAISE(ev); \
58+
}; \
5659
struct event_type *as_##event_type(const zmk_event_t *eh) { \
5760
return (eh->event == &zmk_event_##event_type) ? &((struct event_type##_event *)eh)->data \
5861
: NULL; \
@@ -68,17 +71,15 @@ struct zmk_event_subscription {
6871
.listener = &zmk_listener_##mod, \
6972
};
7073

71-
#define ZMK_EVENT_RAISE(ev) zmk_event_manager_raise((zmk_event_t *)ev);
74+
#define ZMK_EVENT_RAISE(ev) zmk_event_manager_raise((zmk_event_t *)&ev);
7275

7376
#define ZMK_EVENT_RAISE_AFTER(ev, mod) \
74-
zmk_event_manager_raise_after((zmk_event_t *)ev, &zmk_listener_##mod);
77+
zmk_event_manager_raise_after((zmk_event_t *)&ev, &zmk_listener_##mod);
7578

7679
#define ZMK_EVENT_RAISE_AT(ev, mod) \
77-
zmk_event_manager_raise_at((zmk_event_t *)ev, &zmk_listener_##mod);
78-
79-
#define ZMK_EVENT_RELEASE(ev) zmk_event_manager_release((zmk_event_t *)ev);
80+
zmk_event_manager_raise_at((zmk_event_t *)&ev, &zmk_listener_##mod);
8081

81-
#define ZMK_EVENT_FREE(ev) k_free((void *)ev);
82+
#define ZMK_EVENT_RELEASE(ev) zmk_event_manager_release((zmk_event_t *)&ev);
8283

8384
int zmk_event_manager_raise(zmk_event_t *event);
8485
int zmk_event_manager_raise_after(zmk_event_t *event, const struct zmk_listener *listener);

app/include/zmk/events/keycode_state_changed.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ struct zmk_keycode_state_changed {
2121

2222
ZMK_EVENT_DECLARE(zmk_keycode_state_changed);
2323

24-
static inline struct zmk_keycode_state_changed_event *
24+
static inline struct zmk_keycode_state_changed_event
2525
zmk_keycode_state_changed_from_encoded(uint32_t encoded, bool pressed, int64_t timestamp) {
2626
uint16_t page = ZMK_HID_USAGE_PAGE(encoded);
2727
uint16_t id = ZMK_HID_USAGE_ID(encoded);

app/include/zmk/events/layer_state_changed.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ struct zmk_layer_state_changed {
1717

1818
ZMK_EVENT_DECLARE(zmk_layer_state_changed);
1919

20-
static inline struct zmk_layer_state_changed_event *create_layer_state_changed(uint8_t layer,
21-
bool state) {
20+
static inline struct zmk_layer_state_changed_event create_layer_state_changed(uint8_t layer,
21+
bool state) {
2222
return new_zmk_layer_state_changed((struct zmk_layer_state_changed){
2323
.layer = layer, .state = state, .timestamp = k_uptime_get()});
2424
}

app/src/activity.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ static uint32_t activity_last_uptime;
4343
#endif
4444

4545
int raise_event() {
46-
return ZMK_EVENT_RAISE(new_zmk_activity_state_changed(
47-
(struct zmk_activity_state_changed){.state = activity_state}));
46+
return raise_new_zmk_activity_state_changed(
47+
(struct zmk_activity_state_changed){.state = activity_state});
4848
}
4949

5050
int set_state(enum zmk_activity_state state) {

app/src/battery.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ static int zmk_battery_update(const struct device *battery) {
6060
return rc;
6161
}
6262

63-
rc = ZMK_EVENT_RAISE(new_zmk_battery_state_changed(
64-
(struct zmk_battery_state_changed){.state_of_charge = last_state_of_charge}));
63+
rc = raise_new_zmk_battery_state_changed(
64+
(struct zmk_battery_state_changed){.state_of_charge = last_state_of_charge});
6565
}
6666

6767
return rc;

app/src/behaviors/behavior_hold_tap.c

Lines changed: 59 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,24 @@ struct active_hold_tap {
8888
struct active_hold_tap *undecided_hold_tap = NULL;
8989
struct active_hold_tap active_hold_taps[ZMK_BHV_HOLD_TAP_MAX_HELD] = {};
9090
// We capture most position_state_changed events and some modifiers_state_changed events.
91-
const zmk_event_t *captured_events[ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS] = {};
91+
92+
enum captured_event_tag {
93+
ET_NONE,
94+
ET_POS_CHANGED,
95+
ET_CODE_CHANGED,
96+
};
97+
98+
union captured_event_data {
99+
struct zmk_position_state_changed_event position;
100+
struct zmk_keycode_state_changed_event keycode;
101+
};
102+
103+
struct captured_event {
104+
enum captured_event_tag tag;
105+
union captured_event_data data;
106+
};
107+
108+
struct captured_event captured_events[ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS] = {};
92109

93110
// Keep track of which key was tapped most recently for the standard, if it is a hold-tap
94111
// a position, will be given, if not it will just be INT32_MIN
@@ -119,33 +136,32 @@ static bool is_quick_tap(struct active_hold_tap *hold_tap) {
119136
}
120137
}
121138

122-
static int capture_event(const zmk_event_t *event) {
139+
static int capture_event(struct captured_event data) {
123140
for (int i = 0; i < ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS; i++) {
124-
if (captured_events[i] == NULL) {
125-
captured_events[i] = event;
141+
if (captured_events[i].tag == ET_NONE) {
142+
memcpy(&captured_events[i], &data, sizeof(struct captured_event));
126143
return 0;
127144
}
128145
}
129146
return -ENOMEM;
130147
}
131148

132-
static struct zmk_position_state_changed *find_captured_keydown_event(uint32_t position) {
133-
struct zmk_position_state_changed *last_match = NULL;
149+
static bool have_captured_keydown_event(uint32_t position) {
134150
for (int i = 0; i < ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS; i++) {
135-
const zmk_event_t *eh = captured_events[i];
136-
if (eh == NULL) {
137-
return last_match;
151+
struct captured_event ev = captured_events[i];
152+
if (ev.tag == ET_NONE) {
153+
return false;
138154
}
139-
struct zmk_position_state_changed *position_event = as_zmk_position_state_changed(eh);
140-
if (position_event == NULL) {
155+
156+
if (ev.tag != ET_POS_CHANGED) {
141157
continue;
142158
}
143159

144-
if (position_event->position == position && position_event->state) {
145-
last_match = position_event;
160+
if (ev.data.position.data.position == position && ev.data.position.data.state) {
161+
return true;
146162
}
147163
}
148-
return last_match;
164+
return false;
149165
}
150166

151167
const struct zmk_listener zmk_listener_behavior_hold_tap;
@@ -181,25 +197,33 @@ static void release_captured_events() {
181197
// [k1_down, k1_up, null, null, null, ...]
182198
// now mt2 will start releasing it's own captured positions.
183199
for (int i = 0; i < ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS; i++) {
184-
const zmk_event_t *captured_event = captured_events[i];
185-
if (captured_event == NULL) {
200+
struct captured_event captured_event = captured_events[i];
201+
if (captured_event.tag == ET_NONE) {
186202
return;
187203
}
188-
captured_events[i] = NULL;
204+
205+
captured_events[i].tag = ET_NONE;
189206
if (undecided_hold_tap != NULL) {
190207
k_msleep(10);
191208
}
192209

193-
struct zmk_position_state_changed *position_event;
194-
struct zmk_keycode_state_changed *modifier_event;
195-
if ((position_event = as_zmk_position_state_changed(captured_event)) != NULL) {
196-
LOG_DBG("Releasing key position event for position %d %s", position_event->position,
197-
(position_event->state ? "pressed" : "released"));
198-
} else if ((modifier_event = as_zmk_keycode_state_changed(captured_event)) != NULL) {
199-
LOG_DBG("Releasing mods changed event 0x%02X %s", modifier_event->keycode,
200-
(modifier_event->state ? "pressed" : "released"));
210+
switch (captured_event.tag) {
211+
case ET_CODE_CHANGED:
212+
LOG_DBG("Releasing mods changed event 0x%02X %s",
213+
captured_event.data.keycode.data.keycode,
214+
(captured_event.data.keycode.data.state ? "pressed" : "released"));
215+
ZMK_EVENT_RAISE_AT(captured_event.data.keycode, behavior_hold_tap);
216+
break;
217+
case ET_POS_CHANGED:
218+
LOG_DBG("Releasing key position event for position %d %s",
219+
captured_event.data.position.data.position,
220+
(captured_event.data.position.data.state ? "pressed" : "released"));
221+
ZMK_EVENT_RAISE_AT(captured_event.data.position, behavior_hold_tap);
222+
break;
223+
default:
224+
LOG_ERR("Unhandled captured event type");
225+
break;
201226
}
202-
ZMK_EVENT_RAISE_AT(captured_event, behavior_hold_tap);
203227
}
204228
}
205229

@@ -619,7 +643,7 @@ static int position_state_changed_listener(const zmk_event_t *eh) {
619643
return ZMK_EV_EVENT_BUBBLE;
620644
}
621645

622-
if (!ev->state && find_captured_keydown_event(ev->position) == NULL) {
646+
if (!ev->state && !have_captured_keydown_event(ev->position)) {
623647
// no keydown event has been captured, let it bubble.
624648
// we'll catch modifiers later in modifier_state_changed_listener
625649
LOG_DBG("%d bubbling %d %s event", undecided_hold_tap->position, ev->position,
@@ -629,7 +653,10 @@ static int position_state_changed_listener(const zmk_event_t *eh) {
629653

630654
LOG_DBG("%d capturing %d %s event", undecided_hold_tap->position, ev->position,
631655
ev->state ? "down" : "up");
632-
capture_event(eh);
656+
struct captured_event capture;
657+
capture.tag = ET_POS_CHANGED;
658+
memcpy(&capture.data.position, eh, sizeof(struct zmk_position_state_changed_event));
659+
capture_event(capture);
633660
decide_hold_tap(undecided_hold_tap, ev->state ? HT_OTHER_KEY_DOWN : HT_OTHER_KEY_UP);
634661
return ZMK_EV_EVENT_CAPTURED;
635662
}
@@ -656,7 +683,10 @@ static int keycode_state_changed_listener(const zmk_event_t *eh) {
656683
// if a undecided_hold_tap is active.
657684
LOG_DBG("%d capturing 0x%02X %s event", undecided_hold_tap->position, ev->keycode,
658685
ev->state ? "down" : "up");
659-
capture_event(eh);
686+
struct captured_event capture;
687+
capture.tag = ET_CODE_CHANGED;
688+
memcpy(&capture.data.keycode, eh, sizeof(struct zmk_keycode_state_changed_event));
689+
capture_event(capture);
660690
return ZMK_EV_EVENT_CAPTURED;
661691
}
662692

app/src/behaviors/behavior_key_press.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,17 @@ static int behavior_key_press_init(const struct device *dev) { return 0; };
2121
static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
2222
struct zmk_behavior_binding_event event) {
2323
LOG_DBG("position %d keycode 0x%02X", event.position, binding->param1);
24-
return ZMK_EVENT_RAISE(
25-
zmk_keycode_state_changed_from_encoded(binding->param1, true, event.timestamp));
24+
struct zmk_keycode_state_changed_event ev =
25+
zmk_keycode_state_changed_from_encoded(binding->param1, true, event.timestamp);
26+
return ZMK_EVENT_RAISE(ev);
2627
}
2728

2829
static int on_keymap_binding_released(struct zmk_behavior_binding *binding,
2930
struct zmk_behavior_binding_event event) {
3031
LOG_DBG("position %d keycode 0x%02X", event.position, binding->param1);
31-
return ZMK_EVENT_RAISE(
32-
zmk_keycode_state_changed_from_encoded(binding->param1, false, event.timestamp));
32+
struct zmk_keycode_state_changed_event ev =
33+
zmk_keycode_state_changed_from_encoded(binding->param1, false, event.timestamp);
34+
return ZMK_EVENT_RAISE(ev);
3335
}
3436

3537
static const struct behavior_driver_api behavior_key_press_driver_api = {

app/src/behaviors/behavior_key_repeat.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ static int on_key_repeat_binding_pressed(struct zmk_behavior_binding *binding,
4343
sizeof(struct zmk_keycode_state_changed));
4444
data->current_keycode_pressed.timestamp = k_uptime_get();
4545

46-
ZMK_EVENT_RAISE(new_zmk_keycode_state_changed(data->current_keycode_pressed));
46+
raise_new_zmk_keycode_state_changed(data->current_keycode_pressed);
4747

4848
return ZMK_BEHAVIOR_OPAQUE;
4949
}
@@ -60,7 +60,7 @@ static int on_key_repeat_binding_released(struct zmk_behavior_binding *binding,
6060
data->current_keycode_pressed.timestamp = k_uptime_get();
6161
data->current_keycode_pressed.state = false;
6262

63-
ZMK_EVENT_RAISE(new_zmk_keycode_state_changed(data->current_keycode_pressed));
63+
raise_new_zmk_keycode_state_changed(data->current_keycode_pressed);
6464
return ZMK_BEHAVIOR_OPAQUE;
6565
}
6666

app/src/behaviors/behavior_key_toggle.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
2323
struct zmk_behavior_binding_event event) {
2424
LOG_DBG("position %d keycode 0x%02X", event.position, binding->param1);
2525
bool pressed = zmk_hid_is_pressed(binding->param1);
26-
return ZMK_EVENT_RAISE(
27-
zmk_keycode_state_changed_from_encoded(binding->param1, !pressed, event.timestamp));
26+
return raise_zmk_keycode_state_changed_from_encoded(binding->param1, !pressed, event.timestamp);
2827
}
2928

3029
static int on_keymap_binding_released(struct zmk_behavior_binding *binding,

app/src/behaviors/behavior_sticky_key.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,9 @@ static int sticky_key_keycode_state_changed_listener(const zmk_event_t *eh) {
228228
if (sticky_key->config->quick_release) {
229229
// immediately release the sticky key after the key press is handled.
230230
if (!event_reraised) {
231-
ZMK_EVENT_RAISE_AFTER(eh, behavior_sticky_key);
231+
struct zmk_keycode_state_changed_event dupe_ev;
232+
memcpy(&dupe_ev, eh, sizeof(struct zmk_keycode_state_changed_event));
233+
ZMK_EVENT_RAISE_AFTER(dupe_ev, behavior_sticky_key);
232234
event_reraised = true;
233235
}
234236
release_sticky_key_behavior(sticky_key, ev->timestamp);

0 commit comments

Comments
 (0)