Refactor SMXManager::SendLightUpdates to queue multiple lights commands if possible.
This also fixes a memory leak if lights are queued too quickly.
This commit is contained in:
parent
0c19451d7d
commit
69b2239922
@ -486,26 +486,46 @@ void SMX::SMXManager::ReenableAutoLights()
|
|||||||
void SMX::SMXManager::SendLightUpdates()
|
void SMX::SMXManager::SendLightUpdates()
|
||||||
{
|
{
|
||||||
g_Lock.AssertLockedByCurrentThread();
|
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;
|
return;
|
||||||
|
|
||||||
const PendingCommand &command = m_aPendingLightsCommands[0];
|
// 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
|
||||||
// See if it's time to send the next command. We only need to look at the first
|
// the whole lights update at once. V3 pads require us to time commands, so we can't
|
||||||
// command, since these are always sorted.
|
// spam both lights commands at once, which is handled by fTimeToSend.
|
||||||
if(command.fTimeToSend > GetMonotonicTime())
|
while( !m_aPendingLightsCommands.empty() )
|
||||||
return;
|
|
||||||
|
|
||||||
// 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())
|
// Send the lights command for each pad. If either pad isn't connected, this won't do
|
||||||
m_pDevices[iPad]->SendCommandLocked(command.sPadCommand[iPad]);
|
// anything.
|
||||||
}
|
const PendingCommand &command = m_aPendingLightsCommands[0];
|
||||||
|
|
||||||
// Remove the command we've sent.
|
// See if it's time to send this command.
|
||||||
m_aPendingLightsCommands.erase(m_aPendingLightsCommands.begin(), m_aPendingLightsCommands.begin()+1);
|
if(command.fTimeToSend > GetMonotonicTime())
|
||||||
|
break;
|
||||||
|
|
||||||
|
for(int iPad = 0; iPad < 2; ++iPad)
|
||||||
|
{
|
||||||
|
if(!command.sPadCommand[iPad].empty())
|
||||||
|
{
|
||||||
|
// 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)
|
void SMX::SMXManager::SetPanelTestMode(PanelTestMode mode)
|
||||||
|
@ -76,6 +76,7 @@ private:
|
|||||||
string sPadCommand[2];
|
string sPadCommand[2];
|
||||||
};
|
};
|
||||||
vector<PendingCommand> m_aPendingLightsCommands;
|
vector<PendingCommand> m_aPendingLightsCommands;
|
||||||
|
int m_iLightsCommandsInProgress = 0;
|
||||||
double m_fDelayLightCommandsUntil = 0;
|
double m_fDelayLightCommandsUntil = 0;
|
||||||
|
|
||||||
// Panel test mode. This is separate from the sensor test mode (pressure display),
|
// Panel test mode. This is separate from the sensor test mode (pressure display),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user