1
0
forked from 0ad/0ad

Debounce gamesetup network messages & slider changes to avoid lag.

Gamesetup Net synchronisation messages are sent on any change, which
includes slider changes. They can be quite slow for clients to process,
so it makes sense to introduce some 'debounce' here. I picked 400ms
somewhat arbitrarily.

Sliders also call UpdateGameAttributes, which can also lag, so run it
only once per 50ms at most.

Reported by: nani
Differential Revision: https://code.wildfiregames.com/D3536
This was SVN commit r24852.
This commit is contained in:
wraitii 2021-02-07 18:00:57 +00:00
parent 65195211a8
commit 612515a163
2 changed files with 24 additions and 4 deletions

View File

@ -132,7 +132,7 @@ class GameSettingsControl
g_GameAttributes = this.gameSettingsFile.loadFile();
this.updateGameAttributes();
this.setNetworkGameAttributes();
this.setNetworkGameAttributesImmediately();
}
}
@ -223,9 +223,19 @@ class GameSettingsControl
*
* To avoid an infinite loop, do not call this function when a game setup message was
* received and the data had only been modified deterministically.
*
* This is run on a timer to avoid flooding the network with messages,
* e.g. when modifying a slider.
*/
setNetworkGameAttributes()
{
if (g_IsNetworked && this.timer === undefined)
this.timer = setTimeout(this.setNetworkGameAttributesImmediately.bind(this), this.Timeout);
}
setNetworkGameAttributesImmediately()
{
delete this.timer;
if (g_IsNetworked)
Engine.SetNetworkGameAttributes(g_GameAttributes);
}
@ -274,12 +284,17 @@ class GameSettingsControl
for (let handler of this.gameAttributesFinalizeHandlers)
handler();
this.setNetworkGameAttributes();
this.setNetworkGameAttributesImmediately();
}
}
GameSettingsControl.prototype.MaxDepth = 512;
/**
* Wait (at most) this many milliseconds before sending network messages.
*/
GameSettingsControl.prototype.Timeout = 400;
/**
* This number is used when selecting the random map type, which doesn't provide PlayerData.
*/

View File

@ -60,8 +60,11 @@ class GameSettingControlSlider extends GameSettingControl
onValueChangeSuper()
{
if (!this.isInGuiUpdate)
this.onValueChange(this.slider.value);
if (!this.isInGuiUpdate && !this.timer)
this.timer = setTimeout(() => {
this.onValueChange(this.slider.value);
delete this.timer;
}, this.Timeout);
}
onPress()
@ -75,5 +78,7 @@ class GameSettingControlSlider extends GameSettingControl
}
}
GameSettingControlSlider.prototype.Timeout = 50;
GameSettingControlSlider.prototype.UnknownValue =
translateWithContext("settings value", "Unknown");