-
Notifications
You must be signed in to change notification settings - Fork 3
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
feat: Shift Registers for Shift+Trigger operations #11
Merged
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
97aa0b8
feat(Streamdeck): add a "trigger down" map for rendering feedbacks
jstarpl c6654b3
feat: add shift registers
jstarpl 1e92094
feat(StreamDeck, XKeys, Skaarhoj): add direction information
jstarpl b097d67
feat: improve feedback refresh
jstarpl bdd5062
fix(Streamdeck): tests
jstarpl 469d79c
chore: document Shift Registers idea
jstarpl 283fe59
chore: improve FeedbackStore
jstarpl b36616f
fix(Streamdeck): simplify feedback update
jstarpl File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
Shift Registers | ||
=== | ||
|
||
In order to support a "generic" way of doing multiple "layers" of controls on a single control surface (or a group of them), the concept of "modifier keys" had to be generalized. This has been done by coming up with the concept of _Shift Registers_. | ||
|
||
A Shift Register is a numbered integer variable that is global to a given instance of Input Gateway. Actions mounted to the Triggers of various Input Devices can then modify these Shift Registers using simple operations: Add (`+`), Subtract (`-`) and Set (`=`) and a single operand value. Since the Add and Subtract operations do not have any stop conditions, in order for their behavior to be more predictable, additional `min` and `max` properties to clamp the resulting Shift Register to a range after the operation is done. | ||
|
||
The state of all of the Shift Registers in an Input Gateway is prepended to the "triggerId" string of all emitted triggers using the following algorithm: | ||
|
||
* If all Shift Registers are set to 0 (their initial value), the prefix is an empty string. _This allows backwards compatibility if one is not using Shift Registers at all._ | ||
* If a Shift Register is set to a value other than 0, iterate through the Shift Registers and concatenate their values, joined with a `:` character, until the last non-zero Shift Register is found. An example Shift Registers state prefix will look look something like this: `[1:2:0:1]` | ||
|
||
Since this "Shift Registers" prefix is effectively changing the triggers themselves, this also affects the feedback displayed by the Input Devices. | ||
|
||
For example: by adding the "Change Shift Register" actions to various _button down_ and _button up_ triggers, one can choose to build various interaction models: | ||
|
||
* Shift + Button interactions | ||
* Latching Shift buttons | ||
* Cascading menus | ||
* Folders | ||
* Or even number inputs | ||
|
||
In order to get the desired interaction model, it may be neccessary to add the same action to multiple triggers (the same physical trigger with various Shift Register prefixes) or to split actions on prefixed and unprefixed triggers. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { SomeFeedback } from '../feedback/feedback' | ||
|
||
export class FeedbackStore<T extends SomeFeedback> { | ||
private feedbacks: Record<string, Record<string, T>> = {} | ||
|
||
public set(feedbackId: string, triggerId: string, feedback: T): void { | ||
if (this.feedbacks[feedbackId] === undefined) { | ||
this.feedbacks[feedbackId] = {} | ||
} | ||
|
||
this.feedbacks[feedbackId][triggerId] = feedback | ||
} | ||
|
||
public get(feedbackId: string, acceptedTriggerIds: string[]): T | null | ||
public get(feedbackId: string, triggerId: string): T | null | ||
public get(feedbackId: string, triggerId: string | string[]): T | null { | ||
const triggersInPriority = Array.isArray(triggerId) ? triggerId : [triggerId] | ||
|
||
const feedbackObj = this.feedbacks[feedbackId] as Record<string, T> | undefined | ||
if (!feedbackObj) return null | ||
|
||
for (const trigger of triggersInPriority) { | ||
if (feedbackObj[trigger]) return feedbackObj[trigger] | ||
} | ||
|
||
return null | ||
} | ||
|
||
public clear(): void { | ||
this.feedbacks = {} | ||
} | ||
|
||
public allFeedbackIds(): string[] { | ||
return Array.from(Object.keys(this.feedbacks)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Question: You're not really using this class as a generic anywhere, perhaps just use
SomeFeedback
directly?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.
Well, I'm not using it right now, but the plan was that the FeedbackStore could be used for objects enhancing the SomeFeedback interface, that's why it's generic.