loadConfig: Difference between revisions
Jump to navigation
Jump to search
(Add note about config getting destroyed when not referenced directly) |
Lou Montana (talk | contribs) m (Text replacement - "seperat" to "separat") |
||
(2 intermediate revisions by 2 users not shown) | |||
Line 6: | Line 6: | ||
|gr1= Config | |gr1= Config | ||
|descr= Loads the given file as a [[Config]], allowing easy processing of the config file contents using commands such as [[configClasses]], [[configProperties]], [[config greater greater name|>>]], etc. It can load .rvmat, .bisurf, .cpp, .bin, .sqm, and description.ext files (both binarized and unbinarized configs are supported). | |descr= Loads the given file as a [[Config]], allowing easy processing of the config file contents using commands such as [[configClasses]], [[configProperties]], [[config greater greater name|>>]], etc. It can load [[Rvmat File Format|.rvmat]], .bisurf, [[CPP File Format|.cpp]], [[BIN File Formats|.bin]], [[Mission.sqm|.sqm]], and [[Description.ext|description.ext]] files (both binarized and unbinarized configs are supported). | ||
{{Feature|important| | {{Feature|important| | ||
* Config loading can be very slow; the config should only be loaded once and cached, e.g in a [[HashMap]] of {{hl|File Path → Config}} pairs (see {{Link|#Example 3}}). | |||
* It is advised to store the generated config in a variable, otherwise it will get destroyed if it is not being referenced directly (see {{Link|#Example 2}}). | |||
}} | |||
|s1= [[loadConfig]] path | |s1= [[loadConfig]] path | ||
Line 22: | Line 24: | ||
|x2= <sqf> | |x2= <sqf> | ||
// INCORRECT - the config is destroyed after the first operator >> accesses it | |||
getNumber (loadConfig "mission.sqm" >> "ScenarioData" >> "respawnDelay"); | |||
// CORRECT - the config is destroyed only when the variable _cfg is destroyed | |||
_cfg = loadConfig "mission.sqm"; | |||
getNumber (_cfg >> "ScenarioData" >> "respawnDelay"); | |||
</sqf> | |||
|x3= <sqf> | |||
// using a hashmap to cache loaded configs, since loading configs is very slow and should be done once. | // using a hashmap to cache loaded configs, since loading configs is very slow and should be done once. | ||
private _fnc_loadConfig = { | private _fnc_loadConfig = { | ||
params ["_path"]; | params ["_path"]; | ||
// initialize cache if not initialized yet | // initialize cache if not initialized yet | ||
if (isNil "TAG_configCache") then { | if (isNil "TAG_configCache") then | ||
{ | |||
TAG_configCache = createHashMap; | TAG_configCache = createHashMap; | ||
}; | }; | ||
private _cfg = TAG_configCache getOrDefault [_path, configNull]; | private _cfg = TAG_configCache getOrDefault [_path, configNull]; | ||
// if path doesn't exist in the cache or cfg is null, load the config | // if path doesn't exist in the cache or cfg is null, load the config | ||
if (isNull _cfg) then { | if (isNull _cfg) then | ||
{ | |||
_cfg = loadConfig _path; | _cfg = loadConfig _path; | ||
TAG_configCache set [_path, _cfg]; | TAG_configCache set [_path, _cfg]; | ||
Line 41: | Line 54: | ||
</sqf> | </sqf> | ||
| | |x4= <sqf> | ||
// converting a config into hashmap | // converting a config into hashmap | ||
private _fnc_convertClass = { | private _fnc_convertClass = { | ||
Line 48: | Line 61: | ||
private _result = createHashMap; | private _result = createHashMap; | ||
private _props = configProperties [_cfgClass, "true", true]; | private _props = configProperties [_cfgClass, "true", true]; | ||
// | // note: Hashmaps are case-sensitive so configName cases have to be consistent (e.g. all lowercase) | ||
{ | { | ||
if (isNumber _x) then {_result set [toLowerANSI configName _x, getNumber _x]; continue; }; | if (isNumber _x) then { _result set [toLowerANSI configName _x, getNumber _x]; continue; }; | ||
if (isText _x) then {_result set [toLowerANSI configName _x, getText _x]; continue; }; | if (isText _x) then { _result set [toLowerANSI configName _x, getText _x]; continue; }; | ||
if (isArray _x) then {_result set [toLowerANSI configName _x, getArray _x]; continue; }; | if (isArray _x) then { _result set [toLowerANSI configName _x, getArray _x]; continue; }; | ||
} forEach _props; | } forEach _props; | ||
Line 59: | Line 72: | ||
_result set [toLowerANSI configName _x, _x call _fnc_convertClass]; | _result set [toLowerANSI configName _x, _x call _fnc_convertClass]; | ||
} forEach _classes; | } forEach _classes; | ||
_result; | _result; | ||
}; | }; | ||
private _cfg = loadConfig "mission.sqm"; | private _cfg = loadConfig "mission.sqm"; | ||
private _cfgMap = _cfg call _fnc_convertClass; | private _cfgMap = _cfg call _fnc_convertClass; | ||
// | // the following expression is similar to getNumber(_cfg >> "EditorData" >> "moveGridStep") | ||
// | // note that all strings are lowercase (which is how they were stored in hashmap) | ||
_cfgMap get "editordata" get "movegridstep"; | _cfgMap get "editordata" get "movegridstep"; | ||
</sqf> | </sqf> | ||
|seealso= [[loadFile]] [[config greater greater name|>>]] [[configFile]] [[configClasses]] [[isText]] [[isNumber]] [[isArray]] [[isClass]] [[configName]] [[getText]] [[getNumber]] [[getArray]] | |seealso= [[loadFile]] [[config greater greater name|>>]] [[configFile]] [[configClasses]] [[isText]] [[isNumber]] [[isArray]] [[isClass]] [[configName]] [[getText]] [[getNumber]] [[getArray]] | ||
}} | |||
{{Note | {{Note | ||
Line 88: | Line 92: | ||
|text= When trying to load a terrain surface name, like you get from Ammo Eventhandlers when you hit the terrain, you can simply use | |text= When trying to load a terrain surface name, like you get from Ammo Eventhandlers when you hit the terrain, you can simply use | ||
<sqf>private _config = configFile >> "CfgSurfaces" >> _surfaceName;</sqf> | <sqf>private _config = configFile >> "CfgSurfaces" >> _surfaceName;</sqf> | ||
You can recognize surface names by them not having any \ path | You can recognize surface names by them not having any \ path separators in them, they usually start with gdt, for example "gdtvrsurface01". | ||
}} | }} |
Latest revision as of 15:02, 25 May 2023
Description
- Description:
- Loads the given file as a Config, allowing easy processing of the config file contents using commands such as configClasses, configProperties, >>, etc. It can load .rvmat, .bisurf, .cpp, .bin, .sqm, and description.ext files (both binarized and unbinarized configs are supported).
- Groups:
- Config
Syntax
- Syntax:
- loadConfig path
- Parameters:
- path: String - path to the file, which should be in a valid config format.
- Return Value:
- Config - loaded config. Returns configNull if the file doesn't exist.
Examples
- Example 1:
- Example 2:
- // INCORRECT - the config is destroyed after the first operator >> accesses it getNumber (loadConfig "mission.sqm" >> "ScenarioData" >> "respawnDelay"); // CORRECT - the config is destroyed only when the variable _cfg is destroyed _cfg = loadConfig "mission.sqm"; getNumber (_cfg >> "ScenarioData" >> "respawnDelay");
- Example 3:
- // using a hashmap to cache loaded configs, since loading configs is very slow and should be done once. private _fnc_loadConfig = { params ["_path"]; // initialize cache if not initialized yet if (isNil "TAG_configCache") then { TAG_configCache = createHashMap; }; private _cfg = TAG_configCache getOrDefault [_path, configNull]; // if path doesn't exist in the cache or cfg is null, load the config if (isNull _cfg) then { _cfg = loadConfig _path; TAG_configCache set [_path, _cfg]; }; _cfg; }; // the first call will be slow (~0.1200 ms), but subsequent calls are fast (~0.0050 ms) ["a3\data_f\default_super.rvmat"] call _fnc_loadConfig;
- Example 4:
- // converting a config into hashmap private _fnc_convertClass = { params ["_cfgClass"]; private _result = createHashMap; private _props = configProperties [_cfgClass, "true", true]; // note: Hashmaps are case-sensitive so configName cases have to be consistent (e.g. all lowercase) { if (isNumber _x) then { _result set [toLowerANSI configName _x, getNumber _x]; continue; }; if (isText _x) then { _result set [toLowerANSI configName _x, getText _x]; continue; }; if (isArray _x) then { _result set [toLowerANSI configName _x, getArray _x]; continue; }; } forEach _props; private _classes = "true" configClasses _cfgClass; { _result set [toLowerANSI configName _x, _x call _fnc_convertClass]; } forEach _classes; _result; }; private _cfg = loadConfig "mission.sqm"; private _cfgMap = _cfg call _fnc_convertClass; // the following expression is similar to getNumber(_cfg >> "EditorData" >> "moveGridStep") // note that all strings are lowercase (which is how they were stored in hashmap) _cfgMap get "editordata" get "movegridstep";
Additional Information
- See also:
- loadFile >> configFile configClasses isText isNumber isArray isClass configName getText getNumber getArray
Notes
-
Report bugs on the Feedback Tracker and/or discuss them on the Arma Discord or on the Forums.
Only post proven facts here! Add Note
- Posted on Mar 22, 2022 - 09:14 (UTC)
-
When trying to load a terrain surface name, like you get from Ammo Eventhandlers when you hit the terrain, you can simply use
You can recognize surface names by them not having any \ path separators in them, they usually start with gdt, for example "gdtvrsurface01".