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

Port ACE delayed execution functions to CBA #288

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
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
18 changes: 18 additions & 0 deletions addons/common/CfgFunctions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,12 @@ class CfgFunctions
description = "Drops a weapon.";
file = "\x\cba\addons\common\fnc_dropWeapon.sqf";
};
// CBA_fnc_execNextFrame
class execNextFrame
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opening brace on same line as class. I know it's not used in others in this file but it has to get converted anyways.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ït's not used at all in cba_common, so I prefer to maintain consistency

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@commy2 is changing it, he is currently going through entire cba_common. But sure.

description = "Add piece of code that will execute once on the next frame.";
file = "\x\cba\addons\common\fnc_execNextFrame.sqf";
};
// CBA_fnc_findEntity
class findEntity
{
Expand Down Expand Up @@ -513,6 +519,18 @@ class CfgFunctions
description = "Display a message in the global chat channel.";
file = "\x\cba\addons\common\fnc_systemChat.sqf";
};
// CBA_fnc_waitAndExecute
class waitAndExecute
{
description = "Add piece of code that will execute after a certain delay in seconds.";
file = "\x\cba\addons\common\fnc_waitAndExecute.sqf";
};
// CBA_fnc_waitUntilAndExecute
class waitUntilAndExecute
{
description = "Add a condition and statement code. The condition will every frame until it's true, and then the statement will execute once. Both execute in non sched environment";
file = "\x\cba\addons\common\fnc_waitUntilAndExecute.sqf";
};
};
};
// Missing BIS functions
Expand Down
30 changes: 30 additions & 0 deletions addons/common/fnc_execNextFrame.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/* ----------------------------------------------------------------------------
Function: CBA_fnc_execNextFrame

Description:
Executes a code once in non sched environment on the next frame.

Parameters:
_function - The function to run. <CODE>
_args - Parameters passed to the function executing. This will be the same array every execution. [optional] <ANY>

Returns:
Nothing

Examples:
(begin example)
[{player sideChat format ["This is frame %1, not %2", diag_frameno, _this select 0];}, [diag_frameno]] call CBA_fnc_execNextFrame;
(end)

Author:
esteldunedain and PabstMirror, donated from ACE3
---------------------------------------------------------------------------- */
#include "script_component.hpp"

params [["_function", {}, [{}]], ["_args", []]];

if (diag_frameno != GVAR(nextFrameNo)) then {
GVAR(nextFrameBufferA) pushBack [_args, _function];
} else {
GVAR(nextFrameBufferB) pushBack [_args, _function];
};
28 changes: 28 additions & 0 deletions addons/common/fnc_waitAndExecute.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* ----------------------------------------------------------------------------
Function: CBA_fnc_waitAndExecute

Description:
Executes a code once in non sched environment with a given game time delay.

Parameters:
_function - The function you wish to execute. <CODE>
_args - Parameters passed to the function executing. This will be the same array every execution. [optional] <ANY>
_delay - The amount of time in seconds between executions, 0 for every frame. [optional] (default: 0) <NUMBER>

Returns:
Nothing

Examples:
(begin example)
[{player sideChat format ["5s later! _this: %1", _this];}, ["some","params",1,2,3], 5] call CBA_fnc_waitAndExecute;
(end)

Author:
esteldunedain and PabstMirror, donated from ACE3
---------------------------------------------------------------------------- */
#include "script_component.hpp"

params [["_function", {}, [{}]], ["_args", []], ["_delay", 0, [0]]];

GVAR(waitAndExecArray) pushBack [CBA_missionTime + _delay, _function, _args];
GVAR(waitAndExecArrayIsSorted) = false;
27 changes: 27 additions & 0 deletions addons/common/fnc_waitUntilAndExecute.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/* ----------------------------------------------------------------------------
Function: CBA_fnc_waitUntilAndExecute

Description:
Executes a code once in non sched environment after a condition is true.

Parameters:
_conditionFunction - The function to evaluate as condition. <CODE>
_statementFunction - The function to run once the condition is true. <CODE>
_args - Parameters passed to the function executing. This will be the same array every execution. [optional] <ANY>

Returns:
Nothing

Examples:
(begin example)
[{(_this select 0) == vehicle (_this select 0)}, {(_this select 0) setDamage 1;}, [player]] call CBA_fnc_waitUntilAndExecute;
(end)

Author:
joko // Jonas, donated from ACE3
---------------------------------------------------------------------------- */
#include "script_component.hpp"

params [["_conditionFunction", {}, [{}]], ["_statementFunction", {}, [{}]], ["_args", []]];

GVAR(waitUntilAndExecArray) pushBack [_conditionFunction, _statementFunction, _args];
58 changes: 58 additions & 0 deletions addons/common/init_perFrameHandler.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ GVAR(lastCount) = -1;
GVAR(lastFrameRender) = diag_frameNo;
GVAR(lastTickTime) = diag_tickTime;

GVAR(waitAndExecArray) = [];
GVAR(waitAndExecArrayIsSorted) = false;
GVAR(nextFrameNo) = diag_frameno;
GVAR(nextFrameBufferA) = [];
GVAR(nextFrameBufferB) = [];
GVAR(waitUntilAndExecArray) = [];

PREP(perFrameEngine);

FUNC(blaHandler) = {
Expand Down Expand Up @@ -133,6 +140,7 @@ FUNC(onFrame) = {
private _tickTime = diag_tickTime;
call FUNC(missionTimePFH);

// Execute per frame handlers
{
_x params ["_function", "_delay", "_delta", "", "_args", "_handle"];

Expand All @@ -142,6 +150,56 @@ FUNC(onFrame) = {
false
};
} count GVAR(perFrameHandlerArray);


// Execute wait and execute functions
// Sort the queue if necessary
if (!GVAR(waitAndExecArrayIsSorted)) then {
GVAR(waitAndExecArray) sort true;
GVAR(waitAndExecArrayIsSorted) = true;
};
private _delete = false;
{
if (_x select 0 > CBA_missionTime) exitWith {};

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

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


// Execute the exec next frame functions
{
(_x select 0) call (_x select 1);
false
} count GVAR(nextFrameBufferA);
// Swap double-buffer:
GVAR(nextFrameBufferA) = GVAR(nextFrameBufferB);
GVAR(nextFrameBufferB) = [];
GVAR(nextFrameNo) = diag_frameno + 1;


// Execute the waitUntilAndExec functions:
_delete = false;
{
// if condition is satisfied call statement
if ((_x select 2) call (_x select 0)) then {
(_x select 2) call (_x select 1);

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

};

// fix for save games. subtract last tickTime from ETA of all PFHs after mission was loaded
Expand Down