Skip to content

Instantly share code, notes, and snippets.

@jameslkingsley
Created June 22, 2016 01:21
Show Gist options
  • Save jameslkingsley/5ec121ce184007c7ca2ff48d31cb6837 to your computer and use it in GitHub Desktop.
Save jameslkingsley/5ec121ce184007c7ca2ff48d31cb6837 to your computer and use it in GitHub Desktop.
callOverMultipleFrames
/*
* Author: Kingsley
* Calls the given code over multiple frames until all code has been executed
* Think of this as a PFH version of spawn
*
* Arguments:
* 0: Code to execute <CODE/STRING>
* 1: Arguments to pass to code <ARRAY>
* 2: Number of lines to execute per frame <NUMBER>
*
* Return Value:
* PFH Handler ID <NUMBER>
*
* Example:
* _handle = [{}, [], 2] call mars_common_fnc_callOverMultipleFrames;
*
* Public: Yes
*/
#include "script_component.hpp"
params [
["_code", {}, ["", {}]],
["_args", [], [[]]],
["_lines", 1, [0, []]]
];
if (_code isEqualType {}) then {
_code = _code call FUNC(codeToString);
};
if (_lines isEqualType []) then {
_lines params ["_perFrameLines", "_perFrameDelay"];
} else {
private _perFrameLines = _lines;
private _perFrameDelay = 0;
};
_codeLines = (_code splitString ";") apply {[_x] call CBA_fnc_leftTrim};
diag_log ""; diag_log ""; diag_log ""; diag_log ""; diag_log "";
MARS_LOGINFO_1("Lines to process: %1", _codeLines);
_handle = [{
params ["_argsPFH", "_handlePFH"];
_getExecIndex = {
params ["_targetIndex"];
private _result = -1;
{
_x params ["_thisIndex"];
if (_thisIndex == _targetIndex) exitWith {
_result = _forEachIndex;
};
} forEach GVAR(frameExecutions);
_result
};
private _thisExecIndex = _handlePFH call _getExecIndex;
if (_thisExecIndex == -1) exitWith {};
private _thisExec = GVAR(frameExecutions) select _thisExecIndex;
if (_thisExec isEqualTo []) exitWith {
[_handlePFH] call CBA_fnc_removePerFrameHandler;
MARS_LOGINFO("Couldn't find frame execution data");
};
_thisExec params ["_handleID", "_args", "_numberOfLines", "_codeLines", "_privates"];
if (_codeLines isEqualTo []) exitWith {
[_handlePFH] call CBA_fnc_removePerFrameHandler;
GVAR(frameExecutions) deleteAt _thisExecIndex;
MARS_LOGINFO("No more lines to execute - removing handler");
};
_privatesToString = {
params ["_privates"];
private _strings = [];
{
_x params ["_key", "_value"];
MARS_LOGINFO_2("Joining pairs: %1 = %2", _key, _value);
_strings pushBack format ["%1 = %2", _key, _value];
} forEach _privates;
([(_strings joinString ";"), ""] select (_strings isEqualTo []))
};
{
if (_numberOfLines == (_forEachIndex + 1)) exitWith {
MARS_LOGINFO("Reached line limit");
};
MARS_LOGINFO_1("Frame privates: %1", _privates);
private _line = _x;
private _usePrivates = [_privates] call _privatesToString;
MARS_LOGINFO_1("Processing line: %1", _line);
MARS_LOGINFO_1("Using privates: %1", _usePrivates);
if ((_line select [0,1]) == "_" || {(_line select [0,7]) == "private"}) then {
private _chars = _line splitString "=";
private _key = [(_chars select 0)] call CBA_fnc_trim;
private _returnKey = [_key, "private", ""] call CBA_fnc_replace;
_chars deleteAt 0;
private _joinedChars = _chars joinString "=";
private _value = [
format ["%1;%2", _usePrivates, _joinedChars],
format ["%1", [_joinedChars, ";", ""] call CBA_fnc_replace]
] select (_usePrivates == "");
MARS_LOGINFO_1("Prep private value: %1", _value);
_value = call compile _value;
_privates pushBack [_key, _value];
MARS_LOGINFO_2("Add private: %1 = %2", _key, _value);
} else {
private _execStr = format ["%1;%2", _usePrivates, _line];
call compile _execStr;
MARS_LOGINFO_2("Executed at frame %1: %2", diag_frameNo, _execStr);
};
_codeLines deleteAt 0;
} forEach _codeLines;
GVAR(frameExecutions) set [_thisExecIndex, [
_handleID,
_args,
_numberOfLines,
_codeLines,
_privates
]];
MARS_LOGINFO_2("Frame execution data at frame %1: %2", diag_frameNo, GVAR(frameExecutions));
}, _perFrameDelay, []] call CBA_fnc_addPerFrameHandler;
GVAR(frameExecutions) pushBack [
_handle,
_args,
_perFrameLines,
_codeLines,
[]
];
_handle
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment