Refactor SMXManager::SendLightUpdates to queue multiple lights commands if possible.

This also fixes a memory leak if lights are queued too quickly.
master
Glenn Maynard 6 years ago
parent 0c19451d7d
commit 69b2239922
  1. 34
      sdk/Windows/SMXManager.cpp
  2. 1
      sdk/Windows/SMXManager.h

@ -486,26 +486,46 @@ void SMX::SMXManager::ReenableAutoLights()
void SMX::SMXManager::SendLightUpdates()
{
g_Lock.AssertLockedByCurrentThread();
if(m_aPendingLightsCommands.empty())
// If previous lights commands are being sent, wait for them to complete before
// queueing more.
if(m_iLightsCommandsInProgress > 0)
return;
// If we have more than one command queued, we can queue several of them if we're
// before fTimeToSend. For the V4 pads that require more commands, this lets us queue
// the whole lights update at once. V3 pads require us to time commands, so we can't
// spam both lights commands at once, which is handled by fTimeToSend.
while( !m_aPendingLightsCommands.empty() )
{
// Send the lights command for each pad. If either pad isn't connected, this won't do
// anything.
const PendingCommand &command = m_aPendingLightsCommands[0];
// See if it's time to send the next command. We only need to look at the first
// command, since these are always sorted.
// See if it's time to send this command.
if(command.fTimeToSend > GetMonotonicTime())
return;
break;
// Send the lights command for each pad. If either pad isn't connected, this won't do
// anything.
for(int iPad = 0; iPad < 2; ++iPad)
{
if(!command.sPadCommand[iPad].empty())
m_pDevices[iPad]->SendCommandLocked(command.sPadCommand[iPad]);
{
// Count the number of commands we've queued. We won't send any more until
// this reaches 0 and all queued commands were sent.
m_iLightsCommandsInProgress++;
// The completion callback is guaranteed to always be called, even if the controller
// disconnects and the command wasn't sent.
m_pDevices[iPad]->SendCommandLocked(command.sPadCommand[iPad], [this, iPad](string response) {
g_Lock.AssertLockedByCurrentThread();
m_iLightsCommandsInProgress--;
});
}
}
// Remove the command we've sent.
m_aPendingLightsCommands.erase(m_aPendingLightsCommands.begin(), m_aPendingLightsCommands.begin()+1);
}
}
void SMX::SMXManager::SetPanelTestMode(PanelTestMode mode)

@ -76,6 +76,7 @@ private:
string sPadCommand[2];
};
vector<PendingCommand> m_aPendingLightsCommands;
int m_iLightsCommandsInProgress = 0;
double m_fDelayLightCommandsUntil = 0;
// Panel test mode. This is separate from the sensor test mode (pressure display),

Loading…
Cancel
Save