@@ -90,54 +90,56 @@ class ProController : public AbstractController{
9090public:
9191 //
9292 // Cancellation
93- // These are thread-safe with everything.
93+ //
94+ // These functions will return immediately and are thread-safe with
95+ // everything. The intended use-case is for an inference thread to cancel
96+ // a running sequence of commands on a program thread.
9497 //
9598
9699 // Cancel all commands. This returns the controller to the neutral button
97100 // state and clears the command queue.
101+ // This does not wait for the commands to finish cancelling. This is an
102+ // asynchronous function that merely initiates the cancellation process.
98103 virtual void cancel_all_commands () = 0;
99104
100- // Declare that the next command will replace the current command stream
101- // with no gaps.
105+ // Same as "cancel_all_commands()", but instead of cancelling the stream,
106+ // it lets it keep running. Then on the next command issued after this
107+ // cancel, it will atomically replace the stream without gapping.
108+ // This lets you do stuff like suddenly change joystick movement in
109+ // response to inference while simultaneously holding a button without
110+ // ever releasing it during the transition.
102111 virtual void replace_on_next_command () = 0;
103112
104113
105114public:
106115 //
107- // Basic Commands
116+ // Commands
117+ //
118+ // Commands are actions like button presses or joystick movements that are
119+ // eventually sent to the console.
120+ //
121+ // All commands are prefixed with "issue_".
122+ // Commands are not thread-safe with other commands.
123+ // Commands are thread-safe with the cancellation functions above.
108124 //
109- // Commands not thread-safe with other commands. But they are thread-safe
110- // with the cancellation functions above.
125+ // Commands are asynchronous. When you call a command function on this,
126+ // class it gets enqueued into a FIFO and immediately returns. It will only
127+ // block if the FIFO is full.
111128 //
112- // As of this writing, all implementations are thread-safe enough that
113- // they will neither crash nor enter an invalid state with concurrent
114- // commands. But the implied queuing semantics means that parallelizing
115- // commands will not do what you want it to do .
129+ // If a command is called with a cancelled "cancellable" parameter, it will
130+ // throw an OperationCancelledException.
131+ // If a cancellation happens while you are inside a command function, it
132+ // will immediately stop and throw an OperationCancelledException .
116133 //
117134
118135 // Wait for all unfinished commands to finish. This will also wait out
119136 // hanging commands including their cooldown periods.
137+ // This is not a true command function as it waits for the entire queue to
138+ // empty out rather than entering itself into the queue.
139+ // If a cancellation happens inside this function, it will immediately
140+ // throw an OperationCancelledException.
120141 virtual void wait_for_all (const Cancellable* cancellable) = 0;
121142
122- //
123- // All commands are enqueued into a FIFO that the controller will execute
124- // in order preserving the timing semantics as closely as possible
125- // irrespective of the latencies between the host and the device.
126- //
127- // For wired controller emulation, the timings will be preserved exactly as
128- // long as the FIFO never completely empties out.
129- //
130- // For wireless controllers (Joy Con), while we do not have an
131- // implementation of this at this time, we do not expect it to be able to
132- // preserve timing.
133- //
134- // Whether a controller supports exact timings is controlled by the feature
135- // flag "TickPrecise".
136- //
137-
138- // The following functions are asynchronous. They will return immediately
139- // if the command can be enqueued into the FIFO. Otherwise, they will block
140- // until there is space in the FIFO.
141143
142144 // Temporary for refactor: Send custom requests for PABotBase's advanced
143145 // RPCs.
@@ -167,7 +169,7 @@ class ProController : public AbstractController{
167169 // exposes.
168170 //
169171 // If the button is busy (due to still being held down or is waiting out
170- // the cooldown), the command will block until the button is ready.
172+ // the cooldown), the command will wait until the button is ready.
171173 //
172174 // By setting (delay < hold), the command will "return" early and move onto
173175 // the next command while the button is still being held down.
@@ -183,6 +185,14 @@ class ProController : public AbstractController{
183185 // Users are responsible for understanding the controller state and
184186 // managing the timeline/scheduling.
185187 //
188+ // It is important to remember that the "timeline" here is the timeline
189+ // being fed to the Switch. Thus the timing parameters written in the C++
190+ // code here is what you will get on the console (or as close as possible).
191+ //
192+ // The actual calls to the methods in the class will return or block in an
193+ // unspecified manner as they merely enqueue into a FIFO which is then
194+ // "replayed" to the Switch in an implementation-dependent manner.
195+ //
186196
187197 // Tell the scheduler to wait for all pending commands to finish
188198 // (including cooldowns) before executing further instructions.
@@ -229,13 +239,12 @@ class ProController : public AbstractController{
229239 //
230240 // This command will wait until the controller is fully idle (including
231241 // cooldowns) before it starts. This ensures that everything is issued
232- // simultaneously.
242+ // simultaneously. In other words, there is an implied call to
243+ // "issue_barrier()" before executing the state.
233244 //
234245 // The sole purpose of this function is for keyboard commands.
235- // While it's technically possible to implement any button overlapping
236- // sequence with this, doing so this way can lead to very inefficient
237- // serial bandwidth usage if buttons are being rapidly pressed and released
238- // in an arbitrary manner that leads to constant state changes.
246+ // For programs, it is easier to use the individual button/joystick
247+ // functions above.
239248 //
240249 // If we need to support new Switch controller functionality
241250 // (such as Joycon gyro or new stuff in Switch 2), we can simply add
@@ -255,14 +264,13 @@ class ProController : public AbstractController{
255264 //
256265 // High speed Macros
257266 //
258- // It is currently unclear if these can be properly executed over wireless.
259- // If they can't, then it remains to be decided if we should gate these
260- // behind a feature flag or if the controller should slow them down to make
261- // them work properly.
267+ // Be mindful when calling these mashing functions on a tick imprecise
268+ // controller. You can guarantee that some (most) of them will be dropped.
262269 //
263- // It is not advised to call these if you are micromanaging with tick-level
264- // precision since the exact timing characteristics and button selection
265- // is not specified and context-dependent.
270+ // Even if you are on a tick-precise controller, it is not advised to call
271+ // these if you are micromanaging with tick-level granularity. The exact
272+ // timing characteristics and button selection is not specified and may be
273+ // context and implementation-dependent.
266274 //
267275
268276 // Mash a button as quickly as possible.
0 commit comments