Cache config UI (#4234)

* Cache config UI

* Use configClasses to prevent reading entries in base class

* Fix header not containing return value

* One more count

* More lazy eval
This commit is contained in:
jonpas 2016-08-18 19:07:05 +02:00 committed by GitHub
parent 468662b46e
commit 986ac43a68
9 changed files with 104 additions and 79 deletions

View File

@ -1,7 +1,3 @@
#define ANYWHERE 0
#define GROUND_ONLY 1
#define VEHICLE_ONLY 2
class ACE_UI { class ACE_UI {
class weaponName { class weaponName {
idd = 300; idd = 300;

View File

@ -1,4 +1,4 @@
PREP(findSetElement); PREP(compileConfigUI);
PREP(moduleInit); PREP(moduleInit);
PREP(setAdvancedElement); PREP(setAdvancedElement);
PREP(setElements); PREP(setElements);

View File

@ -3,6 +3,14 @@
// Exit on Headless // Exit on Headless
if (!hasInterface) exitWith {}; if (!hasInterface) exitWith {};
// Compile and cache config UI
GVAR(configCache) = call CBA_fnc_createNamespace;
call FUNC(compileConfigUI);
// Scripted API namespace
GVAR(elementsSet) = call CBA_fnc_createNamespace;
// Attach all event handlers where UI has to be updated
["ace_settingsInitialized", { ["ace_settingsInitialized", {
// Initial settings // Initial settings
[false] call FUNC(setElements); [false] call FUNC(setElements);
@ -13,9 +21,8 @@ if (!hasInterface) exitWith {};
// Defaults must be set in this EH to make sure controls are activated and advanced settings can be modified // Defaults must be set in this EH to make sure controls are activated and advanced settings can be modified
private _force = [true, false] select (GVAR(allowSelectiveUI)); private _force = [true, false] select (GVAR(allowSelectiveUI));
{ {
private _name = configName _x; [_x, missionNamespace getVariable (format [QGVAR(%1), _x]), false, _force] call FUNC(setAdvancedElement);
[_name, missionNamespace getVariable (format [QGVAR(%1), _name]), false, _force] call FUNC(setAdvancedElement); } forEach (allVariables GVAR(configCache));
} forEach ("true" configClasses (configFile >> "ACE_UI"));
// Execute local event for when it's safe to modify UI through this API // Execute local event for when it's safe to modify UI through this API
// infoDisplayChanged can execute multiple times, make sure it only happens once // infoDisplayChanged can execute multiple times, make sure it only happens once
@ -32,10 +39,11 @@ if (!hasInterface) exitWith {};
if (_name in ELEMENTS_BASIC) then { if (_name in ELEMENTS_BASIC) then {
[true] call FUNC(setElements); [true] call FUNC(setElements);
} else { } else {
if (isClass (configFile >> "ACE_UI" >> _name select [7])) then { private _nameNoPrefix = toLower (_name select [7]);
[_name select [7], missionNamespace getVariable _name, true] call FUNC(setAdvancedElement); private _cachedElement = GVAR(configCache) getVariable _nameNoPrefix;
if (!isNil "_cachedElement") then {
[_nameNoPrefix, missionNamespace getVariable _name, true] call FUNC(setAdvancedElement);
}; };
}; };
}] call CBA_fnc_addEventHandler; }] call CBA_fnc_addEventHandler;
}] call CBA_fnc_addEventHandler; }] call CBA_fnc_addEventHandler;

View File

@ -4,7 +4,6 @@ ADDON = false;
#include "XEH_PREP.hpp" #include "XEH_PREP.hpp"
GVAR(elementsSet) = [];
GVAR(interfaceInitialized) = false; GVAR(interfaceInitialized) = false;
ADDON = true; ADDON = true;

View File

@ -0,0 +1,45 @@
/*
* Author: Jonpas
* Compiles and caches UI from ACE_UI config.
*
* Arguments:
* None
*
* Return Value:
* None
*
* Example:
* [] call ace_ui_fnc_compileConfigUI
*
* Public: No
*/
#include "script_component.hpp"
{
private _failure = false;
private _class = toLower (configName _x);
private _idd = getNumber (_x >> "idd");
private _elements = getArray (_x >> "elements");
if (_elements isEqualTo []) then {
ACE_LOGERROR_1("Failed compiling ACE_UI for Element: %1 - missing elements",_class);
_failure = true;
};
private _location = getNumber (_x >> "location");
if !(_location in [ANYWHERE, GROUND_ONLY, VEHICLE_ONLY]) then {
ACE_LOGERROR_2("Failed compiling ACE_UI for Element: %1 - missing or invalid location %2",_class,_location);
_failure = true;
};
if (!_failure) then {
private _conditions = [];
{
_conditions pushBack [compile (getText _x), configName _x];
TRACE_1("Caching Condition",_x);
} forEach (configProperties [_x >> "conditions"]);
GVAR(configCache) setVariable [_class, [_idd, _elements, _location, _conditions]];
};
} forEach ("true" configClasses (configFile >> "ACE_UI"));

View File

@ -1,25 +0,0 @@
/*
* Author: Jonpas
* Finds set element by element name and returns index, source of the set element and state.
*
* Arguments:
* 0: Element Name <STRING>
*
* Return Value:
* None
*
* Example:
* ["ace_ui_ammoCount"] call ace_ui_fnc_findSetElement
*
* Public: No
*/
#include "script_component.hpp"
params ["_element"];
{
if (_element in _x) exitWith {
[_forEachIndex, _x select 0, _x select 2]
};
[-1, "", false]
} forEach GVAR(elementsSet);

View File

@ -12,7 +12,7 @@
* Successfully Set <BOOL> * Successfully Set <BOOL>
* *
* Example: * Example:
* ["ace_ui_ammoCount", true, false] call ace_ui_fnc_setAdvancedElement * _successfullySet = ["ammoCount", true, false] call ace_ui_fnc_setAdvancedElement
* *
* Public: No * Public: No
*/ */
@ -20,43 +20,40 @@
params ["_element", "_show", ["_showHint", false, [true]], ["_force", false, [true]] ]; params ["_element", "_show", ["_showHint", false, [true]], ["_force", false, [true]] ];
private _cachedElement = GVAR(configCache) getVariable _element;
if (isNil "_cachedElement") exitWith {};
if (!_force && {!GVAR(allowSelectiveUI)}) exitWith { if (!_force && {!GVAR(allowSelectiveUI)}) exitWith {
[LSTRING(Disallowed), 2] call EFUNC(common,displayTextStructured); [LSTRING(Disallowed), 2] call EFUNC(common,displayTextStructured);
false false
}; };
private _config = configFile >> "ACE_UI" >> _element; _cachedElement params ["_idd", "_elements", "_location", "_conditions"];
// Exit if main vehicle type condition not fitting // Exit if main vehicle type condition not fitting
private _location = getNumber (_config >> "location"); // (0-both, 1-ground, 2-vehicle)
private _canUseWeapon = ACE_player call CBA_fnc_canUseWeapon; private _canUseWeapon = ACE_player call CBA_fnc_canUseWeapon;
if ((_canUseWeapon && _location == 2) || (!_canUseWeapon && _location == 1)) exitWith {false}; if ((_canUseWeapon && {_location == 2}) || {!_canUseWeapon && {_location == 1}}) exitWith {false};
private _idd = getNumber (_config >> "idd");
private _elements = getArray (_config >> "elements");
// Get setting from config API // Get setting from config API
{ {
private _condition = call compile (getText _x); if (!call (_x select 0)) exitWith {
if !(_condition) exitWith {
// Display and print info which component forced the element except for default vehicle check // Display and print info which component forced the element except for default vehicle check
if (_showHint) then { if (_showHint) then {
[LSTRING(Disabled), 2] call EFUNC(common,displayTextStructured); [LSTRING(Disabled), 2] call EFUNC(common,displayTextStructured);
ACE_LOGINFO_2("Attempted modification of a forced User Interface element '%1' by '%2'",_element,configName _x); ACE_LOGINFO_2("Attempted modification of a forced User Interface element '%1' by '%2'.",_element,_x select 1);
}; };
_show = false; _show = false;
}; };
} forEach (configProperties [_config >> "conditions"]); } count _conditions;
// Get setting from scripted API // Get setting from scripted API
if (!_force) then { if (!_force) then {
private _setElement = [_element] call FUNC(findSetElement); private _setElement = GVAR(elementsSet) getVariable _element;
_setElement params ["_indexSet", "_sourceSet", "_showSet"]; if (!isNil "_setElement") then {
_setElement params ["_sourceSet", "_showSet"];
if (_indexSet != -1) then {
if (_showHint) then { if (_showHint) then {
[LSTRING(Disabled), 2] call EFUNC(common,displayTextStructured); [LSTRING(Disabled), 2] call EFUNC(common,displayTextStructured);
ACE_LOGINFO_2("Attempted modification of a forced User Interface element '%1' by '%2'",_element,_sourceSet); ACE_LOGINFO_2("Attempted modification of a forced User Interface element '%1' by '%2'.",_element,_sourceSet);
}; };
_show = _showSet; _show = _showSet;
}; };
@ -79,7 +76,8 @@ private _success = false;
_success = true; _success = true;
}; };
} forEach (uiNamespace getVariable "IGUI_displays"); } count (uiNamespace getVariable "IGUI_displays");
} forEach _elements; nil
} count _elements;
_success _success

View File

@ -9,10 +9,10 @@
* 3: Show/Hide Element <BOOL> (default: false) * 3: Show/Hide Element <BOOL> (default: false)
* *
* Return Value: * Return Value:
* None * Successfully Modified <BOOL>
* *
* Example: * Example:
* ["ace_reload", true, "ace_ui_ammoCount", false] call ace_ui_fnc_setElementVisibility * _successfullyModified = ["ace_reload", true, "ammoCount", false] call ace_ui_fnc_setElementVisibility
* *
* Public: Yes * Public: Yes
*/ */
@ -25,45 +25,44 @@ params [
["_show", false, [true]] ["_show", false, [true]]
]; ];
// Verify element is bound
if (!isClass (configFile >> "ACE_UI" >> _element)) exitWith {
ACE_LOGWARNING_1("Element '%1' does not exist",_element);
};
if (_source == "" || {_element == ""}) exitWith { if (_source == "" || {_element == ""}) exitWith {
ACE_LOGWARNING("Source or Element may not be empty strings!"); ACE_LOGWARNING("Source or Element may not be empty strings!");
}; };
_element = toLower _element;
// Verify element is bound
private _cachedElement = GVAR(configCache) getVariable _element;
if (isNil "_cachedElement") exitWith {
ACE_LOGWARNING_2("Element '%1' does not exist - modification by '%2' failed.",_element,_source);
};
private _setElement = GVAR(elementsSet) getVariable _element;
private _return = false; private _return = false;
private _setElement = [_element] call FUNC(findSetElement); if (isNil "_setElement") then {
_setElement params ["_indexSet", "_sourceSet"]; TRACE_3("Setting element",_source,_element,_show);
if (_set) then {
// Exit if element has been set from another component, print warning if after interface initialization
if (_indexSet != -1) exitWith {
if (GVAR(interfaceInitialized)) then {
ACE_LOGWARNING_2("Element '%1' already set by %2",_element,_sourceSet);
};
};
TRACE_4("Setting element",_source,_element,_show,GVAR(elementsSet));
private _success = [_element, _show, false, true] call FUNC(setAdvancedElement); private _success = [_element, _show, false, true] call FUNC(setAdvancedElement);
if (_success) then { if (_success) then {
GVAR(elementsSet) pushBack [_source, _element, _show]; GVAR(elementsSet) setVariable [_element, [_source, _show]];
_return = true; _return = true;
}; };
} else { } else {
if (_indexSet != -1) then { _setElement params ["_sourceSet"];
TRACE_4("Unsetting element",_sourceSet,_element,_show,GVAR(elementsSet));
GVAR(elementsSet) deleteAt _indexSet; if (_set) then {
if (GVAR(interfaceInitialized)) then {
ACE_LOGWARNING_3("Element '%1' already set by '%2' - modification by '%3' failed.",_element,_sourceSet,_source);
};
} else {
TRACE_3("Unsetting element",_sourceSet,_element,_show);
GVAR(elementsSet) setVariable [_element, nil];
[_element, _show, false, true] call FUNC(setAdvancedElement); [_element, _show, false, true] call FUNC(setAdvancedElement);
_return = true; _return = true;
}; };
}; };
TRACE_2("Visibility set",_return,GVAR(elementsSet)); TRACE_2("Visibility set",_element,_return);
_return _return

View File

@ -21,6 +21,11 @@
// Basic Elements // Basic Elements
#define ELEMENTS_BASIC [QGVAR(soldierVehicleWeaponInfo), QGVAR(vehicleRadar), QGVAR(vehicleCompass), QGVAR(commandMenu), QGVAR(groupBar)] #define ELEMENTS_BASIC [QGVAR(soldierVehicleWeaponInfo), QGVAR(vehicleRadar), QGVAR(vehicleCompass), QGVAR(commandMenu), QGVAR(groupBar)]
// Locations
#define ANYWHERE 0
#define GROUND_ONLY 1
#define VEHICLE_ONLY 2
/* /*
RscUnitInfo = 300 RscUnitInfo = 300
-------------------- --------------------