Home   Help Search Login Register  

Author Topic: Fast dump of config  (Read 5963 times)

0 Members and 1 Guest are viewing this topic.

Offline Denisko-Redisko

  • Members
  • *
Fast dump of config
« on: 03 Oct 2010, 10:13:58 »
Code: [Select]
//
// dumpConfig.sqf
// Copyright (c) 2010 Denis Usenko, DenVdmj@gmail.com
// MIT-style license
//

/*
======================================================================================

Dump config to the clipboard:

    [config HNDL, bool IncludeInheritedPropertiesFlag] call compile preprocessFileLineNumbers "dumpConfig.sqf"

This example put section CfgVehicles on the clipboard:

    [configFile >> "CfgVehicles"] call compile preprocessFileLineNumbers "dumpConfig.sqf"

This example will put on the clipboard class "RscDisplayArcadeUnit", all classes will contain all heritable properties, so you get a full and self-sufficient class, independent from the other classes.

    [configFile >> "RscDisplayArcadeUnit", true] call compile preprocessFileLineNumbers "dumpConfig.sqf"

More examples:

    [configFile >> "RscTitle", true] call compile preprocessFileLineNumbers "dumpConfig.sqf"
    [configFile >> "RscEdit", true] call compile preprocessFileLineNumbers "dumpConfig.sqf"
    [configFile >> "RscToolbox", true] call compile preprocessFileLineNumbers "dumpConfig.sqf"

Warning: don't attempt to get a large classes with switched on parameter "IncludeInheritedPropertiesFlag", eg don't do so:

    [configFile, true] call compile preprocessFileLineNumbers "dumpConfig.sqf"

Dump the entire config, it can take over ten seconds:

    [configFile] call compile preprocessFileLineNumbers "dumpConfig.sqf"

======================================================================================
*/

//
// #include "\rls\common";
//

#define arg(x)          (_this select (x))
#define argIf(x)        if(count _this > (x))
#define argIfType(x,t)  if(argIf(x)then{typeName arg(x) == (t)}else{false})
#define argSafe(x)      argIf(x)then{arg(x)}
#define argSafeType(x,t)  argIfType(x,t)then{arg(x)}
#define argOr(x,v)      (argSafe(x)else{v})
#define push(a,v)       (a)set[count(a),(v)]
#define pushTo(a)       call{(a)set[count(a),_this]}
#define log2(number)    ((log number)/.3010299956639812)

private [
    "_joinString",
    "_escapeString",
    "_collectInheritedProperties",
    "_dumpConfigTree"
];

_joinString = {
    //
    // Fast string concatenation,
    //
    private ["_list", "_char", "_size", "_subsize", "_oversize", "_j"];

    _list = arg(0);
    _char = arg(1);

    if( count _list < 1 ) exitwith {""};

    // while { count _list > 1 } do {
    for "" from 1 to ceil(log2(count _list)) do {
        _size = count _list / 2;
        _subsize = floor _size;
        _oversize = ceil _size;
        _j = 0;
        for "_i" from 0 to _subsize - 1 do {
            _list set [_i, (_list select _j) + _char + (_list select (_j+1))];
            _j = _j + 2;
        };
        if( _subsize != _oversize ) then { // to add a tail
            _list set [_j/2, _list select _j];
        };
        _list resize _oversize;
    };

    _list select 0;
};

_escapeString = {
    private ["_source", "_target", "_start", "_charCode"];
    _source = toArray _this;
    _start = _source find 34;
    if(_start > 0) then {
        _target = +_source;
        _target resize _start;
        for "_i" from _start to count _source - 1 do {
            _charCode = _source select _i;
            push(_target, _charCode);
            if(_charCode == 34) then {
                push(_target, _charCode);
            };
        };
        str toString _target;
    } else {
        str _this;
    };
};

_collectInheritedProperties = {
    private [
        "_config",
        "_className",
        "_propertyNameList",
        "_propertyNameLCList",
        "_propertyName",
        "_propertyNameLC"
    ];
    _config = _this;
    _propertyNameList = [];
    _propertyNameLCList = [];
    while {
        _className = configName _config;
        for "_i" from 0 to count _config - 1 do {
            _propertyName = _config select _i;
            _propertyNameLC = toLower configName _propertyName;
            if!(_propertyNameLC in _propertyNameLCList) then {
                push(_propertyNameList, _propertyName);
                push(_propertyNameLCList, _propertyNameLC);
            };
        };
        _className != "";
    } do {
        _config = inheritsFrom _config;
    };
    _propertyNameList;
};

_dumpConfigTree = {
    private [
        "_includeInheritedProperties", "_specifyParentClass",
        "_result", "_indents", "_depth",
        "_pushLine", "_traverse", "_traverseArray"
    ];
    _includeInheritedProperties = argOr(1, false);
    _specifyParentClass = argOr(2, !_includeInheritedProperties);

    _result = [];
    _indents = [""];
    _depth = 0;
    _pushLine = {
        if(_depth >= count _indents) then {
            _indents set [_depth, (_indents select _depth-1) + "    "];
        };
        push(_result, (_indents select _depth) + _this);
    };

    _traverse = {
        private "_confName";
        _confName = configName _this;
        if( isText _this ) exitwith {
            _confName + " = " + (getText _this call _escapeString) + ";" call _pushLine;
        };
        if( isNumber _this ) exitwith {
            _confName + " = " + str getNumber _this + ";" call _pushLine;
        };
        if( isArray _this ) exitwith {
            _confName + "[] = " + (getArray _this call _traverseArray) + ";" call _pushLine;
        };
        if( isClass _this ) exitwith {
            "class " + _confName + (
                configName inheritsFrom _this call {
                    if( _this == "" || !_specifyParentClass ) then { "" } else { " : " + _this }
                }
            ) + " {" call _pushLine;
            if( _includeInheritedProperties ) then {
                _this = _this call _collectInheritedProperties;
            };
            _depth = _depth + 1;
            for "_i" from 0 to count _this - 1 do {
                _this select _i call _traverse
            };
            _depth = _depth - 1;
            "};" call _pushLine;
        };
    };

    _traverseArray = {
        if(typeName _this == "array") exitwith {
            private "_array";
            _array = [];
            for "_i" from 0 to count _this - 1 do {
                push(_array, _this select _i call _traverseArray);
            };
            "{" + ([_array, ", "] call _joinString) + "}";
        };
        if(typeName _this == "string") exitwith {
            _this call _escapeString;
        };
        str _this;
    };

    arg(0) call _traverse;

    [_result, toString [0x0D,0x0A]] call _joinString;
};

private ["_res", "_startTime", "_endTime"];
_startTime = diag_tickTime;
_res = _this call _dumpConfigTree;
_endTime = diag_tickTime;
copyToClipboard _res;
hint format["Ready\nNow get config from clipboard\ntime: %1", _endTime - _startTime];
_res;

sorry for my english

Offline kju

  • Members
  • *
    • PvPScene - The ArmA II multiplayer community
Re: Fast dump of config
« Reply #1 on: 03 Oct 2010, 13:50:45 »
Try http://community.bistudio.com/wiki/startLoadingScreen for it.
Nothing can be faster from what I understand.  :)

Offline Denisko-Redisko

  • Members
  • *
Re: Fast dump of config
« Reply #2 on: 04 Oct 2010, 09:59:24 »
Heh :)
this code:
Code: [Select]
[configFile] call compile preprocessFileLineNumbers "_dumpConfig.sqf";in scheduled environment with startLoadingScreen/endLoadingScreen (from addAction):
time: 28.54
in non scheduled environment with startLoadingScreen/endLoadingScreen (from trigger):
time 25.14, ("start loading screen" wasn't drawn)
in non scheduled environment without startLoadingScreen/endLoadingScreen (from trigger):
time 25.56
« Last Edit: 04 Oct 2010, 10:13:19 by Denisko-Redisko »
sorry for my english

Offline Worldeater

  • Former Staff
  • ****
  • Suum cuique
Re: Fast dump of config
« Reply #3 on: 06 Oct 2010, 07:03:12 »
Good job! :)

Using the clipboard instead of the RPT seems to be the way to go. It also avoids the ugly formatting problem diag_log has... *sigh*
try { return true; } finally { return false; }