diff --git a/build.sh b/build.sh index ca0eb98a9..9c8b6d44c 100755 --- a/build.sh +++ b/build.sh @@ -333,7 +333,7 @@ function performZephyrAction() { createCentralCompileCommands ;; make) - $NICE west build --build-dir $ROOT/device/build/$DEVICE device + $NICE west build --build-dir $ROOT/device/build/$DEVICE device exitOnFail $? ;; flash) diff --git a/doc-dev/reference-manual.md b/doc-dev/reference-manual.md index aedc5682a..60c75452b 100644 --- a/doc-dev/reference-manual.md +++ b/doc-dev/reference-manual.md @@ -219,6 +219,7 @@ CONDITION = {ifLayerToggled | ifNotLayerToggled} CONDITION = {ifRecording | ifNotRecording} CONDITION = {ifRecordingId | ifNotRecordingId} MACROID CONDITION = {ifModuleConnected | ifNotModuleConnected} MODULEID +CONDITION = {ifAlreadyRunning | ifNotAlreadyRunning} MODIFIER = MODIFIER = suppressMods MODIFIER = postponeKeys @@ -558,6 +559,7 @@ Conditions are checked before processing the rest of the command. If the conditi - `{ifKeymap|ifNotKeymap|ifLayer|ifNotLayer} ` will test if the current Keymap/Layer equals the first argument. - `{ifLayerToggled|ifNotLayerToggled}` will return true if current layer is toggled. It will return true if the toggled layer is on top of the stack, or anywhere else as long as only the same (currently active) layers are above it in the layer stack. - `ifRecording/ifNotRecording` and `ifRecordingId/ifNotRecordingId MACROID` test if the runtime macro recorder is in the recording state. +- `ifAlreadyRunning/ifNotAlreadyRunning` is true if another macro slot is currently playing the same macro index as the current one. Useful to prevent re-entering a macro that is already in progress. - `ifShortcut/ifNotShortcut [IFSHORTCUT_OPTIONS]* [KEYID]*` will wait for future keypresses and compare them to the argument. See the postponer mechanism section. - `ifGesture/ifNotGesture [IFSHORTCUT_OPTIONS]* [KEYID]*` just as `ifShortcut`, but breaks after 1000ms instead of when the key is released. See the postponer mechanism section. - `ifPrimary/ifSecondary [ simpleStrategy | advancedStrategy | ignoreTriggersFromSameHalf | acceptTriggersFromSameHalf ] ... COMMAND` will wait until the firmware can distinguish whether primary or secondary action should be activated and then either execute `COMMAND` or skip it. diff --git a/right/src/macros/command_hash.gperf b/right/src/macros/command_hash.gperf index 9148cbb5c..74d7cee54 100644 --- a/right/src/macros/command_hash.gperf +++ b/right/src/macros/command_hash.gperf @@ -76,6 +76,8 @@ ifKeyDefined, CommandId_ifKeyDefined ifNotKeyDefined, CommandId_ifNotKeyDefined ifModuleConnected, CommandId_ifModuleConnected ifNotModuleConnected, CommandId_ifNotModuleConnected +ifAlreadyRunning, CommandId_ifAlreadyRunning +ifNotAlreadyRunning, CommandId_ifNotAlreadyRunning ifHold, CommandId_ifHold ifTap, CommandId_ifTap ifSecondary, CommandId_ifSecondary diff --git a/right/src/macros/command_ids.h b/right/src/macros/command_ids.h index 038eb7cc5..b42843af7 100644 --- a/right/src/macros/command_ids.h +++ b/right/src/macros/command_ids.h @@ -93,6 +93,8 @@ typedef enum { CommandId_ifNotKeyDefined, CommandId_ifModuleConnected, CommandId_ifNotModuleConnected, + CommandId_ifAlreadyRunning, + CommandId_ifNotAlreadyRunning, CommandId_ifHold, CommandId_ifTap, CommandId_ifSecondary, diff --git a/right/src/macros/commands.c b/right/src/macros/commands.c index bb1627f2c..e44a34e81 100644 --- a/right/src/macros/commands.c +++ b/right/src/macros/commands.c @@ -591,6 +591,26 @@ static bool processIfRecordingIdCommand(parser_context_t* ctx, bool negate) return res != negate; } +static bool processIfAlreadyRunningCommand(bool negate) +{ + if (Macros_DryRun) { + return true; + } + uint8_t myIndex = S->ms.currentMacroIndex; + uint8_t mySlot = S - MacroState; + bool found = false; + for (uint8_t i = 0; i < MACRO_STATE_POOL_SIZE; i++) { + if (i == mySlot) { + continue; + } + if (MacroState[i].ms.macroPlaying && MacroState[i].ms.currentMacroIndex == myIndex) { + found = true; + break; + } + } + return found != negate; +} + static bool processIfPendingCommand(parser_context_t* ctx, bool negate) { uint32_t cnt = Macros_ConsumeInt(ctx); @@ -2183,6 +2203,10 @@ static macro_result_t processCommand(parser_context_t* ctx) PROCESS_CONDITION(processIfModuleConnected(ctx, false)) case CommandId_ifNotModuleConnected: PROCESS_CONDITION(processIfModuleConnected(ctx, true)) + case CommandId_ifAlreadyRunning: + PROCESS_CONDITION(processIfAlreadyRunningCommand(false)) + case CommandId_ifNotAlreadyRunning: + PROCESS_CONDITION(processIfAlreadyRunningCommand(true)) case CommandId_ifHold: return processIfHoldCommand(ctx, false); case CommandId_ifTap: