Skip to content
4 changes: 0 additions & 4 deletions addons/xeh/CfgFunctions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,6 @@ class CfgFunctions {
description = "Occurs once per mission after objects and functions are initialized.";
file = PATHTOF(fnc_postInit.sqf);
};
class postInit_unscheduled {
description = "Occurs once per mission after objects and functions are initialized.";
file = PATHTOF(fnc_postInit_unscheduled.sqf);
};
class startFallbackLoop {
description = "Starts a loop to iterate through all objects to initialize event handlers on XEH incompatible objects.";
file = PATHTOF(fnc_startFallbackLoop.sqf);
Expand Down
143 changes: 81 additions & 62 deletions addons/xeh/fnc_compileEventHandlers.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -27,72 +27,80 @@ params [["_baseConfig", configNull, [configNull]]];
private _result = [];
private _resultNames = [];

private _allowRecompile = _baseConfig isEqualTo configFile;

if (_allowRecompile) then {
if ("compile" call CBA_fnc_isRecompileEnabled || {isFilePatchingEnabled}) then {
XEH_LOG("XEH: init function preProcessing disabled [recompile or filepatching enabled]");
_allowRecompile = false;
};
};

// note: format is never used for config parsing here, because of it's 8192 character limitation.

{
private _eventName = _x;

{
private _eventFunc = "";
private _funcAll = "";
private _funcClient = "";
private _funcServer = "";
private _customName = configName _x;

if (isClass _x) then {
// events on clients and server
private _entry = _x >> "init";

if (isText _entry) then {
_eventFunc = _eventFunc + getText _entry + ";";
_funcAll = getText _entry;
};

// client only events
if (!isDedicated) then {
_entry = _x >> "clientInit";

if (isText _entry) then {
_eventFunc = _eventFunc + getText _entry + ";";
};
_entry = _x >> "clientInit";
if (isText _entry) then {
_funcClient = getText _entry;
};

// server only events
if (isServer) then {
_entry = _x >> "serverInit";

if (isText _entry) then {
_eventFunc = _eventFunc + getText _entry + ";";
};
_entry = _x >> "serverInit";
if (isText _entry) then {
_funcServer = getText _entry;
};
} else {
// global events
if (isText _x) then {
_eventFunc = getText _x + ";";
_funcAll = getText _x;
};
};

if !(_eventFunc isEqualTo "") then {

//Optimize "QUOTE(call COMPILE_FILE(XEH_preInit));" down to just the content of the EH script
if (!(["compile"] call CBA_fnc_isRecompileEnabled) && { //Users might expect their preInit script to be reloaded everytime when debugging
(toLower (_eventFunc select [0,40])) isEqualTo "call compile preprocessfilelinenumbers '" && {
(_eventFunc select [count _eventFunc -2]) isEqualTo "';"
}}) then {
private _funcPath = _eventFunc select [40, count _eventFunc - 42];
//If there is a quote mark in the path, then something went wrong and we got multiple paths, just skip optimization
//Example cause: "call COMPILE_FILE(XEH_preInit);call COMPILE_FILE(XEH_preClientInit)"
if (_funcPath find "'" == -1) then {
_eventFunc = preprocessFileLineNumbers _funcPath;

TRACE_2("eventfunction redirected",_customName,_funcPath);
private _eventFuncs = [_funcAll, _funcClient, _funcServer] apply {
if (_x == "") then {
TRACE_2("does NOT do something",_customName,_eventName);
{} // apply return
} else {
TRACE_2("does something",_customName,_eventName);
private _eventFunc = _x;

//Optimize "QUOTE(call COMPILE_FILE(XEH_preInit));" down to just the content of the EH script
if (_allowRecompile) then {
if (toLower (_eventFunc select [0,40]) isEqualTo "call compile preprocessfilelinenumbers '" && {(_eventFunc select [count _eventFunc - 1]) isEqualTo "'"}) then {
private _funcPath = _eventFunc select [40, count _eventFunc - 41];

//If there is a quote mark in the path, then something went wrong and we got multiple paths, just skip optimization
//Example cause: "call COMPILE_FILE(XEH_preInit);call COMPILE_FILE(XEH_preClientInit)"
if (_funcPath find "'" == -1) then {
_eventFunc = preprocessFileLineNumbers _funcPath;
TRACE_2("eventfunction redirected",_customName,_funcPath);
};
};
// if (_eventFunc isEqualTo _x) then { diag_log text format ["XEH: Could not recompile [%1-%2]: %3", _eventName, _customName, _eventFunc]; };
};
};

_eventFunc = compile _eventFunc;
TRACE_2("does something",_customName,_eventName);
} else {
_eventFunc = {};
TRACE_2("does NOT do something",_customName,_eventName);
compile _eventFunc // apply return
};
};

_result pushBack ["", _eventName, _eventFunc];
_result pushBack ["", _eventName, _eventFuncs];
_resultNames pushBack _customName;
} forEach configProperties [_baseConfig >> XEH_FORMAT_CONFIG_NAME(_eventName)];
} forEach ["preInit", "postInit"];
Expand All @@ -119,10 +127,12 @@ private _resultNames = [];
};

{
private _eventFunc = _eventFuncBase;
private _customName = configName _x;
private _allowInheritance = true;
private _excludedClasses = [];
private _funcAll = "";
private _funcClient = "";
private _funcServer = "";

if (isClass _x) then {
// allow inheritance of this event?
Expand All @@ -132,6 +142,9 @@ private _resultNames = [];
_allowInheritance = getNumber _scope != 0;
};

// init event handlers that should run on respawn again, onRespawn = 1
private _onRespawn = toLower _eventName in ["init", "initpost"] && {getNumber (_x >> "onRespawn") == 1};

// classes excluded from this event
private _exclude = _x >> "exclude";

Expand All @@ -147,35 +160,38 @@ private _resultNames = [];
private _entry = _x >> _entryName;

if (isText _entry) then {
_eventFunc = _eventFunc + getText _entry + ";";
_funcAll = _eventFuncBase + getText _entry + ";";

if (_onRespawn) then {
_funcAll = _funcAll + "(_this select 0) addEventHandler ['Respawn', " + str _funcAll + "];";
};
};

// client only events
if (!isDedicated) then {
_entry = _x >> format ["client%1", _entryName];
_entry = _x >> format ["client%1", _entryName];

if (isText _entry) then {
_funcClient = _eventFuncBase + getText _entry + ";";

if (isText _entry) then {
_eventFunc = _eventFunc + getText _entry + ";";
if (_onRespawn) then {
_funcClient = _funcClient + "(_this select 0) addEventHandler ['Respawn', " + str _funcClient + "];";
};
};

// server only events
if (isServer) then {
_entry = _x >> format ["server%1", _entryName];
_entry = _x >> format ["server%1", _entryName];

if (isText _entry) then {
_eventFunc = _eventFunc + getText _entry + ";";
};
};
if (isText _entry) then {
_funcServer = _eventFuncBase + getText _entry + ";";

// init event handlers that should run on respawn again, onRespawn = 1
if (toLower _eventName in ["init", "initpost"] && {getNumber (_x >> "onRespawn") == 1}) then {
_eventFunc = _eventFunc + "(_this select 0) addEventHandler ['Respawn', " + str _eventFunc + "];";
if (_onRespawn) then {
_funcServer = _funcServer + "(_this select 0) addEventHandler ['Respawn', " + str _funcServer + "];";
};
};
} else {
// global events
if (isText _x) then {
_eventFunc = _eventFunc + getText _x + ";";
_funcAll = _eventFuncBase + getText _x + ";";
};
};

Expand All @@ -197,19 +213,22 @@ private _resultNames = [];
};
} forEach _resultNames;

// only add event on machines where it exists
if !(_eventFunc isEqualTo _eventFuncBase) then {
_eventFunc = compile _eventFunc;
TRACE_3("does something",_customName,_className,_eventName);
} else {
_eventFunc = {};
TRACE_3("does NOT do something",_customName,_className,_eventName);
private _eventFuncs = [_funcAll, _funcClient, _funcServer] apply {
// only add event on machines where it exists
if (_x == "") then {
TRACE_3("does NOT do something",_customName,_className,_eventName);
{}
} else {
TRACE_3("does something",_customName,_className,_eventName);
compile _x
};
};

_result pushBack [_className, _eventName, _eventFunc, _allowInheritance, _excludedClasses];
_result pushBack [_className, _eventName, _eventFuncs, _allowInheritance, _excludedClasses];
_resultNames pushBack _customName;
} forEach configProperties [_x];
} forEach configProperties [_baseConfig >> XEH_FORMAT_CONFIG_NAME(_eventName), "isClass _x"];
} forEach [XEH_EVENTS];

_result select {!((_x select 2) isEqualTo {})}
TRACE_2("compiled",_baseConfig,count _result);

_result select {!((_x select 2) isEqualTo [{},{},{}])}
2 changes: 1 addition & 1 deletion addons/xeh/fnc_initDisplay.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ if !(_event isEqualTo "") then {
private ["_event", "_className"]; // prevent these variables from being overwritten
_args call compile getText _x;
} forEach configProperties [_x >> XEH_FORMAT_CONFIG_NAME(_event) >> _className, "isText _x"];
} forEach XEH_MAIN_CONFIGS;
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.

why?

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.

Macro seemed pointless. Bugged me for a while and now is an opportunity to muck it out.

} forEach [configFile, campaignConfigFile, missionConfigFile];
};
49 changes: 48 additions & 1 deletion addons/xeh/fnc_postInit.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,51 @@ Author:
commy2
---------------------------------------------------------------------------- */

CBA_fnc_postInit_unscheduled call CBA_fnc_directCall;
isNil {
XEH_LOG("XEH: PostInit started. " + PFORMAT_9("MISSIONINIT",missionName,missionVersion,worldName,isMultiplayer,isServer,isDedicated,CBA_isHeadlessClient,hasInterface,didJIP));

// fix CBA_missionTime being -1 on (non-JIP) clients at mission start.
if (CBA_missionTime == -1) then {
CBA_missionTime = 0;
};

// call PostInit events
{
if (_x select 1 == "postInit") then {
(_x select 2) call {
private "_x";

[] call (_this select 0);

if (!isDedicated) then {
[] call (_this select 1);
};

if (isServer) then {
[] call (_this select 2);
};
};
};
} forEach GVAR(allEventHandlers);

// do InitPost
{
_x params ["_this"];

{
[_this] call _x;
} forEach (_this getVariable QGVAR(initPost));
} forEach GVAR(initPostStack);

GVAR(initPostStack) = nil;

#ifdef DEBUG_MODE_FULL
diag_log text format ["isScheduled = %1", call CBA_fnc_isScheduled];
#endif

SLX_XEH_MACHINE set [8, true]; // PostInit passed

XEH_LOG("XEH: PostInit finished.");
};

nil
50 changes: 0 additions & 50 deletions addons/xeh/fnc_postInit_unscheduled.sqf

This file was deleted.

Loading