From 50df691493ff87b89d5971ff74619d71f68ccd83 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Mon, 10 Jul 2023 19:36:16 +0200 Subject: [PATCH 1/5] Added n frame delay --- addons/common/fnc_execNextFrame.sqf | 17 ++++++++--- addons/common/init_perFrameHandler.sqf | 40 ++++++++++++++++++++++---- 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/addons/common/fnc_execNextFrame.sqf b/addons/common/fnc_execNextFrame.sqf index c81cc92b9f..e3248e91fb 100644 --- a/addons/common/fnc_execNextFrame.sqf +++ b/addons/common/fnc_execNextFrame.sqf @@ -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. - _args - Parameters passed to the function executing. This will be the same array every execution. [optional] + _args - Parameters passed to the function executing. This will be the same array every execution. (optional, default: []) + _frames - The number of frames the execution will be delayed by. (optional, default: 1) Returns: Nothing @@ -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]; + GVAR(nextFrameNBufferIsSorted) = false; +}; + +if (diag_frameNo != GVAR(nextFrameNo)) then { GVAR(nextFrameBufferA) pushBack [_args, _function]; } else { GVAR(nextFrameBufferB) pushBack [_args, _function]; diff --git a/addons/common/init_perFrameHandler.sqf b/addons/common/init_perFrameHandler.sqf index 795211f423..141640cea2 100644 --- a/addons/common/init_perFrameHandler.sqf +++ b/addons/common/init_perFrameHandler.sqf @@ -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) = []; @@ -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 @@ -44,7 +46,9 @@ GVAR(waitUntilAndExecArray) = []; GVAR(waitAndExecArray) sort true; GVAR(waitAndExecArrayIsSorted) = true; }; + private _delete = false; + { if (_x select 0 > CBA_missionTime) exitWith {}; @@ -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: @@ -81,6 +110,7 @@ GVAR(waitUntilAndExecArray) = []; _delete = true; }; } forEach GVAR(waitUntilAndExecArray); + if (_delete) then { GVAR(waitUntilAndExecArray) = GVAR(waitUntilAndExecArray) - [objNull]; }; From ab61a68aba5f1a70e66906d1e47bd0ee728d5db5 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Tue, 11 Jul 2023 17:32:58 +0200 Subject: [PATCH 2/5] Revert "Added n frame delay" This reverts commit 50df691493ff87b89d5971ff74619d71f68ccd83. --- addons/common/fnc_execNextFrame.sqf | 17 +++-------- addons/common/init_perFrameHandler.sqf | 40 ++++---------------------- 2 files changed, 9 insertions(+), 48 deletions(-) diff --git a/addons/common/fnc_execNextFrame.sqf b/addons/common/fnc_execNextFrame.sqf index e3248e91fb..c81cc92b9f 100644 --- a/addons/common/fnc_execNextFrame.sqf +++ b/addons/common/fnc_execNextFrame.sqf @@ -3,12 +3,11 @@ Function: CBA_fnc_execNextFrame Description: - Executes a code once in non sched environment delayed by n frames. + Executes a code once in non sched environment on the next frame. Parameters: _function - The function to run. - _args - Parameters passed to the function executing. This will be the same array every execution. (optional, default: []) - _frames - The number of frames the execution will be delayed by. (optional, default: 1) + _args - Parameters passed to the function executing. This will be the same array every execution. [optional] Returns: Nothing @@ -22,17 +21,9 @@ Author: esteldunedain and PabstMirror, donated from ACE3 ---------------------------------------------------------------------------- */ -params [["_function", {}, [{}]], ["_args", []], ["_frames", 1, [0]]]; +params [["_function", {}, [{}]], ["_args", []]]; -// Do not allow negative or 0 frame delays -_frames = _frames max 1; - -if (_frames > 1) exitWith { - GVAR(nextFrameNBuffer) pushBack [diag_frameNo + _frames, _args, _function]; - GVAR(nextFrameNBufferIsSorted) = false; -}; - -if (diag_frameNo != GVAR(nextFrameNo)) then { +if (diag_frameno != GVAR(nextFrameNo)) then { GVAR(nextFrameBufferA) pushBack [_args, _function]; } else { GVAR(nextFrameBufferB) pushBack [_args, _function]; diff --git a/addons/common/init_perFrameHandler.sqf b/addons/common/init_perFrameHandler.sqf index 141640cea2..795211f423 100644 --- a/addons/common/init_perFrameHandler.sqf +++ b/addons/common/init_perFrameHandler.sqf @@ -9,9 +9,7 @@ GVAR(lastTickTime) = diag_tickTime; GVAR(waitAndExecArray) = []; GVAR(waitAndExecArrayIsSorted) = false; -GVAR(nextFrameNBuffer) = []; -GVAR(nextFrameNBufferAIsSorted) = false; -GVAR(nextFrameNo) = diag_frameNo + 1; +GVAR(nextFrameNo) = diag_frameno + 1; GVAR(nextFrameBufferA) = []; GVAR(nextFrameBufferB) = []; GVAR(waitUntilAndExecArray) = []; @@ -24,9 +22,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 @@ -46,9 +44,7 @@ GVAR(waitUntilAndExecArray) = []; GVAR(waitAndExecArray) sort true; GVAR(waitAndExecArrayIsSorted) = true; }; - private _delete = false; - { if (_x select 0 > CBA_missionTime) exitWith {}; @@ -58,45 +54,20 @@ 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: @@ -110,7 +81,6 @@ GVAR(waitUntilAndExecArray) = []; _delete = true; }; } forEach GVAR(waitUntilAndExecArray); - if (_delete) then { GVAR(waitUntilAndExecArray) = GVAR(waitUntilAndExecArray) - [objNull]; }; From 0a06b6c96be7b395c1ffa0299724ad85f8537d76 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Tue, 11 Jul 2023 17:50:20 +0200 Subject: [PATCH 3/5] Added function from ZEN --- addons/common/CfgFunctions.hpp | 1 + addons/common/fnc_execAfterNFrames.sqf | 35 ++++++++++++++++++++++++++ addons/common/fnc_execNextFrame.sqf | 2 +- 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 addons/common/fnc_execAfterNFrames.sqf diff --git a/addons/common/CfgFunctions.hpp b/addons/common/CfgFunctions.hpp index 17478a7557..9366f9803d 100644 --- a/addons/common/CfgFunctions.hpp +++ b/addons/common/CfgFunctions.hpp @@ -131,6 +131,7 @@ class CfgFunctions { PATHTO_FNC(directCall); PATHTO_FNC(objectRandom); PATHTO_FNC(execNextFrame); + PATHTO_FNC(execAfterNFrames); PATHTO_FNC(waitAndExecute); PATHTO_FNC(waitUntilAndExecute); PATHTO_FNC(compileFinal); diff --git a/addons/common/fnc_execAfterNFrames.sqf b/addons/common/fnc_execAfterNFrames.sqf new file mode 100644 index 0000000000..c81cb7bfb6 --- /dev/null +++ b/addons/common/fnc_execAfterNFrames.sqf @@ -0,0 +1,35 @@ +#include "script_component.hpp" +/* ---------------------------------------------------------------------------- +Function: CBA_fnc_execAfterNFrames + +Description: + Executes the given code after the specified number of frames. + +Parameters: + _function - The function to run. + _args - Parameters passed to the function executing. This will be the same array every execution. (optional, default: []) + _frames - The amount of frames the execution of the function should be delayed by. (optional, default: 0) + +Returns: + Nothing + +Examples: + (begin example) + [{hint "Done!"}, [], 5] call cba_fnc_execAfterNFrames; + (end) + +Author: + mharis001, donated from ZEN +---------------------------------------------------------------------------- */ + +if (canSuspend) exitWith { + [CBA_fnc_execAfterNFrames, _this] call CBA_fnc_directCall; +}; + +params [["_function", {}, [{}]], ["_args", []], ["_frames", 0, [0]]]; + +if (_frames > 0) exitWith { + [CBA_fnc_execAfterNFrames, [_function, _args, _frames - 1]] call CBA_fnc_execNextFrame; +}; + +_args call _function; diff --git a/addons/common/fnc_execNextFrame.sqf b/addons/common/fnc_execNextFrame.sqf index c81cc92b9f..744f27b789 100644 --- a/addons/common/fnc_execNextFrame.sqf +++ b/addons/common/fnc_execNextFrame.sqf @@ -7,7 +7,7 @@ Description: Parameters: _function - The function to run. - _args - Parameters passed to the function executing. This will be the same array every execution. [optional] + _args - Parameters passed to the function executing. This will be the same array every execution. (optional, default: []) Returns: Nothing From d2dbfa16e1fdb99e79d43deaa4ab6dea30079195 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Wed, 12 Jul 2023 08:18:17 -0700 Subject: [PATCH 4/5] Update addons/common/fnc_execAfterNFrames.sqf Co-authored-by: PabstMirror --- addons/common/fnc_execAfterNFrames.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/common/fnc_execAfterNFrames.sqf b/addons/common/fnc_execAfterNFrames.sqf index c81cb7bfb6..3c141e72ca 100644 --- a/addons/common/fnc_execAfterNFrames.sqf +++ b/addons/common/fnc_execAfterNFrames.sqf @@ -11,7 +11,7 @@ Parameters: _frames - The amount of frames the execution of the function should be delayed by. (optional, default: 0) Returns: - Nothing + Nothing Useful Examples: (begin example) From cf7786416591394d8cec82ae5e56bcf69868c60d Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Wed, 12 Jul 2023 17:20:05 +0200 Subject: [PATCH 5/5] Update fnc_execNextFrame.sqf --- addons/common/fnc_execNextFrame.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/common/fnc_execNextFrame.sqf b/addons/common/fnc_execNextFrame.sqf index 744f27b789..e0b2b00eef 100644 --- a/addons/common/fnc_execNextFrame.sqf +++ b/addons/common/fnc_execNextFrame.sqf @@ -10,7 +10,7 @@ Parameters: _args - Parameters passed to the function executing. This will be the same array every execution. (optional, default: []) Returns: - Nothing + Nothing Useful Examples: (begin example)