Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Common - Add CBA_fnc_execAfterNFrames from ZEN #1584

Merged
merged 5 commits into from
Jul 13, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions addons/common/fnc_execNextFrame.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
Function: CBA_fnc_execNextFrame

Description:
Executes a code once in non sched environment on the next frame.
Executes a code once in non sched environment delayed by n frames.

Parameters:
_function - The function to run. <CODE>
_args - Parameters passed to the function executing. This will be the same array every execution. [optional] <ANY>
_args - Parameters passed to the function executing. This will be the same array every execution. (optional, default: []) <ANY>
_frames - The number of frames the execution will be delayed by. (optional, default: 1) <NUMBER>

Returns:
Nothing
Expand All @@ -21,9 +22,17 @@ Author:
esteldunedain and PabstMirror, donated from ACE3
---------------------------------------------------------------------------- */

params [["_function", {}, [{}]], ["_args", []]];
params [["_function", {}, [{}]], ["_args", []], ["_frames", 1, [0]]];

if (diag_frameno != GVAR(nextFrameNo)) then {
// Do not allow negative or 0 frame delays
_frames = _frames max 1;

if (_frames > 1) exitWith {
GVAR(nextFrameNBuffer) pushBack [diag_frameNo + _frames, _args, _function];
johnb432 marked this conversation as resolved.
Show resolved Hide resolved
GVAR(nextFrameNBufferIsSorted) = false;
};

if (diag_frameNo != GVAR(nextFrameNo)) then {
GVAR(nextFrameBufferA) pushBack [_args, _function];
} else {
GVAR(nextFrameBufferB) pushBack [_args, _function];
Expand Down
40 changes: 35 additions & 5 deletions addons/common/init_perFrameHandler.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ GVAR(lastTickTime) = diag_tickTime;

GVAR(waitAndExecArray) = [];
GVAR(waitAndExecArrayIsSorted) = false;
GVAR(nextFrameNo) = diag_frameno + 1;
GVAR(nextFrameNBuffer) = [];
GVAR(nextFrameNBufferAIsSorted) = false;
GVAR(nextFrameNo) = diag_frameNo + 1;
GVAR(nextFrameBufferA) = [];
GVAR(nextFrameBufferB) = [];
GVAR(waitUntilAndExecArray) = [];
Expand All @@ -22,9 +24,9 @@ GVAR(waitUntilAndExecArray) = [];

// frame number does not match expected; can happen between pre and postInit, save-game load and on closing map
// need to manually set nextFrameNo, so new items get added to buffer B and are not executed this frame
if (diag_frameno != GVAR(nextFrameNo)) then {
TRACE_2("frame mismatch",diag_frameno,GVAR(nextFrameNo));
GVAR(nextFrameNo) = diag_frameno;
if (diag_frameNo != GVAR(nextFrameNo)) then {
TRACE_2("frame mismatch",diag_frameNo,GVAR(nextFrameNo));
GVAR(nextFrameNo) = diag_frameNo;
};

// Execute per frame handlers
Expand All @@ -44,7 +46,9 @@ GVAR(waitUntilAndExecArray) = [];
GVAR(waitAndExecArray) sort true;
GVAR(waitAndExecArrayIsSorted) = true;
};

private _delete = false;

{
if (_x select 0 > CBA_missionTime) exitWith {};

Expand All @@ -54,20 +58,45 @@ GVAR(waitUntilAndExecArray) = [];
GVAR(waitAndExecArray) set [_forEachIndex, objNull];
_delete = true;
} forEach GVAR(waitAndExecArray);

if (_delete) then {
GVAR(waitAndExecArray) = GVAR(waitAndExecArray) - [objNull];
_delete = false;
};


// Execute the exec next n frame functions
if (!GVAR(nextFrameNBufferIsSorted)) then {
GVAR(nextFrameNBuffer) sort true;
GVAR(nextFrameNBufferIsSorted) = true;
};

{
if (_x select 0 > GVAR(nextFrameNo)) exitWith {};

(_x select 1) call (_x select 2);

// Mark the element for deletion so it's not executed ever again
GVAR(nextFrameNBuffer) set [_forEachIndex, objNull];
_delete = true;
} forEach GVAR(nextFrameNBuffer);

if (_delete) then {
GVAR(nextFrameNBuffer) = GVAR(nextFrameNBuffer) - [objNull];
_delete = false;
};


// Execute the exec next frame functions
{
(_x select 0) call (_x select 1);
} forEach GVAR(nextFrameBufferA);

// Swap double-buffer:
GVAR(nextFrameBufferA) = GVAR(nextFrameBufferB);
GVAR(nextFrameBufferB) = [];
GVAR(nextFrameNo) = diag_frameno + 1;

GVAR(nextFrameNo) = diag_frameNo + 1;


// Execute the waitUntilAndExec functions:
Expand All @@ -81,6 +110,7 @@ GVAR(waitUntilAndExecArray) = [];
_delete = true;
};
} forEach GVAR(waitUntilAndExecArray);

if (_delete) then {
GVAR(waitUntilAndExecArray) = GVAR(waitUntilAndExecArray) - [objNull];
};
Expand Down