-
Notifications
You must be signed in to change notification settings - Fork 17
feat: implement dynamic key buffer system #77
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
base: master
Are you sure you want to change the base?
Conversation
|
Could you please explain how this action based system works in detail? |
|
@Prayag2, an action is essentially a task that is executed when one or a combination of keyboard shortcuts is pressed. For one task, there can be many shortcuts. The task class only encapsulates the execution logic and the keyboard shortcuts are decoupled from it. You can see this from the The This system is meant to allow Drawy to store keyboard shortcut data in a JSON format like this: [
{
"action": "Use Tool", // The ID of the action type in the code
"actionParameters": {
"tool": "Move" // The name of the tool to be used
},
"keys": [
{
"id": 1234, // Qt input tokens (mouse or keyboard)
"type": "Mouse",
"count": 1 // Must be >= 1 (fallbacks to 1)
}
],
"holdRequired": false, // Whether to stop using the tool on key release
"maxGapMs": 50 // The time threshold in which the keys need to be pressed, if they are not pressed in their defined order; the threshold time the other keys need to be pressed in (0 means they need to be pressed in-order, -1 means infinite threshold)
}
]You can see the default actions that are created in the Actions are just not limited to tools. I have made the code abstract so that we can define actions for other things that we may need in the future. The main issue with this implementation, as I mentioned, is that the shortcuts inside the tools themselves remain hard-coded. I have only decoupled the logic for the shortcuts in the controller class, and I need further advice for how we can make the system cover those as well, and if it needs to do so. |
| }); | ||
|
|
||
| if (bufIt == m_keyBuffer.end()) { | ||
| goto try_timed; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please avoid goto statements whenever possible. They make code harder to read and can easily be avoided.
|
|
||
| for (size_t s = 0; s < n; s++) { | ||
| // quick skip: start event must be a required token (it is, by construction) | ||
| std::unordered_map<uint64_t, int> have; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use better variable names! For example, what is s and what's have? Use descriptive variable names, even if they are long. For example, eventSize instead of n, eventIndex instead of s. Even long variable names are fine if they're descriptive, e.g., requiredCountOfKeyTokens. Instead of using a uint64_t directly to represent a token, you can alias it to a more meaningful name like KeyToken.
| have.reserve(reqCounts.size()); | ||
| have[events[s].m_token] = 1; | ||
| qint64 prevTime = events[s].m_timeMs; | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should also split the function into smaller parts, one for the ordered check, one for timed check, and other checks if you have them.
|
|
||
| struct TaskContext { | ||
| ApplicationContext *m_appContext; | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The class ApplicationContext was recently made a singleton, which means only one instance of it exists in the app. You don't have to pass its pointers anymore. Just access it by using ApplicationContext::instance().
| bool m_prevHeld{false}; | ||
| }; | ||
|
|
||
| class IActionTask { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't use the I prefix, it's not a convention I follow here.
|
Hi @quarterstar, there are a few things that need to be taken care of before you continue. Even though the project does not require a dynamic buffer system at the moment, you can proceed with adding it. A few points that were not mentioned in my reviews:
Everything else looks good. Thank you for contributing. |
|
Hi @Prayag2, yesterday I received an email which said my Discord account disabled, for seemingly no apparent reason. I'm not sure what caused it but I suspect that it was my VPN or unusual browser activity being flagged. I will look into reinstating my account, but until then I will keep you informed with these comments about my progress. |
|
Hi @quarterstar, |
This PR implements a new dynamic keybinding system that makes the controller class more flexible. Specifically, its primary purpose is to fill the needs of issue #41 and lay down the road for implementing custom keybinds in the future.
The PR implements an action-based system. However, this only addresses the shortcuts defined in the controller itself. For the other hard-coded keybinds in the tool files, further adjustment will be needed.
Currently, the shortcuts implemented are Space + Left Click for using the move tool and
Right Clickfor using the erase tool. The implementation is not finished and I am requesting comments before I proceed further.