Skip to content
Open
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
1 change: 1 addition & 0 deletions addons/common/CfgFunctions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ class CfgFunctions {
PATHTO_FNC(waitAndExecute);
PATHTO_FNC(waitUntilAndExecute);
PATHTO_FNC(compileFinal);
PATHTO_FNC(missionTimeDelta);
};

class Broken {
Expand Down
34 changes: 34 additions & 0 deletions addons/common/fnc_missionTimeDelta.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include "script_component.hpp"
/* ----------------------------------------------------------------------------
Function: CBA_fnc_missionTimeDelta

Description:
Return precise time in seconds between two CBA_missionTimeSTR timestamps.

Parameters:
_t0 - Smaller time string <STRING>
_t1 - Larger time string <STRING>

Returns:
Time difference <NUMBER>

Examples:
(begin example)
_elapsedTime = my_oldTimeString call CBA_fnc_missionTimeDelta;

_deltaTime = [my_oldTimeString, my_newTimeString] call CBA_fnc_missionTimeDelta;

_missionTime = [] call CBA_fnc_missionTimeDelta;
(end)

Author:
commy2
---------------------------------------------------------------------------- */

params [["_t0", "0000.000000", [""]], ["_t1", CBA_missionTimeStr, [""]]];

private _len0 = count _t0 - 10;
private _len1 = count _t1 - 10;

(parseNumber (_t1 select [0, _len1]) - parseNumber (_t0 select [0, _len0])) * 1000 +
(parseNumber (_t1 select [_len1]) - parseNumber (_t0 select [_len0]))
84 changes: 34 additions & 50 deletions addons/common/init_perFrameHandler.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

GVAR(perFrameHandlerArray) = [];
GVAR(perFrameHandlersToRemove) = [];
GVAR(lastTickTime) = diag_tickTime;

GVAR(waitAndExecArray) = [];
GVAR(waitAndExecArrayIsSorted) = false;
Expand All @@ -14,11 +13,34 @@ GVAR(nextFrameBufferA) = [];
GVAR(nextFrameBufferB) = [];
GVAR(waitUntilAndExecArray) = [];

GVAR(missionTimeSynchronized) = false;
GVAR(missionTimePrecise) = 0;
GVAR(missionTimeThousands) = 0;
CBA_missionTime = 0;
CBA_missionTimeStr = "0000.000000";

// per frame handler system
[QFUNC(onFrame), {
SCRIPT(onFrame);
private _tickTime = diag_tickTime;
call FUNC(missionTimePFH);

// Update CBA_missionTime when synchronized, time has started, and game is not paused.
if ([GVAR(missionTimeSynchronized), time > 0, isGamePaused] isEqualTo [true, true, false]) then {

@mharis001 mharis001 May 31, 2020

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this is better written as:

Suggested change
if ([GVAR(missionTimeSynchronized), time > 0, isGamePaused] isEqualTo [true, true, false]) then {
if (GVAR(missionTimeSynchronized) && time > 0 && !isGamePaused) then {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Isn't that slower though? That shit runs every frame.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It is slightly faster.

Result:
0.0028 ms

Cycles:
10000/10000

Code:
[cba_common_missionTimeSynchronized, time > 0, isGamePaused] isEqualTo [true, true, false]
Result:
0.0021 ms

Cycles:
10000/10000

Code:
cba_common_missionTimeSynchronized && {time > 0 && {!isGamePaused}}

@commy2 commy2 May 31, 2020

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

What was cba_common_missionTimeSynchronized in your example? It will be true all mission long.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It was true; the overall result for both statements was also true.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

hows the speed without the lazy eval?
creating array, calling "true" command 3 times, creating another array, calling isEqualTo command surely is a bit expensive.
But lazy eval is also expensive but in this case as commy said, we don't expect neither missionTimeSynchronized or the time check to ever be false, so why lazy eval?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yeah, no lazy eval is the fastest.

Result:
0.0017 ms

Cycles:
10000/10000

Code:
cba_common_missionTimeSynchronized && time > 0 && !isGamePaused

Updated the suggestion.

GVAR(missionTimePrecise) = GVAR(missionTimePrecise) + diag_deltaTime * accTime;

while {GVAR(missionTimePrecise) >= 1000} do {
GVAR(missionTimePrecise) = GVAR(missionTimePrecise) - 1000;
GVAR(missionTimeThousands) = GVAR(missionTimeThousands) + 1;
};

CBA_missionTimeStr = format [
"%1%2",
GVAR(missionTimeThousands) toFixed 0,
(1000 + GVAR(missionTimePrecise)) toFixed 6 select [1]
];

CBA_missionTime = parseNumber CBA_missionTimeStr;
};

// 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
Expand Down Expand Up @@ -86,37 +108,15 @@ GVAR(waitUntilAndExecArray) = [];
};
}] call CBA_fnc_compileFinal;

// fix for save games. subtract last tickTime from ETA of all PFHs after mission was loaded
addMissionEventHandler ["Loaded", {
private _tickTime = diag_tickTime;

{
_x set [2, (_x select 2) - GVAR(lastTickTime) + _tickTime];
} forEach GVAR(perFrameHandlerArray);

GVAR(lastTickTime) = _tickTime;
}];

CBA_missionTime = 0;
GVAR(lastTime) = time;

// increase CBA_missionTime variable every frame
if (isMultiplayer) then {
// multiplayer - no accTime in MP
if (isServer) then {
// multiplayer server
[QFUNC(missionTimePFH), {
SCRIPT(missionTimePFH_server);
if (time != GVAR(lastTime)) then {
CBA_missionTime = CBA_missionTime + (_tickTime - GVAR(lastTickTime));
GVAR(lastTime) = time; // used to detect paused game
};

GVAR(lastTickTime) = _tickTime;
}] call CBA_fnc_compileFinal;
GVAR(missionTimeSynchronized) = true;

addMissionEventHandler ["PlayerConnected", {
(_this select 4) publicVariableClient "CBA_missionTime";
(_this select 4) publicVariableClient "CBA_missionTimeStr";
}];
} else {
CBA_missionTime = -1;
Expand All @@ -125,40 +125,24 @@ if (isMultiplayer) then {
0 spawn {
isNil {
private _fnc_init = {
CBA_missionTime = _this select 1;

GVAR(lastTickTime) = diag_tickTime; // prevent time skip on clients

[QFUNC(missionTimePFH), {
SCRIPT(missionTimePFH_client);
if (time != GVAR(lastTime)) then {
CBA_missionTime = CBA_missionTime + (_tickTime - GVAR(lastTickTime));
GVAR(lastTime) = time; // used to detect paused game
};

GVAR(lastTickTime) = _tickTime;
}] call CBA_fnc_compileFinal;
params ["", "_timestamp"];
private _length = count _timestamp - 10;

GVAR(missionTimePrecise) = parseNumber (_timestamp select [_length]);
GVAR(missionTimeThousands) = parseNumber (_timestamp select [0, _length]);
GVAR(missionTimeSynchronized) = true;
};

"CBA_missionTime" addPublicVariableEventHandler _fnc_init;
"CBA_missionTimeStr" addPublicVariableEventHandler _fnc_init;

if (CBA_missionTime != -1) then {
WARNING_1("CBA_missionTime packet arrived prematurely. Installing update handler manually. Transferred value was %1.",CBA_missionTime);
[nil, CBA_missionTime] call _fnc_init;
[nil, CBA_missionTimeStr] call _fnc_init;
};
};
};
};
} else {
// single player
[QFUNC(missionTimePFH), {
SCRIPT(missionTimePFH_sp);
if (time != GVAR(lastTime)) then {
CBA_missionTime = CBA_missionTime + (_tickTime - GVAR(lastTickTime)) * accTime;
GVAR(lastTime) = time; // used to detect paused game
};

GVAR(lastTickTime) = _tickTime;
}] call CBA_fnc_compileFinal;
GVAR(missionTimeSynchronized) = true;
};