Skip to content

Commit

Permalink
Zeus Utils - Initial and add Zeus FPS tracker (#623)
Browse files Browse the repository at this point in the history
* Initial commit

* more progress on client side system

* Finished up initial version

* Whitespace cleanup pt 1

* Updated button feedback text
  • Loading branch information
lambdatiger authored Jan 11, 2025
1 parent 9b10a01 commit 4340ab0
Show file tree
Hide file tree
Showing 16 changed files with 404 additions and 0 deletions.
1 change: 1 addition & 0 deletions addons/zeusUtils/$PBOPREFIX$
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
z\potato\addons\zeusUtils
17 changes: 17 additions & 0 deletions addons/zeusUtils/CfgEventHandlers.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class Extended_PreStart_EventHandlers {
class ADDON {
init = QUOTE(call COMPILE_SCRIPT(XEH_preStart));
};
};

class Extended_PreInit_EventHandlers {
class ADDON {
init = QUOTE(call COMPILE_SCRIPT(XEH_preInit));
};
};

class Extended_PostInit_EventHandlers {
class ADDON {
init = QUOTE(call COMPILE_SCRIPT(XEH_postInit));
};
};
17 changes: 17 additions & 0 deletions addons/zeusUtils/CfgUI.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class RscButton;
class RscDisplayCurator {
class Controls {
class GVAR(displayFPSButton): RscButton {
idc = ZEUSUTILS_IDC_DISPLAYFPSBUTTON;
// based on Potato's ACRE spectate button
x = "safezoneX";
y = "safezoneY + safeZoneH - 28 * pixelH";
w = "80 * pixelW";
h = "12 * pixelH";
sizeEx = "12 * pixelH";
text = "FPS Display";
onLoad = QUOTE([ARR_2(_this#0,1)] call FUNC(changeFPSDisplayState));
onButtonClick = QUOTE([_this#0] call FUNC(changeFPSDisplayState));
};
};
};
5 changes: 5 additions & 0 deletions addons/zeusUtils/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Zeus Utils (zeusUtils)


## Current Items
- Interact to pick up weapons when they are close enough to a body, for when weapon holders get placed in unreachable areas.
7 changes: 7 additions & 0 deletions addons/zeusUtils/XEH_PREP.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
TRACE_1("",QUOTE(ADDON));

PREP(changeFPSDisplayState);
PREP(drawFPSHandle);
PREP(handleZeusFPSRequest);
PREP(initLocalFPSEH);
PREP(updateServerFPSList);
18 changes: 18 additions & 0 deletions addons/zeusUtils/XEH_postInit.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include "script_component.hpp"

if (isServer && isMultiplayer) then {
[QGVAR(ZeusFPSMonitorUpdate), LINKFUNC(handleZeusFPSRequest)] call CBA_fnc_addEventHandler;
GVAR(serverUpdateFPSEH) = [{
{
_x publicVariableClient QGVAR(playerFPSCache);
} forEach GVAR(clientsTrackingFPS);
}, 3] call CBA_fnc_addPerFrameHandler;
};

if !(hasInterface) exitWith {};
["CBA_SettingsInitialized", {
TRACE_4("CBA_SettingsInitialized EH Client",_this,GVAR(fpsDisplayEH),GVAR(fpsAvgCalcEH),GVAR(fpsAvgCalc));
if (isMultiplayer) then {
[] call FUNC(initLocalFPSEH);
};
}] call CBA_fnc_addEventHandler;
18 changes: 18 additions & 0 deletions addons/zeusUtils/XEH_preInit.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include "script_component.hpp"

ADDON = false;

PREP_RECOMPILE_START;
#include "XEH_PREP.hpp"
PREP_RECOMPILE_END;

GVAR(fpsDisplayEH) = -1;
GVAR(fpsAvgCalcEH) = -1;
GVAR(fpsAvgCalc) = [0, [0, 0, 0, 0, 0]];
GVAR(playerFPSCache) = createHashMap;
GVAR(clientsTrackingFPS) = [];
GVAR(serverUpdateFPSEH) = -1;

#include "initSettings.inc.sqf"

ADDON = true;
3 changes: 3 additions & 0 deletions addons/zeusUtils/XEH_preStart.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include "script_component.hpp"

#include "XEH_PREP.hpp"
18 changes: 18 additions & 0 deletions addons/zeusUtils/config.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include "script_component.hpp"

class CfgPatches {
class ADDON {
units[] = {};
weapons[] = {};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {"cba_common"};
skipWhenMissingDependencies = 1;
author = "Potato";
authors[] = {"Lambda.Tiger"};
authorUrl = "https://github.com/BourbonWarfare/POTATO";
VERSION_CONFIG;
};
};

#include "CfgEventHandlers.hpp"
#include "CfgUI.hpp"
53 changes: 53 additions & 0 deletions addons/zeusUtils/functions/fnc_changeFPSDisplayState.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#include "..\script_component.hpp"
/*
* Author: Lambda.Tiger
*
*
*
* Arguments:
* 0: The control that an event happens to
* 1: What mode to change to, either (NUMBER, default 0)
* - 0 - Toggle display between on and off
* - 1 - Load last value and re-add EH as necessary
*
* Return Value:
* None
*
* Examples:
* [_control, 0] call potato_zeusUtils_fnc_changeFPSDisplayState;
*
* Public: No
*/
params [
"_control",
["_toggleMode", 0, [0]]
];
TRACE_2("",_control,_toggleMode);

if !(GVAR(missionFPSEnable)) exitWith {
_control ctrlSetFade 1;
_control ctrlCommit 0;
};
_control ctrlSetFade ([0, 0.2] select (GVAR(fpsDisplayEH) > 0));

if (_toggleMode == 1 && GVAR(fpsDisplayEH) == -2) then {
_toggleMode = 0;
};

if (_toggleMode == 0) then {
TRACE_1("Toggling diag frame fps, current EH:",GVAR(fpsDisplayEH));
if (GVAR(fpsDisplayEH) > 0) then {
[QGVAR(ZeusFPSMonitorUpdate), [clientOwner, false]] call CBA_fnc_serverEvent;
removeMissionEventHandler ["Draw3D", GVAR(fpsDisplayEH)];
GVAR(fpsDisplayEH) = -1;
_control ctrlSetFade 0;
INFORM_USER(Disabled FPS display);
} else {
[QGVAR(ZeusFPSMonitorUpdate), [clientOwner, true]] call CBA_fnc_serverEvent;
GVAR(fpsDisplayEH) = addMissionEventHandler ["Draw3D",
{call FUNC(drawFPSHandle)}
];
INFORM_USER(Enabled FPS display);
};
};
_control ctrlCommit 0;
56 changes: 56 additions & 0 deletions addons/zeusUtils/functions/fnc_drawFPSHandle.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#include "..\script_component.hpp"
/*
* Author: Lambda.Tiger
* This function is called each frame from a Draw3D EH.
* It adds an FPS count to each unit that reports it and will only show when
* the Zeus interface is open. This function MUST be called through the Draw3D
* event handler.
*
* Arguments:
* None
*
* Return Value:
* None
*
* Examples:
* call potato_zeusUtils_fnc_drawFPSHandle;
*
* Public: No
*/
//IGNORE_PRIVATE_WARNING["_thisEvent", "_thisEventHandler"];
TRACE_1("diag FPS Handle:",diag_frameNo);
if (isNull findDisplay 312 ||
!GVAR(missionFPSEnable)) exitWith {
removeMissionEventHandler [_thisEvent, _thisEventHandler];
GVAR(fpsDisplayEH) = -2;
};

private _localCuratorModule = curatorCamera;
// It takes twice as long to access all these global variables as it does
// to make a private copy and use that
private _colorSelectArray = [[1, 1, 1, GVAR(fpsWarningColor)#3], GVAR(fpsWarningColor)];
private _skipAbove = GVAR(skipFPSAboveThreshold);
private _fpsThreshold = GVAR(fpsThreshold);
private _maxDisplayDistance = GVAR(playerFPSDisplayDistance);
{
_y params ["_unit", "_fps"];
private _distance = _unit distance _localCuratorModule;
if (_fps < -1 ||
(_skipAbove && _fps > _fpsThreshold ) ||
{_distance > _maxDisplayDistance}) then {
continue;
};
private _color = _colorSelectArray select (_fps <= _fpsThreshold);
_fps = (_fps toFixed 1) + " FPS";
drawIcon3D [
"",
_color,
ASLToAGL getPosASLVisual _unit,
1,
2,
0,
_fps,
2,
0.03
];
} forEach GVAR(playerFPSCache);
31 changes: 31 additions & 0 deletions addons/zeusUtils/functions/fnc_handleZeusFPSRequest.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include "..\script_component.hpp"
/*
* Author: Lambda.Tiger
* This function handle the "ZeusFPSMonitorUpdate" event sent by zeuses
* requesting to be provided player frame rates for monitoring.
*
* Arguments:
* 0: The Zeus's machine network ID (SCALAR)
* 1: Whether a client wants to recieve FPS data (BOOL)
*
* Return Value:
* None
*
* Examples:
* [clientOwner, true] call potato_zeusUtils_fnc_handleZeusFPSRequest;
*
* Public: No
*/

if !(isServer) exitWith {};
params [
["_clientOwner", -1, [123]],
["_shouldRecieveData", false, [false]]];

if (_clientOwner < 0) exitWith {};

if (_shouldRecieveData) then {
GVAR(clientsTrackingFPS) pushBackUnique _clientOwner;
} else {
GVAR(clientsTrackingFPS) = GVAR(clientsTrackingFPS) - [_clientOwner];
};
40 changes: 40 additions & 0 deletions addons/zeusUtils/functions/fnc_initLocalFPSEH.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include "..\script_component.hpp"
/*
* Author: Lambda.Tiger
* This function initializes the GVAR(fpsAvgCalc) array and adds the per
* frame event handler to calculate and report FPS to the server. If the player
* has turned off the system or it's already runnig
*
* Arguments:
* None
*
* Return Value:
* None
*
* Examples:
* [] call potato_zeusUtils_fnc_initLocalFPSEH;
*
* Public: No
*/
TRACE_3("init local FPS EH",hasInterface,GVAR(fpsAvgCalcEH),GVAR(clientFPSEnable));
if (!hasInterface || GVAR(fpsAvgCalcEH) >= 0 || !GVAR(clientFPSEnable)) exitWith {};

[{ // offset so users stagger reporting to server
GVAR(fpsAvgCalc) = [diag_fps, [1, 1, 1, 1, 1] vectorMultiply (diag_fps / 5)];
GVAR(fpsAvgCalcEH) = [{
params ["_startTime", "_handle"];
if !(GVAR(clientFPSEnable)) exitWith {
GVAR(fpsAvgCalcEH) = -1;
[_handle] call CBA_fnc_removePerFrameHandler;
[player, -1] remoteExecCall [QFUNC(updateServerFPSList), 2];
};
private _nextFPS = diag_fps / 5;
private _timeSinceInit = floor CBA_missionTime - _startTime;
private _idx = _timeSinceInit mod 5;
GVAR(fpsAvgCalc) set [0, GVAR(fpsAvgCalc)#0 + _nextFPS - GVAR(fpsAvgCalc)#1#_idx];
GVAR(fpsAvgCalc)#1 set [_idx, diag_fps / 5];
if (_timeSinceInit mod GVAR(clientFPSUpdateRate) == 0) then {
[player, GVAR(fpsAvgCalc)#0] remoteExecCall [QFUNC(updateServerFPSList), 2];
};
}, 1, floor CBA_missionTime] call CBA_fnc_addPerFrameHandler;
}, 0, random 5] call CBA_fnc_waitAndExecute;
28 changes: 28 additions & 0 deletions addons/zeusUtils/functions/fnc_updateServerFPSList.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include "..\script_component.hpp"
/*
* Author: Lambda.Tiger
* This function initializes the GVAR(fpsAvgCalc) array and adds the per
* frame event handler to calculate and report FPS
*
* Arguments:
* None
*
* Return Value:
* None
*
* Examples:
* [] call potato_zeusUtils_fnc_initLocalFPSEH;
*
* Public: No
*/
params [
["_unit", objNull, [objNull]],
["_fps", -1, [123]]
];

if (isNull _unit) exitWith {};
if (_fps < 0) then {
GVAR(playerFPSCache) deleteAt owner _unit;
} else {
GVAR(playerFPSCache) set [owner _unit, [_unit, _fps]];
};
Loading

0 comments on commit 4340ab0

Please sign in to comment.