Skip to content

Commit c44cf03

Browse files
committed
wrap text to satisfy precommit
Signed-off-by: Owen Williams <owilliams@mixxx.org>
1 parent ccac383 commit c44cf03

1 file changed

Lines changed: 90 additions & 48 deletions

File tree

proposals/2025-12-02_controller_shared_data.md

Lines changed: 90 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -7,46 +7,65 @@
77
* **Implementation Status:** `Partially implemented`
88

99
* **Related Issues and PRs:**
10-
* [Ability for controller to share data at runtime](https://github.com/mixxxdj/mixxx/pull/12199)
10+
* [Ability for controller to share data at
11+
runtime](https://github.com/mixxxdj/mixxx/pull/12199)
1112

12-
> TL;DR: Allow controllers to set and get data objects of arbitrary type for sharing between the controller code and the engine. Think: ControlObjects of arbitrary type that controllers can declare.
13+
> TL;DR: Allow controllers to set and get data objects of arbitrary type for
14+
> sharing between the controller code and the engine. Think: ControlObjects of
15+
> arbitrary type that controllers can declare.
1316
1417
## Why
1518

16-
There are multiple scenarios where controllers need to share and access data outside the container of the controller mapping file.
17-
This includes situations where some controllers expose more than one USB device that need to communicate with each other, or when a DJ connects multiple instances of the same hardware to Mixxx.
19+
There are multiple scenarios where controllers need to share and access data
20+
outside the container of the controller mapping file. This includes situations
21+
where some controllers expose more than one USB device that need to communicate
22+
with each other, or when a DJ connects multiple instances of the same hardware
23+
to Mixxx.
1824

1925
### Pitfalls of the current solution
2026

2127
ControlObjects are the normal way we share data, but:
2228

2329
* Controllers can't declare control objects.
24-
* Putting controller-specific data inside Mixxx itself would be bad and lead to bloat.
30+
* Putting controller-specific data inside Mixxx itself would be bad and lead to
31+
bloat.
2532
* Controllers need to share more types of data than just double values.
2633

2734
## Goals
2835

2936
Goals and use cases for the solution as proposed in [How](#how):
3037

31-
* Namespacing: Allow different controllers to declare same-named data objects without risk of collisions
32-
* Support controllers with screens that require communication from HID to separate Bulk USB devices (Traktor S4 MK3).
33-
* Build a data model foundation for users with multiple instances of the same controller (CDJ-2000).
34-
* Ensure that the API could support the features we may wish to add in the future, such as global namespace, without breaking controller mappings that use the API defined here.
38+
* Namespacing: Allow different controllers to declare same-named data objects
39+
without risk of collisions
40+
* Support controllers with screens that require communication from HID to
41+
separate Bulk USB devices (Traktor S4 MK3).
42+
* Build a data model foundation for users with multiple instances of the same
43+
controller (CDJ-2000).
44+
* Ensure that the API could support the features we may wish to add in the
45+
future, such as global namespace, without breaking controller mappings that
46+
use the API defined here.
3547

3648
### Audience
3749

3850
Users of modern controllers or multiple controllers will appreciate this work.
39-
Specifically, this work is required to fully support the Traktor S4 MK3, which has separate devices for the controller and the two screens (two total USB devices).
51+
Specifically, this work is required to fully support the Traktor S4 MK3, which
52+
has separate devices for the controller and the two screens (two total USB
53+
devices).
4054

4155
## Non-Goals
4256

43-
* We do not intend to fully support the multi-device scenario yet, that needs further design to associate specific devices with specific controller configurations.
44-
* We do not intend to immediately support "global" objects accessible across namespaces, like "universal shift".
57+
* We do not intend to fully support the multi-device scenario yet, that needs
58+
further design to associate specific devices with specific controller
59+
configurations.
60+
* We do not intend to immediately support "global" objects accessible across
61+
namespaces, like "universal shift".
4562

4663
## "Universal Shift"
4764

48-
"Universal Shift" refers to the idea that a shift button pressed on one controller can be detected by any and all other controllers.
49-
This may be a useful use-case but creates a lot of difficulties, so for now Universal Shift is out of scope for this first implementation.
65+
"Universal Shift" refers to the idea that a shift button pressed on one
66+
controller can be detected by any and all other controllers. This may be a
67+
useful use-case but creates a lot of difficulties, so for now Universal Shift is
68+
out of scope for this first implementation.
5069

5170
## How
5271

@@ -61,28 +80,34 @@ We will create a central object inside Mixxx that contains a triple-keyed map:
6180

6281
#### Namespace
6382

64-
`Namespace` is a string that is unique to each controller **mapping definition**.
65-
All connected controllers of the same model will share the same namespace.
66-
e.g. Two CDJ-2000's will both have a namespace like `CDJ_2000`.
67-
No two hardware mappings will have the same namespace, and we can enforce that with a precommit check.
83+
`Namespace` is a string that is unique to each controller **mapping
84+
definition**. All connected controllers of the same model will share the same
85+
namespace. e.g. Two CDJ-2000's will both have a namespace like `CDJ_2000`. No
86+
two hardware mappings will have the same namespace, and we can enforce that with
87+
a precommit check.
6888

6989
#### Grouping
7090

71-
`Grouping` is a logical value defined by the controller mapping definition.
72-
It can be like a Mixxx-style group ("`[Channel1]`") but it can be any arbitrary string.
73-
Many controllers will want to define something like `deck1` to refer to a device that can itself be assigned to multiple mixxx channels.
74-
This document does not use the word `group`, instead preferring `grouping`, to try to differentiate Mixxx-style "groups" from this concept, which is a distinct abstraction.
91+
`Grouping` is a logical value defined by the controller mapping definition. It
92+
can be like a Mixxx-style group ("`[Channel1]`") but it can be any arbitrary
93+
string. Many controllers will want to define something like `deck1` to refer to
94+
a device that can itself be assigned to multiple mixxx channels. This document
95+
does not use the word `group`, instead preferring `grouping`, to try to
96+
differentiate Mixxx-style "groups" from this concept, which is a distinct
97+
abstraction.
7598

76-
The controller mapping decides how these groups behave and Mixxx does no enforcement of them.
77-
To reiterate: even if a "grouping" "looks like" a Mixxx group, it is not.
99+
The controller mapping decides how these groups behave and Mixxx does no
100+
enforcement of them. To reiterate: even if a "grouping" "looks like" a Mixxx
101+
group, it is not.
78102

79103
#### Key
80104

81-
`Key` is a logical value defined by the controller mapping definition.
82-
It could refer to a button, light, knob, or abstract name.
105+
`Key` is a logical value defined by the controller mapping definition. It could
106+
refer to a button, light, knob, or abstract name.
83107

84-
The controller mapping decides how these groups behave and Mixxx does no enforcement of them.
85-
Similar to "grouping", keys bear no relation to equivalent Mixxx keys.
108+
The controller mapping decides how these groups behave and Mixxx does no
109+
enforcement of them. Similar to "grouping", keys bear no relation to equivalent
110+
Mixxx keys.
86111

87112
#### Example
88113

@@ -95,61 +120,78 @@ pseudocode:
95120
### API
96121

97122
The shared data API should be roughly the same across Controllers, QML, and C++.
98-
The primary difference is that C++ will have access to the namespace value at all times, whereas controllers and QML will have that value elided.
123+
The primary difference is that C++ will have access to the namespace value at
124+
all times, whereas controllers and QML will have that value elided.
99125

100-
The controller javascript has access to the shared data object through three functions:
126+
The controller javascript has access to the shared data object through three
127+
functions:
101128

102129
#### Get
103130

104131
excuse the pseudo-js:
105132

106133
`engine.GetSharedData(grouping: string, key: string): Error | any`
107134

108-
`namespace` is set automatically by the engine code, so controllers can't get that wrong.
135+
`namespace` is set automatically by the engine code, so controllers can't get
136+
that wrong.
109137

110138
This function returns error if the value is not found.
111139

112140
#### Set
113141

114142
`engine.SetSharedData(grouping: string, key: string, value: any): void`
115143

116-
`namespace` is set automatically by the engine code, so controllers can't get that wrong.
144+
`namespace` is set automatically by the engine code, so controllers can't get
145+
that wrong.
117146

118-
Calling "set" triggers "updated" signals to all subscribers across the engine, QML (e.g. controller screen code), and controllers.
147+
Calling "set" triggers "updated" signals to all subscribers across the engine,
148+
QML (e.g. controller screen code), and controllers.
119149

120-
Controllers do not get notified about updates they initiated themselves, to prevent circular signal loops.
150+
Controllers do not get notified about updates they initiated themselves, to
151+
prevent circular signal loops.
121152

122153
#### Updated
123154

124-
Controllers get notified about data updates via a standard callback, which they can optionally implement:
155+
Controllers get notified about data updates via a standard callback, which they
156+
can optionally implement:
125157

126158
`function SharedDataUpdated(grouping: string, key: string, value: any){}`
127159

128-
Controllers get update calls for each updated item separately, and can handle them however they wish.
129-
There is no effect (no logging or error) If a controller does not implement this function.
160+
Controllers get update calls for each updated item separately, and can handle
161+
them however they wish. There is no effect (no logging or error) If a controller
162+
does not implement this function.
130163

131164
### Possible future directions
132165

133-
The following are possible future extensions to this proposal that are currently out of scope and will not be implemented in the first version, but we want to make sure to leave room in case we add them in the future:
166+
The following are possible future extensions to this proposal that are currently
167+
out of scope and will not be implemented in the first version, but we want to
168+
make sure to leave room in case we add them in the future:
134169

135170
#### Cross-device communication / subscription
136171

137-
There is a possibility controller authors may want access to signals sent from other controllers, for instance a "universal shift" button.
138-
For this purpose we may choose to allow controller to "subscribe" to updates from other namespaces, or all namespaces, in a read-only fashion.
139-
In this scenario, controllers would not have the ability to write updates to namespaces outside their own.
140-
This may be brittle because controllers would need to know about all possible valid namespaces, so this feature would need more care to make it maintainable.
172+
There is a possibility controller authors may want access to signals sent from
173+
other controllers, for instance a "universal shift" button. For this purpose we
174+
may choose to allow controller to "subscribe" to updates from other namespaces,
175+
or all namespaces, in a read-only fashion. In this scenario, controllers would
176+
not have the ability to write updates to namespaces outside their own. This may
177+
be brittle because controllers would need to know about all possible valid
178+
namespaces, so this feature would need more care to make it maintainable.
141179

142180
#### "Global" namespace
143181

144-
Another possibility is that we may want a "global" namespaces that all controllers can read and write to.
145-
This would be another way to support a "universal shift" button.
146-
This would have to be carefully managed to prevent collisions between controller configs.
147-
One way to do this would be to "bless" specific groupings and keys for the global namespace, and controller authors would have to add their requested global grouping/key to Mixxx.
182+
Another possibility is that we may want a "global" namespaces that all
183+
controllers can read and write to. This would be another way to support a
184+
"universal shift" button. This would have to be carefully managed to prevent
185+
collisions between controller configs. One way to do this would be to "bless"
186+
specific groupings and keys for the global namespace, and controller authors
187+
would have to add their requested global grouping/key to Mixxx.
148188

149189
## Alternatives
150190

151-
The original implementation did not have groupings and keys and instead had a single namespaced data blob that controllers had to manage themselves.
152-
This approach requires a lot more work on the part of the controller author to merge and manage the data object.
191+
The original implementation did not have groupings and keys and instead had a
192+
single namespaced data blob that controllers had to manage themselves. This
193+
approach requires a lot more work on the part of the controller author to merge
194+
and manage the data object.
153195

154196
## Action Plan
155197

0 commit comments

Comments
 (0)