-
Notifications
You must be signed in to change notification settings - Fork 148
/
fnc_addClassEventHandler.sqf
96 lines (73 loc) · 3.88 KB
/
fnc_addClassEventHandler.sqf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/* ----------------------------------------------------------------------------
Function: CBA_fnc_addClassEventHandler
Description:
Add an eventhandler to a class and all children.
Parameters:
0: _className - The classname of objects you wish to add the eventhandler too. Can be a base class. <STRING>
1: _eventName - The type of the eventhandler. E.g. "init", "fired", "killed" etc. <STRING>
2: _eventFunc - Function to execute when event happens. <CODE>
3: _allowInheritance - Allow event for objects that only inherit from the given classname? [optional] <BOOLEAN> (default: true)
4: _excludedClasses - Exclude these classes from this event including their children [optional] <ARRAY> (default: [])
5: _applyInitRetroactively - Apply "init" event type on existing units that have already been initilized. [optional] <BOOLEAN> ((default: false)
Returns:
_success - Whether adding the event was successful or not. <BOOLEAN>
Examples:
(begin example)
["CAManBase", "fired", {systemChat str _this}] call CBA_fnc_addClassEventHandler;
["All", "init", {systemChat str _this}] call CBA_fnc_addClassEventHandler;
["Car", "init", {(_this select 0) engineOn true}, true, [], true] call CBA_fnc_addClassEventHandler; //Starts all current cars and those created later
(end)
Author:
commy2
---------------------------------------------------------------------------- */
#include "script_component.hpp"
params [["_className", "", [""]], ["_eventName", "", [""]], ["_eventFunc", {}, [{}]], ["_allowInheritance", true, [false]], ["_excludedClasses", [], [[]]], ["_applyInitRetroactively", false, [false]]];
private _config = configFile >> "CfgVehicles" >> _className;
// init fallback loop when executing on incompatible class for the first time
if (!GVAR(fallbackRunning) && {ISINCOMP(_className)}) then {
diag_log text format ["[XEH]: One or more children of class %1 do not support Extended Event Handlers. Fall back to loop.", configName _config];
call CBA_fnc_startFallbackLoop;
};
// no such CfgVehicles class
if (!isClass _config) exitWith {false};
_eventName = toLower _eventName;
// no such event
if (_eventName == "FiredBIS") exitWith {
WARNING("Cannot add 'FiredBIS' - Use 'Fired' instead");
false
};
if !(_eventName in GVAR(EventsLowercase)) exitWith {false};
// don't use "apply retroactively" for non init events
if (_applyInitRetroactively && {!(_eventName in ["init", "initpost"])}) then {
_applyInitRetroactively = false;
};
// add events to already existing objects
private _entities = entities "" + allUnits;
private _eventVarName = format [QGVAR(%1), _eventName];
{
if (_x isKindOf _className) then {
private _unit = _x;
if (ISKINDOF(_unit,_className,_allowInheritance,_excludedClasses)) then {
if (isNil {_unit getVariable _eventVarName}) then {
_unit setVariable [_eventVarName, []];
};
(_unit getVariable _eventVarName) pushBack _eventFunc;
//Run initReto now if the unit has already been initialized
if (_applyInitRetroactively && {ISINITIALIZED(_unit)}) then {
[_unit] call _eventFunc;
};
};
};
} forEach (_entities arrayIntersect _entities); // filter duplicates
// define for units that are created later
private _events = EVENTHANDLERS(_eventName,_className);
_events pushBack [_eventFunc, _allowInheritance, _excludedClasses];
SETEVENTHANDLERS(_eventName,_className,_events);
// set flag for this event handler to be used on this class. reduces overhead on init.
private _eventNameFlagsVarName = format [QGVAR(::%1), _className];
private _eventNameFlags = missionNamespace getVariable [_eventNameFlagsVarName, []];
if !(_eventName in _eventNameFlags) then {
_eventNameFlags pushBack _eventName;
missionNamespace setVariable [_eventNameFlagsVarName, _eventNameFlags];
};
true