From 91e5af16474ae8713664b4d06716ab0b938947d7 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Thu, 7 Sep 2023 15:21:07 +0200 Subject: [PATCH] Joint Rails - Optimize `CBA_fnc_compatibleItems` (#1558) --- addons/jr/fnc_compatibleItems.sqf | 91 +++++++++++++++++++------------ 1 file changed, 55 insertions(+), 36 deletions(-) diff --git a/addons/jr/fnc_compatibleItems.sqf b/addons/jr/fnc_compatibleItems.sqf index c1c3ac47a3..e618eefbde 100644 --- a/addons/jr/fnc_compatibleItems.sqf +++ b/addons/jr/fnc_compatibleItems.sqf @@ -19,7 +19,7 @@ Examples: (end) Author: - Original by Karel Moricky, Enhanced by Robalo, jokoho, commy2 + Original by Karel Moricky, Enhanced by Robalo, jokoho, commy2, johnb43 ---------------------------------------------------------------------------- */ SCRIPT(compatibleItems); @@ -27,51 +27,70 @@ params [["_weapon", "", [""]], ["_typefilter", nil, ["", 0]]]; if (_weapon == "") exitWith {[]}; +private _cfgWeapons = configFile >> "CfgWeapons"; +private _weaponConfig = _cfgWeapons >> _weapon; + +// Check if weapon exists +if !(isClass _weaponConfig) exitWith { + ["'%1' not found in CfgWeapons", _weapon] call BIS_fnc_error; + + [] +}; + +// Convert filter into number (if string) +if (_typefilter isEqualType "") then { + _typefilter = [-1, 101, 201, 301, 302] param [["", "muzzle", "optic", "pointer", "bipod"] find _typefilter, -1]; +}; + +private _typeFilterExists = !isNil "_typefilter"; + +// Check if valid type filter +if (_typeFilterExists && {!(_typefilter in [101, 201, 301, 302])}) exitWith {[]}; + if (isNil QGVAR(namespace)) then { - GVAR(namespace) = call CBA_fnc_createNamespace; + GVAR(namespace) = createHashMap; }; -private _compatibleItems = GVAR(namespace) getVariable _weapon; +// Get cached result, if it exists +private _cachekey = format ["%1#%2", _weapon, ["all", _typefilter] select _typeFilterExists]; +private _compatibleItems = GVAR(namespace) get _cachekey; + +if (!isNil "_compatibleItems") exitWith { + +_compatibleItems +}; -if (isNil "_compatibleItems") then { +if (_typeFilterExists) then { + // Get all compatible weapon attachments, then filter + _compatibleItems = _weapon call CBA_fnc_compatibleItems; + _compatibleItems = _compatibleItems select {_typefilter == getNumber (_cfgWeapons >> _x >> "itemInfo" >> "type")}; +} else { _compatibleItems = []; - private _cfgWeapons = configFile >> "CfgWeapons"; - private _weaponConfig = _cfgWeapons >> _weapon; - if (isClass _weaponConfig) then { - { - private _cfgCompatibleItems = _x >> "compatibleItems"; + { + private _cfgCompatibleItems = _x >> "compatibleItems"; - if (isArray _cfgCompatibleItems) then { + if (isArray _cfgCompatibleItems) then { + { + // Ensure item class name is in config case + _compatibleItems pushBackUnique configName (_cfgWeapons >> _x); + } forEach getArray _cfgCompatibleItems; + } else { + if (isClass _cfgCompatibleItems) then { { - _compatibleItems pushBackUnique _x; - } forEach getArray _cfgCompatibleItems; - } else { - if (isClass _cfgCompatibleItems) then { - { - if (getNumber _x > 0) then { - _compatibleItems pushBackUnique configName _x; - }; - } forEach configProperties [_cfgCompatibleItems, "isNumber _x"]; - }; + if (getNumber _x > 0) then { + // Ensure item class name is in config case + _compatibleItems pushBackUnique configName (_cfgWeapons >> configName _x); + }; + } forEach configProperties [_cfgCompatibleItems, "isNumber _x"]; }; - } forEach configProperties [_weaponConfig >> "WeaponSlotsInfo", "isClass _x"]; + }; + } forEach configProperties [_weaponConfig >> "WeaponSlotsInfo", "isClass _x"]; - // Ensure item class names are in config case - _compatibleItems = _compatibleItems apply {configName (_cfgWeapons >> _x)}; - - GVAR(namespace) setVariable [_weapon, _compatibleItems]; // save entry in cache - } else { - ["'%1' not found in CfgWeapons", _weapon] call BIS_fnc_error; - }; + // Remove non-existent item(s) + _compatibleItems deleteAt (_compatibleItems find ""); }; -if (isNil "_typefilter") then { //return - + _compatibleItems -} else { - if (_typefilter isEqualType "") then { - _typefilter = [-1, 101, 201, 301, 302] param [["", "muzzle", "optic", "pointer", "bipod"] find _typefilter, -1]; - }; +// Cache result +GVAR(namespace) set [_cachekey, _compatibleItems]; - _compatibleItems select {_typefilter == getNumber (configFile >> "CfgWeapons" >> _x >> "itemInfo" >> "type")} -}; ++_compatibleItems