Oliman473 / wjoy

Automatically exported from code.google.com/p/wjoy
0 stars 0 forks source link

Delay in input processing every 2.5 seconds #71

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
1. Open any application that gives a live read-out of the controller's analog 
stick position
2. Rotate the control stick in full circles continuously
3. Notice that every 2.5 seconds, the read-out stutters

Making the [m_Device requestStateReport] call in Wiimote.m asynchronous fixes 
the problem, though I don't know what the concurrency implications of this 
change are.

- (void)requestUpdateState
{
    // My fix:
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [m_Device requestStateReport];
    });
}

2013 13" MacBook Pro
OS X 10.10
Wii U Pro Controller & Wiimote Classic Controller

Original issue reported on code.google.com by skyler.l...@gmail.com on 31 Jan 2015 at 10:43

GoogleCodeExporter commented 8 years ago
Big thanks!

On my iMac i can't see any delays, but sometimes some people write to me 
letters about it. Now i know what happens. :)

I think call [m_Device requestStateReport] from background thread is not good 
idea (Wiimote.framework is not threat-safe), but may be i can find other way to 
fix this.

Original comment by alexandr.serkov on 31 Jan 2015 at 8:04

GoogleCodeExporter commented 8 years ago
Perhaps you've already figured this out, but looking at the code, this is the 
WiimoteWatchdog blocking on the [m_DataChannel writeSync:length:] call in 
-[WiimoteBluetoothDeviceTransport postBytes:length:]. Maybe these writes could 
be switched to use writeAsync?

The WiimoteHIDDeviceTransport's postBytes implementation also uses a 
synchronous call (IOHIDDeviceSetReport), but the documentation for both it and 
its asynchronous variant IOHIDDeviceSetReportWithCallback says it "will block 
until the report has been issued to the device"...so it's not async? I guess I 
should try it.

As a temporary workaround, it looks to me that the watchdog is just polling for 
the battery level (is that correct?), so it could be disabled if you don't care 
about that. The same status event, WiimoteDeviceCommandTypeGetState, seems to 
be sent by the Wiimote itself when adding or removing a remote extension, also 
updating the known battery level (even with the watchdog disabled).

Original comment by wilbur.v...@gmail.com on 5 Feb 2015 at 2:29

GoogleCodeExporter commented 8 years ago
Here's a patch that makes the watchdog's state requests non-blocking[1]. It 
adds an "async" parameter to the postBytes: method and other intermediate 
methods to request a non-blocking write. I didn't change any other requests to 
use the async option because I wasn't sure if there were any ordering 
assumptions elsewhere.

I also didn't add a callback parameter, so there's no way to know when a 
particular request finishes, but it isn't needed for the watchdog's use case.

1 : Only for the Bluetooth transport; HID requests are still always 
synchronous. I tried testing the HID transport but I haven't been able to get 
one-button-click connections working for a while. Apparently my remote is 
already paired (with the console?) and won't pair with my Mac?

Original comment by wilbur.v...@gmail.com on 5 Feb 2015 at 3:37

Attachments:

GoogleCodeExporter commented 8 years ago
Mmm...

>> Apparently my remote is already paired (with the console?) and won't pair 
with my Mac?

No, this feature works on mac very unstable. Sometimes helps remove wiimote 
from bluetooth settings (if it visible on bluetooth devices list). Sometimes 
you need remove it two or three times. This strange things needed only for the 
first connection. After what all works fine. I think, it's depends on bluetooth 
adapter (and input/output delay on postBytes method too).

And about async operations on device. Not only one watchdog send commands to 
wiimote. And i don't know, that happens, if watchdog send refresh command, and, 
immediately, something other send another synchronously. Maybe it will work, 
may be it crash application.
I think best way to solve this problem is removing watchdog. And refresh 
wiimote state only if user opens WJoy menu. Or really use async methods for all 
transports and all things, but with command queue.

Anyway, thanks for patch. If i will implement command queue, i'll use it.

Original comment by alexandr.serkov on 5 Feb 2015 at 7:27