kareltucek / firmware

This is fork of UHK's firmware featuring extended macro engine.
Other
82 stars 9 forks source link

Key repeat for macro #82

Closed soraxas closed 2 years ago

soraxas commented 2 years ago

Does it make sense to enable certain macro key to inherent the key-repat features from typical keyboard/OS?

For example, following vim convention, I have e maps to C-right and w maps to macro of tapKeySeq C-right right. (in some vim-like keymap that I had setup)

The e works creat and it repeats while holding. The w, on the other hand, will only executes once (which makes perfect sense!! esp. given with what macro can do).

Perhaps having some setting in agent that can enable key-repeat feature per macro would be nice (key-repeating would only happen if the same macro is not already running).

kareltucek commented 2 years ago

What exactly is the question?

I don't think Laszlo will be enthusiastic about making such feature part of agent and the core engine (i.e., of regular actions, part of the binary serialization format, etc).

Regarding me, I don't want to make this firmware dependent on custom Agent - because it would bring great deal trouble for both me and for users.

On the other hand, if you are asking if I am willing to merge a macro command which will make this possible, then yes, it makes sense to me. (Something like autorepeat tapKey space, which would block for as long as the key is held. I think I am also fine with giving it 2 bits in macro-scope of the state if you want to make it work with backward jumps.)

kareltucek commented 2 years ago

(I am not a huge fan of configuring it somehow globally as a property of a macro, because such setting would be less "transparent" and harder to find. I thing keeping this feature inside of the macro language is ideal.)

soraxas commented 2 years ago

I see, your proposal sounds like a good idea and I will look into it.

It's interesting how you've mentioned the memory constraints in the other issue, and indeed we should try to constrain our memory layout. I am not too familiar with embedded programming, but would there be a smarter way to "only pay for what you use" within the macro (to reduce the overall memory layout)?

For example, we currently keep track of currentIfShortcutConditionPassed, currentIfSecondaryConditionPassed, and potentially autorepeat state in all macro state, regardless of whether the macro is using ifShortcut, ifSecondary, autorepeat etc.

Every additional feature increases the memory layout by 255x (max macro num), even though maybe only a few macros uses these features and need to keep track of these states.


Proposal: Could we only allocate memory when any of these tokens are first encountered in the macro, such that we dynamically increases that macro's memory usage only when it's necessary (i.e. only when those actions appear in the macro)?

We can then free them after the macro finishes. If no memory is available, we will then throw an error and ignore the macro request.

A potential downside is that running malloc on key-press might slow down the response time. And whenever there is dynamic memory allocation in programs, there are potential memory leaks. And I'm not sure if embedded device even uses malloc for these use-cases

kareltucek commented 2 years ago

Every additional feature increases the memory layout by 255x (max macro num), even though maybe only a few macros uses these features and need to keep track of these states.

This holds only for macro metadata (i.e., things in macro_reference_t). Macro engine has its own state pool, which features something like 16 states. (This way, a single macro can also have multiple running instances.)

but would there be a smarter way to "only pay for what you use" within the macro (to reduce the overall memory layout)?

There are some things to notice:


Proposal: Could we only allocate memory when any of these tokens are first encountered in the macro, such that we dynamically increases that macro's memory usage only when it's necessary (i.e. only when those actions appear in the macro)?

Which tokens do you mean? If we are still talking about currentIfShortcutConditionPassed etc flags, then just keeping information about "having this and that stashed elsewhere" would be much more costly than current state of affairs.

If we are talking the string token parsing, I believe there is no need to actually copy the strings.

A potential downside is that running malloc on key-press might slow down the response time. And whenever there is dynamic memory allocation in programs, there are potential memory leaks. And I'm not sure if embedded device even uses malloc for these use-cases

I am not aware of malloc being used in UHK firmware at all, and am not sure if it is actually desired. Static allocation has some benefits:

Downsides of dynamic allocation:


Generally, we still have enough memory reserve to use when there is a good reason to do so, just not enough for the standard I-have-an-infinite-heap-and-don't-fear-to-use-it programming style.