-
Notifications
You must be signed in to change notification settings - Fork 149
/
Copy pathfnc_addClassEventHandler.sqf
94 lines (71 loc) · 3.85 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
#include "script_component.hpp"
/* ----------------------------------------------------------------------------
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
---------------------------------------------------------------------------- */
params [["_className", "", [""]], ["_eventName", "", [""]], ["_eventFunc", {}, [{}]], ["_allowInheritance", true, [false]], ["_excludedClasses", [], [[]]], ["_applyInitRetroactively", false, [false]]];
private _config = configFile >> "CfgVehicles" >> _className;
// 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 _eventVarName = format [QGVAR(%1), _eventName];
private _entities = (entities [[], [], true, false]); // include dead entities to handle respawning units
_entities = _entities arrayIntersect _entities; // entities can return duplicates at postInit - #567
{
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 {
// If PostInit has not finished exit as it will be run via initPostStack
if ((_eventName == "initpost") && {!(SLX_XEH_MACHINE select 8)}) exitWith {};
[_unit] call _eventFunc;
};
};
};
} forEach _entities;
// 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