Make options page agnostic of session page and implement RangeOverlayManager GUI class, refs #5387, #4747.

Avoids further session commits that missed to keep options.json session
code in sync,
enables use of anonymous or object owned config callback handlers and
encourages session developers to make the GUI more reactive to changing
options.

Update RangeOverlays when reseting to default, and update
RangeOverlays of selected entities upon closing the page too (not only
hotkey).

Differential Revision: https://code.wildfiregames.com/D2389
This was SVN commit r23091.
This commit is contained in:
elexis 2019-10-25 11:56:20 +00:00
parent b859195064
commit 3fc18b9be3
8 changed files with 142 additions and 83 deletions

View file

@ -4,9 +4,9 @@
var g_Options;
/**
* Names of session functions to be called after closing the page.
* Names of config keys that have changed, value returned when closing the page.
*/
var g_CloseCallbacks;
var g_ChangedKeys;
/**
* Vertical size of a tab button.
@ -165,7 +165,7 @@ var g_OptionType = {
function init(data, hotloadData)
{
g_CloseCallbacks = hotloadData ? hotloadData.closeCallbacks : new Set();
g_ChangedKeys = hotloadData ? hotloadData.changedKeys : new Set();
g_TabCategorySelected = hotloadData ? hotloadData.tabCategorySelected : 0;
g_Options = Engine.ReadJSONFile("gui/options/options.json");
@ -184,7 +184,7 @@ function getHotloadData()
{
return {
"tabCategorySelected": g_TabCategorySelected,
"closeCallbacks": g_CloseCallbacks
"changedKeys": g_ChangedKeys
};
}
@ -242,12 +242,11 @@ function displayOptions()
Engine.ConfigDB_CreateValue("user", option.config, String(value));
Engine.ConfigDB_SetChanges("user", true);
g_ChangedKeys.add(option.config);
if (option.function)
Engine[option.function](value);
if (option.callback)
g_CloseCallbacks.add(option.callback);
enableButtons();
};
@ -301,7 +300,10 @@ function reallySetDefaults()
{
for (let category in g_Options)
for (let option of g_Options[category].options)
{
Engine.ConfigDB_RemoveValue("user", option.config);
g_ChangedKeys.add(option.config);
}
Engine.ConfigDB_WriteFile("user", "config/user.cfg");
revertChanges();
@ -359,7 +361,7 @@ function reallySaveChanges()
}
/**
* Close GUI page and call callbacks if they exist.
* Close GUI page and inform the parent GUI page which options changed.
**/
function closePage()
{
@ -376,5 +378,5 @@ function closePage()
function closePageWithoutConfirmation()
{
Engine.PopGuiPage(g_CloseCallbacks);
Engine.PopGuiPage(g_ChangedKeys);
}

View file

@ -422,7 +422,6 @@
"label": "Batch Training Size",
"tooltip": "Number of units trained per batch by default.",
"config": "gui.session.batchtrainingsize",
"callback": "updateDefaultBatchSize",
"min": 1,
"max": 20
},
@ -467,22 +466,19 @@
"type": "boolean",
"label": "Attack Range Visualization",
"tooltip": "Display the attack range of selected defensive structures (can also be toggled in-game with the hotkey).",
"config": "gui.session.attackrange",
"callback": "updateEnabledRangeOverlayTypes"
"config": "gui.session.attackrange"
},
{
"type": "boolean",
"label": "Aura Range Visualization",
"tooltip": "Display the range of auras of selected units and structures (can also be toggled in-game with the hotkey).",
"config": "gui.session.aurasrange",
"callback": "updateEnabledRangeOverlayTypes"
"config": "gui.session.aurasrange"
},
{
"type": "boolean",
"label": "Heal Range Visualization",
"tooltip": "Display the healing range of selected units (can also be toggled in-game with the hotkey).",
"config": "gui.session.healrange",
"callback": "updateEnabledRangeOverlayTypes"
"config": "gui.session.healrange"
},
{
"type": "boolean",
@ -517,29 +513,25 @@
"type": "color",
"label": "Diplomacy Colors: Self",
"tooltip": "Color of your units when diplomacy colors are enabled.",
"config": "gui.session.diplomacycolors.self",
"callback": "updateDisplayedPlayerColors"
"config": "gui.session.diplomacycolors.self"
},
{
"type": "color",
"label": "Diplomacy Colors: Ally",
"tooltip": "Color of allies when diplomacy colors are enabled.",
"config": "gui.session.diplomacycolors.ally",
"callback": "updateDisplayedPlayerColors"
"config": "gui.session.diplomacycolors.ally"
},
{
"type": "color",
"label": "Diplomacy Colors: Neutral",
"tooltip": "Color of neutral players when diplomacy colors are enabled.",
"config": "gui.session.diplomacycolors.neutral",
"callback": "updateDisplayedPlayerColors"
"config": "gui.session.diplomacycolors.neutral"
},
{
"type": "color",
"label": "Diplomacy Colors: Enemy",
"tooltip": "Color of enemies when diplomacy colors are enabled.",
"config": "gui.session.diplomacycolors.enemy",
"callback": "updateDisplayedPlayerColors"
"config": "gui.session.diplomacycolors.enemy"
}
]
}

View file

@ -16,6 +16,7 @@ class DiplomacyColors
this.diplomacyColorsChangeHandlers = [];
registerPlayersInitHandler(this.onPlayersInit.bind(this));
registerConfigChangeHandler(this.onConfigChange.bind(this));
}
registerDiplomacyColorsChangeHandler(handler)
@ -40,6 +41,16 @@ class DiplomacyColors
this.updateDisplayedPlayerColors();
}
onConfigChange(changes)
{
for (let change of changes)
if (change.startsWith("gui.session.diplomacycolors."))
{
this.updateDisplayedPlayerColors();
return;
}
}
isEnabled()
{
return this.enabled;

View file

@ -168,11 +168,8 @@ MenuButtons.prototype.Options = class
Engine.PushGuiPage(
"page_options.xml",
{},
callbackFunctionNames => {
for (let functionName of callbackFunctionNames)
if (global[functionName])
global[functionName]();
changes => {
fireConfigChangeHandlers(changes);
resumeGame();
});
}

View file

@ -0,0 +1,80 @@
/**
* This class informs:
* - the GuiInterface of which components of entities are to display range overlays and
* - the RangeOverlayManager entity component which entities are to display range overlays.
*/
class RangeOverlayManager
{
constructor(selection)
{
this.selection = selection;
for (let type of this.Types)
{
this.setEnabled(type, this.isEnabled(type));
Engine.SetGlobalHotkey(type.hotkey, this.toggle.bind(this, type));
}
registerConfigChangeHandler(this.onConfigChange.bind(this));
}
onConfigChange(changes)
{
for (let type of this.Types)
if (changes.has(type.config))
this.setEnabled(type, this.isEnabled(type));
}
isEnabled(type)
{
return Engine.ConfigDB_GetValue("user", type.config) == "true";
}
setEnabled(type, enabled)
{
Engine.GuiInterfaceCall("EnableVisualRangeOverlayType", {
"type": type.component,
"enabled": enabled
});
let selected = this.selection.toList();
for (let ent in this.selection.highlighted)
selected.push(this.selection.highlighted[ent]);
Engine.GuiInterfaceCall("SetRangeOverlays", {
"entities": selected,
"enabled": enabled
});
}
toggle(type)
{
let enabled = !this.isEnabled(type);
Engine.ConfigDB_CreateAndWriteValueToFile(
"user",
type.config,
String(enabled),
"config/user.cfg");
this.setEnabled(type, enabled);
}
}
RangeOverlayManager.prototype.Types = [
{
"component": "Attack",
"config": "gui.session.attackrange",
"hotkey": "session.toggleattackrange"
},
{
"component": "Auras",
"config": "gui.session.aurasrange",
"hotkey": "session.toggleaurasrange"
},
{
"component": "Heal",
"config": "gui.session.healrange",
"hotkey": "session.togglehealrange"
}
];

View file

@ -65,18 +65,6 @@
<action on="Press">clearSelection();</action>
</object>
<object hotkey="session.toggleattackrange">
<action on="Press">toggleRangeOverlay("Attack");</action>
</object>
<object hotkey="session.toggleaurasrange">
<action on="Press">toggleRangeOverlay("Auras");</action>
</object>
<object hotkey="session.togglehealrange">
<action on="Press">toggleRangeOverlay("Heal");</action>
</object>
<object hotkey="session.showstatusbars">
<action on="Press">
g_ShowAllStatusBars = !g_ShowAllStatusBars;

View file

@ -1327,6 +1327,14 @@ function getBuildingsWhichCanTrainEntity(entitiesToCheck, trainEntType)
});
}
function initBatchTrain()
{
registerConfigChangeHandler(changes => {
if (changes.has("gui.session.batchtrainingsize"))
updateDefaultBatchSize();
});
}
function getDefaultBatchTrainingSize()
{
let num = +Engine.ConfigDB_GetValue("user", "gui.session.batchtrainingsize");

View file

@ -22,6 +22,7 @@ var g_PanelEntityManager;
var g_PauseControl;
var g_PauseOverlay;
var g_PlayerViewControl;
var g_RangeOverlayManager;
var g_ResearchProgress;
var g_TradeDialog;
var g_TopPanel;
@ -158,6 +159,12 @@ var g_EntitySelectionChangeHandlers = new Set();
*/
var g_HotkeyChangeHandlers = new Set();
/**
* These events are fired when the user has closed the options page.
* The handlers are provided a Set storing which config values have changed.
*/
var g_ConfigChangeHandlers = new Set();
/**
* List of additional entities to highlight.
*/
@ -280,16 +287,17 @@ function init(initData, hotloadData)
g_PauseControl = new PauseControl();
g_PauseOverlay = new PauseOverlay(g_PauseControl);
g_Menu = new Menu(g_PauseControl, g_PlayerViewControl, g_Chat);
g_RangeOverlayManager = new RangeOverlayManager(g_Selection);
g_ResearchProgress = new ResearchProgress(g_PlayerViewControl, g_Selection);
g_TradeDialog = new TradeDialog(g_PlayerViewControl);
g_TopPanel = new TopPanel(g_PlayerViewControl, g_DiplomacyDialog, g_TradeDialog, g_ObjectivesDialog, g_GameSpeedControl);
initBatchTrain();
initSelectionPanels();
LoadModificationTemplates();
updatePlayerData();
initializeMusic(); // before changing the perspective
Engine.SetBoundingBoxDebugOverlay(false);
updateEnabledRangeOverlayTypes();
for (let handler of g_PlayersInitHandlers)
handler();
@ -345,6 +353,20 @@ function registerHotkeyChangeHandler(handler)
g_HotkeyChangeHandlers.add(handler);
}
function registerConfigChangeHandler(handler)
{
g_ConfigChangeHandlers.add(handler);
}
/**
* @param changes - a Set of config names
*/
function fireConfigChangeHandlers(changes)
{
for (let handler of g_ConfigChangeHandlers)
handler(changes);
}
function updatePlayerData()
{
let simState = GetSimState();
@ -393,15 +415,6 @@ function updatePlayerData()
g_Players = playerData;
}
/**
* Called when the user changed the diplomacy colors in the options.
* TODO: Remove this proxy and make the options page agnostic of the session page.
*/
function updateDisplayedPlayerColors()
{
g_DiplomacyColors.updateDisplayedPlayerColors();
}
/**
* Returns the entity itself except when garrisoned where it returns its garrisonHolder
*/
@ -809,38 +822,6 @@ function toggleConfigBool(configName)
return enabled;
}
/**
* Toggles the display of range overlays of selected entities for the given range type.
* @param {string} type - for example "Auras"
*/
function toggleRangeOverlay(type)
{
let enabled = toggleConfigBool("gui.session." + type.toLowerCase() + "range");
Engine.GuiInterfaceCall("EnableVisualRangeOverlayType", {
"type": type,
"enabled": enabled
});
let selected = g_Selection.toList();
for (let ent in g_Selection.highlighted)
selected.push(g_Selection.highlighted[ent]);
Engine.GuiInterfaceCall("SetRangeOverlays", {
"entities": selected,
"enabled": enabled
});
}
function updateEnabledRangeOverlayTypes()
{
for (let type of ["Attack", "Auras", "Heal"])
Engine.GuiInterfaceCall("EnableVisualRangeOverlayType", {
"type": type,
"enabled": Engine.ConfigDB_GetValue("user", "gui.session." + type.toLowerCase() + "range") == "true"
});
}
// Update the additional list of entities to be highlighted.
function updateAdditionalHighlight()
{