diff --git a/addons/common/XEH_postInit.sqf b/addons/common/XEH_postInit.sqf index 7a012d410..f535445b5 100644 --- a/addons/common/XEH_postInit.sqf +++ b/addons/common/XEH_postInit.sqf @@ -67,11 +67,7 @@ FUNC(initPerFrameHandlers) = { }; // Run the per frame handler init code, bringing up the hidden map control -if (_oldPFH && {!CBA_MISSION_START}) then { - ["CBA_MISSION_START", { _oldPFH call FUNC(initPerFrameHandlers) }] call CBA_fnc_addEventHandler; -} else { - _oldPFH call FUNC(initPerFrameHandlers); -}; +_oldPFH call FUNC(initPerFrameHandlers); // TODO: Consider a waitUntil loop with tickTime check to wait for some frames as opposed to trying to sleep until time > 0. Re MP Briefings etc. /* diff --git a/addons/events/CfgEventHandlers.hpp b/addons/events/CfgEventHandlers.hpp index 0e4a3c921..4622a4938 100644 --- a/addons/events/CfgEventHandlers.hpp +++ b/addons/events/CfgEventHandlers.hpp @@ -5,29 +5,17 @@ class Extended_PreStart_EventHandlers { }; }; -class Extended_PreInit_EventHandlers -{ - class ADDON - { +class Extended_PreInit_EventHandlers { + class ADDON { init = QUOTE(call COMPILE_FILE(XEH_preInit)); - clientInit = QUOTE(call COMPILE_FILE(XEH_preClientInit)); }; }; -/* -class Extended_Hit_EventHandlers -{ - class All - { - GVAR(hit) = QUOTE(_this call FUNC(globalHitEvent)); +class Extended_DisplayLoad_EventHandlers { + class RscDisplayMission { + ADDON = QUOTE(_this call COMPILE_FILE(XEH_missionDisplayLoad)); }; -}; - -class Extended_Killed_EventHandlers -{ - class All - { - GVAR(killed) = QUOTE(_this call FUNC(globalKilledEvent)); + class RscDisplayCurator { + ADDON = QUOTE(_this call COMPILE_FILE(XEH_curatorDisplayLoad)); }; }; -*/ \ No newline at end of file diff --git a/addons/events/CfgFunctions.hpp b/addons/events/CfgFunctions.hpp index 674411d55..06da78f27 100644 --- a/addons/events/CfgFunctions.hpp +++ b/addons/events/CfgFunctions.hpp @@ -1,135 +1,63 @@ -// ----------------------------------------------------------------------------- -// Automatically generated by 'functions_config.rb' -// DO NOT MANUALLY EDIT THIS FILE! -// ----------------------------------------------------------------------------- -class CfgFunctions -{ - class CBA - { - class Events - { - // CBA_fnc_addDisplayHandler - class addDisplayHandler - { - description = "Adds an action to a displayHandler"; +class CfgFunctions { + class CBA { + class Events { + class addDisplayHandler { + description = "Adds an action to the main display."; file = "\x\cba\addons\events\fnc_addDisplayHandler.sqf"; }; - // CBA_fnc_addEventHandler - class addEventHandler - { - description = "Registers an event handler for a specific CBA event."; - file = "\x\cba\addons\events\fnc_addEventHandler.sqf"; + class removeDisplayHandler { + description = "Removes an action from the main display."; + file = "\x\cba\addons\events\fnc_removeDisplayHandler.sqf"; }; - // CBA_fnc_addKeyHandler - class addKeyHandler - { - description = "Adds an action to a keyhandler"; + class addKeyHandler { + description = "Adds an action to a keybind."; file = "\x\cba\addons\events\fnc_addKeyHandler.sqf"; }; - // CBA_fnc_addKeyHandlerFromConfig - class addKeyHandlerFromConfig - { - description = "Adds an action to a keyhandler, read from config"; + class addKeyHandlerFromConfig { + description = "Adds an action to a keybind from config."; file = "\x\cba\addons\events\fnc_addKeyHandlerFromConfig.sqf"; }; - // CBA_fnc_addLocalEventHandler - class addLocalEventHandler - { - description = "Registers an event handler for a specific CBA event which only runs where the first parameter (object) is local."; - file = "\x\cba\addons\events\fnc_addLocalEventHandler.sqf"; + class readKeyFromConfig { + description = "Reads key setting from config."; + file = "\x\cba\addons\events\fnc_readKeyFromConfig.sqf"; }; - // CBA_fnc_changeKeyHandler - class changeKeyHandler - { - description = "Changes an action to a keyhandler"; + class changeKeyHandler { + description = "Changes the key of a key handler."; file = "\x\cba\addons\events\fnc_changeKeyHandler.sqf"; }; - // CBA_fnc_globalEvent - class globalEvent - { - description = "Raises a CBA event on all machines, including the local one."; - file = "\x\cba\addons\events\fnc_globalEvent.sqf"; - }; - // CBA_fnc_localEvent - class localEvent - { - description = "Raises a CBA event only on the local machine."; - file = "\x\cba\addons\events\fnc_localEvent.sqf"; - }; - // CBA_fnc_readKeyFromConfig - class readKeyFromConfig - { - description = "Reads key setting from config"; - file = "\x\cba\addons\events\fnc_readKeyFromConfig.sqf"; - }; - // CBA_fnc_remoteEvent - class remoteEvent - { - description = "Raises a CBA event on all machines EXCEPT the local one."; - file = "\x\cba\addons\events\fnc_remoteEvent.sqf"; + class removeKeyHandler { + description = "Removes an action from a keybind."; + file = "\x\cba\addons\events\fnc_removeKeyHandler.sqf"; }; - // CBA_fnc_removeDisplayHandler - class removeDisplayHandler - { - description = "Removes an action to a displayHandler"; - file = "\x\cba\addons\events\fnc_removeDisplayHandler.sqf"; + class addEventHandler { + description = "Registers an event handler for a specific CBA event."; + file = "\x\cba\addons\events\fnc_addEventHandler.sqf"; }; - // CBA_fnc_removeEventHandler - class removeEventHandler - { + class removeEventHandler { description = "Removes an event handler previously registered with CBA_fnc_addEventHandler."; file = "\x\cba\addons\events\fnc_removeEventHandler.sqf"; }; - // CBA_fnc_removeKeyHandler - class removeKeyHandler - { - description = "Removes an action to a keyhandler"; - file = "\x\cba\addons\events\fnc_removeKeyHandler.sqf"; - }; - // CBA_fnc_removeLocalEventHandler - class removeLocalEventHandler - { - description = "Removes an event handler previously registered with CBA_fnc_addLocalEventHandler."; - file = "\x\cba\addons\events\fnc_removeLocalEventHandler.sqf"; - }; - // CBA_fnc_whereLocalEvent - class whereLocalEvent - { - description = "Raises a CBA event only on the machine where parameter one is local."; - file = "\x\cba\addons\events\fnc_whereLocalEvent.sqf"; - }; - // CBA_fnc_addClientToServerEventhandler - class addClientToServerEventhandler { - description = "Registers an event handler for a client to server event which only runs on the server (thus is only needed on the server)"; - file = "\x\cba\addons\events\fnc_addClientToServerEventhandler.sqf"; - }; - // CBA_fnc_clientToServerEvent - class clientToServerEvent { - description = "Raises an CBA event only on the server (only broadcasted to server and not to other clients)"; - file = "\x\cba\addons\events\fnc_clientToServerEvent.sqf"; + class localEvent { + description = "Raises a CBA event on the local machine."; + file = "\x\cba\addons\events\fnc_localEvent.sqf"; }; - // CBA_fnc_removeClientToServerEvent - class removeClientToServerEvent { - description = "Removes client to server event"; - file = "\x\cba\addons\events\fnc_removeClientToServerEvent.sqf"; + class globalEvent { + description = "Raises a CBA event on all machines, including the local one."; + file = "\x\cba\addons\events\fnc_globalEvent.sqf"; }; - // CBA_fnc_addReceiverOnlyEventhandler - class addReceiverOnlyEventhandler { - description = "Registers an event handler for an CBA event which is only broadcasted to the receiver (and no other clients)"; - file = "\x\cba\addons\events\fnc_addReceiverOnlyEventhandler.sqf"; + class serverEvent { + description = "Raises a CBA event on the server machine."; + file = "\x\cba\addons\events\fnc_serverEvent.sqf"; }; - // CBA_fnc_receiverOnlyEvent - class receiverOnlyEvent { - description = "Raises an CBA event only on the receiver and is only broadcasted there"; - file = "\x\cba\addons\events\fnc_receiverOnlyEvent.sqf"; + class remoteEvent { + description = "Raises a CBA event on all machines, except the local one."; + file = "\x\cba\addons\events\fnc_remoteEvent.sqf"; }; - // CBA_fnc_removeReceiverOnlyEvent - class removeReceiverOnlyEvent { - description = "Removes receiver only event"; - file = "\x\cba\addons\events\fnc_removeReceiverOnlyEvent.sqf"; + class targetEvent { + description = "Raises a CBA event on all machines where this object or at least one of these objects are local."; + file = "\x\cba\addons\events\fnc_targetEvent.sqf"; }; - }; }; }; diff --git a/addons/events/XEH_curatorDisplayLoad.sqf b/addons/events/XEH_curatorDisplayLoad.sqf new file mode 100644 index 000000000..e388391ba --- /dev/null +++ b/addons/events/XEH_curatorDisplayLoad.sqf @@ -0,0 +1,6 @@ +#include "script_component.hpp" + +params ["_display"]; + +_display displayAddEventHandler ["KeyDown", {_this call FUNC(keyHandlerDown)}]; +_display displayAddEventHandler ["KeyUp", {_this call FUNC(keyHandlerUp)}]; diff --git a/addons/events/XEH_missionDisplayLoad.sqf b/addons/events/XEH_missionDisplayLoad.sqf new file mode 100644 index 000000000..d538d2618 --- /dev/null +++ b/addons/events/XEH_missionDisplayLoad.sqf @@ -0,0 +1,22 @@ +#include "script_component.hpp" + +params ["_display"]; + +uiNamespace setVariable ["CBA_missionDisplay", _display]; + +// re apply missions display event handlers when display is loaded (save game) +if (!isNil QGVAR(handlerHash)) then { + [GVAR(handlerHash), { + { + private _code = _x param [1]; + + if (!isNil "_code") then { + private _handler = _display displayAddEventHandler [_key, _code]; + _x set [0, _handler]; + }; + } forEach _value; + }] call CBA_fnc_hashEachPair; + + // copy hash reference to display namespace again, because it's not serialized in save games + _display setVariable [QGVAR(handlerHash), GVAR(handlerHash)]; +}; diff --git a/addons/events/XEH_preClientInit.sqf b/addons/events/XEH_preClientInit.sqf deleted file mode 100644 index 164b60530..000000000 --- a/addons/events/XEH_preClientInit.sqf +++ /dev/null @@ -1,101 +0,0 @@ -// Any registered functions used in the PreINIT phase must use the uiNamespace copies of the variable. -// So uiNamespace getVariable "CBA_fnc_hashCreate" instead of just CBA_fnc_hashCreate -VM -// #define DEBUG_MODE_FULL -#include "script_component.hpp" -/* - Custom events -*/ -LOG(MSG_INIT); - -// ["CBA_loadGame", { SLX_XEH_STR spawn FUNC(attach_handler) }] call CBA_fnc_addEventHandler; // EH is unimplemented due to unreliable -["CBA_playerSpawn", { LOG("Player spawn detected!") }] call (uiNamespace getVariable "CBA_fnc_addEventHandler"); - -SLX_XEH_STR spawn { - private ["_lastPlayer", "_newPlayer"]; - waitUntil {player == player}; - player addEventHandler ["Respawn", { - if(_this select 0 == player) then { - ["CBA_playerSpawn", _this] call (uiNamespace getVariable "CBA_fnc_localEvent") - }; - }]; -}; - - -// Display Eventhandlers - Abstraction layer -GVAR(attaching) = false; - -FUNC(handle_retach) = { - private ["_id", "_ar2"]; - // _key and _value - TRACE_2("",_key,_value); - { - _id = _x select 0; - if !(isNil "_id") then { - TRACE_2("Removing",_key,_id); - (findDisplay 46) displayRemoveEventHandler [_key, _id]; - }; - if (count _x != 1) then { - TRACE_2("Adding",_key,_x select 1); - _x set [0, (findDisplay 46) displayAddEventHandler [_key, _x select 1]]; - }; - } forEach _value; -}; - -CBA_EVENT_KEY_LOGIC = objNull; - -GVAR(keypressed) = -100; -GVAR(attach_count) = 0; - -// TODO: Stack/multiplex into single events per type ? -FUNC(attach_handler) = { - if !(isNull (findDisplay 46)) then { - TRACE_2("ReAttaching",GVAR(keypressed),GVAR(attach_count)); - GVAR(keypressed) = time; - [GVAR(handler_hash), {call FUNC(handle_retach)}] call (uiNamespace getVariable "CBA_fnc_hashEachPair"); - CBA_EVENTS_DONE = true; - INC(GVAR(attach_count)); - }; -}; - -// Display Eventhandlers - Higher level API specially for keyDown/Up and Action events -#define TIMEOUT 10 -// Workaround , in macros -#define UP [_this, 'keyup'] -#define DOWN [_this, 'keydown'] - -["KeyUp", QUOTE(UP call FUNC(keyHandler))] call (uiNamespace getVariable "CBA_fnc_addDisplayHandler"); -["KeyDown", QUOTE(DOWN call FUNC(keyHandler))] call (uiNamespace getVariable "CBA_fnc_addDisplayHandler"); - -// add keyhandlers to zeus interface -["CBA_curatorOpened", { - params ["_display"]; - _display displayAddEventHandler ["KeyUp", {UP call FUNC(keyHandler)}]; - _display displayAddEventHandler ["KeyDown", {DOWN call FUNC(keyHandler)}]; -}] call CBA_fnc_addEventHandler; - -SLX_XEH_STR spawn { - waitUntil { !isNull (findDisplay 46) }; - // Workaround for Single Player, mission editor, or mission, preview/continue, whatever, adding double handlers - if !(isMultiplayer) then { { (findDisplay 46) displayRemoveAllEventHandlers _x } forEach ["KeyUp", "KeyDown"] }; - - // Trigger will attach it.. - // call FUNC(attach_handler); - - // ["KeyDown", QUOTE(_this call FUNC(actionHandler))] call CBA_fnc_addDisplayHandler; - - // Workaround for displayEventhandlers falling off at gameLoad after gameRestart - // Once the last registered keypress is longer than TIMEOUT seconds ago, re-attach the handler. - if (isServer) then { // isServer = SP or MP server-client - // Use a trigger, runs every 0.5s, unscheduled execution - GVAR(keyTrigger) = createTrigger["EmptyDetector", [0,0,0], false]; - GVAR(keyTrigger) setTriggerStatements[QUOTE(if ((GVAR(keypressed) + TIMEOUT) < time) then { call FUNC(attach_handler) }), "", ""]; - } else { // dedicatedClient - // TODO: Find better dummy class to use - CBA_EVENT_KEY_LOGIC = SLX_XEH_DUMMY createVehicleLocal [0,0,0]; - CBA_EVENT_KEY_LOGIC addEventHandler ["Killed", { - call FUNC(attach_handler); - deleteVehicle CBA_EVENT_KEY_LOGIC; - }]; - CBA_EVENT_KEY_LOGIC setDamage 1; - }; -}; diff --git a/addons/events/XEH_preInit.sqf b/addons/events/XEH_preInit.sqf index ce7f056ce..b64fa7f4d 100644 --- a/addons/events/XEH_preInit.sqf +++ b/addons/events/XEH_preInit.sqf @@ -1,103 +1,71 @@ -// Any registered functions used in the PreINIT phase must use the uiNamespace copies of the variable. -// So uiNamespace getVariable "CBA_fnc_hashCreate" instead of just CBA_fnc_hashCreate -VM -//#define DEBUG_MODE_FULL #include "script_component.hpp" -/* - Custom events -*/ -LOG(MSG_INIT); -if (isNil "CBA_fnc_localEvent") then { diag_log "CBA_fnc_localEvent is nil!!";}; -// Initialisation required by CBA events. -CBA_eventHandlers = "Logic" createVehicleLocal [0, 0]; -CBA_eventHandlersLocal = "Logic" createVehicleLocal [0, 0]; -CBA_EVENTS_DONE = false; -PREP(NetRunEventTOR); +ADDON = false; + +// Initialisation required by CBA events. +GVAR(eventNamespace) = call CBA_fnc_createNamespace; +GVAR(eventHashes) = call CBA_fnc_createNamespace; -GVAR(event_holderToR) = "Logic" createVehicleLocal [0, 0]; +// can't add at preInit +0 spawn { + EVENT_PVAR_STR addPublicVariableEventHandler {(_this select 1) call CBA_fnc_localEvent}; -"CBA_ntor" addPublicVariableEventHandler { - (_this select 1) call FUNC(NetRunEventTOR); + if (isServer) then { + TEVENT_PVAR_STR addPublicVariableEventHandler {(_this select 1) call CBA_fnc_targetEvent}; + }; }; -if (isServer) then { - GVAR(event_holderCTS) = "Logic" createVehicleLocal [0, 0]; +#include "backwards_comp.sqf" - PREP(NetRunEventCTS); +ADDON = true; - "CBA_ncts" addPublicVariableEventHandler { - (_this select 1) call FUNC(NetRunEventCTS); - }; -}; +if (!hasInterface) exitWith {}; + +// Display Event Handlers +// Pressing "Restart" in the editor starts a completely new mission (preInit etc. are executed). The main display is never deleted though! +// This would cause douplicate display events to be added, because the old ones carry over while the new ones are added again. +// If we detect an already existing main display we remove all display events that were previously defined. +if (!isNull (uiNamespace getVariable ["CBA_missionDisplay", displayNull])) then { + GVAR(handlerHash) = (uiNamespace getVariable "CBA_missionDisplay") getVariable QGVAR(handlerHash); + [GVAR(handlerHash), { + { + (uiNamespace getVariable "CBA_missionDisplay") displayRemoveEventHandler [_key, _x param [0, -1]]; + } forEach _value; + }] call CBA_fnc_hashEachPair; -// TODO: Verify if this code is okay; there can be no player object ready at PreInit, thus it's not very useful -if (isServer || {alive player}) then { - // We want all events, as soon as they start arriving. - "CBA_e" addPublicVariableEventHandler { (_this select 1) call (uiNamespace getVariable "CBA_fnc_localEvent") }; - "CBA_l" addPublicVariableEventHandler { (_this select 1) call FUNC(remoteLocalEvent) }; + // to carry the hash over into a restarted game, we store the hashes array reference in the mission display namespace. + GVAR(handlerHash) = [[], []] call CBA_fnc_hashCreate; + (uiNamespace getVariable "CBA_missionDisplay") setVariable [QGVAR(handlerHash), GVAR(handlerHash)]; } else { - // Ignore the last event that was sent out before we joined. - SLX_XEH_STR spawn { - waitUntil { alive player }; - "CBA_e" addPublicVariableEventHandler { (_this select 1) call (uiNamespace getVariable "CBA_fnc_localEvent") }; - "CBA_l" addPublicVariableEventHandler { (_this select 1) call FUNC(remoteLocalEvent) }; - }; + GVAR(handlerHash) = [[], []] call CBA_fnc_hashCreate; }; -// Display Eventhandlers - Abstraction layer -GVAR(handler_hash) = [[], ""] call (uiNamespace getVariable "CBA_fnc_hashCreate"); - -// Display Eventhandlers - Higher level API specially for keyDown/Up and Action events -/* - Example: - class CfgSettings { class CBA { class Keys { class sys_attachments { cqb = 33 }; }; }; }; - - - Script (in sys_attachments addon (it has COMPONENT defined as sys_attachments)): - [QUOTE(COMPONENT), "cqb", { _this call GVAR(keyPressed) }] call cba_fnc_AddKeyHandlerFromConfig; -*/ -private ["_arUp", "_arDown"]; -GVAR(keyhandler_hash) = [[], []] call (uiNamespace getVariable "CBA_fnc_hashCreate"); -GVAR(keyhandlers_down) = [[], []] call (uiNamespace getVariable "CBA_fnc_hashCreate"); -GVAR(keyhandlers_up) = [[], []] call (uiNamespace getVariable "CBA_fnc_hashCreate"); -_arUp = [GVAR(keyhandler_hash), "keyup"] call (uiNamespace getVariable "CBA_fnc_hashGet"); -_arDown = [GVAR(keyhandler_hash), "keydown"] call (uiNamespace getVariable "CBA_fnc_hashGet"); -for "_i" from 0 to 250 do { - _arUp set [_i, []]; - _arDown set [_i, []]; -}; +PREP(keyHandler); +PREP(keyHandlerDown); +PREP(keyHandlerUp); -// Due to limitation, have to actually set the first time -[GVAR(keyhandler_hash), "keyup", _arUp] call (uiNamespace getVariable "CBA_fnc_hashSet"); -[GVAR(keyhandler_hash), "keydown", _arDown] call (uiNamespace getVariable "CBA_fnc_hashSet"); +["keyDown", FUNC(keyHandlerDown)] call CBA_fnc_addDisplayHandler; +["keyUp", FUNC(keyHandlerUp)] call CBA_fnc_addDisplayHandler; -GVAR(keyUpDownList) = []; -GVAR(keyDownList) = []; +private _keyHandlers = []; +_keyHandlers resize 250; -GVAR(keyHoldTimers) = [[], ""] call (uiNamespace getVariable "CBA_fnc_hashCreate"); +GVAR(keyDownStates) = _keyHandlers apply {[]}; +GVAR(keyUpStates) = + GVAR(keyDownStates); -PREP(keyHandler); -PREP(remoteLocalEvent); +GVAR(keyHandlersDown) = call CBA_fnc_createNamespace; +GVAR(keyHandlersUp) = call CBA_fnc_createNamespace; + +GVAR(keyDownActiveList) = []; +GVAR(keyUpActiveList) = []; + +GVAR(keyHoldTimers) = call CBA_fnc_createNamespace; FUNC(handleKeyDownUp) = { - private ["_hash"]; - _hash = _this select ((count _this)-1); - if(_hash in GVAR(keyDownList)) then { - GVAR(keyDownList) = GVAR(keyDownList) - [_hash]; - }; - if(([GVAR(keyHoldTimers), _hash] call cba_fnc_hashHasKey)) then { - [GVAR(keyHoldTimers), _hash] call cba_fnc_hashRem; - }; - false -}; + private _xUp = _this select (count _this - 1); -CBA_fnc_remoteLocalEvent = FUNC(remoteLocalEvent); // BWC + GVAR(keyUpActiveList) deleteAt (GVAR(keyUpActiveList) find _xUp); + GVAR(keyHoldTimers) setVariable [_xUp, nil]; -// Awaits XEH PostInit sequence completed -CBA_MISSION_START = false; -objNull spawn { - waitUntil {time > 0 && {(SLX_XEH_MACHINE select 8)}}; - CBA_MISSION_START = true; - TRACE_1("CBA_MISSION_START",nil); + false }; - -nil; diff --git a/addons/events/XEH_preStart.sqf b/addons/events/XEH_preStart.sqf index 7b3c0dfce..f7e90974d 100644 --- a/addons/events/XEH_preStart.sqf +++ b/addons/events/XEH_preStart.sqf @@ -1,6 +1,5 @@ #include "script_component.hpp" -PREP(NetRunEventTOR); -PREP(NetRunEventCTS); PREP(keyHandler); -PREP(remoteLocalEvent); +PREP(keyHandlerDown); +PREP(keyHandlerUp); diff --git a/addons/events/backwards_comp.sqf b/addons/events/backwards_comp.sqf new file mode 100644 index 000000000..8d3e54d28 --- /dev/null +++ b/addons/events/backwards_comp.sqf @@ -0,0 +1,103 @@ + +// imitate deprecated clientToServerEvent +CBA_fnc_addClientToServerEventhandler = { + diag_log text "[CBA]: Usage of deprecated CBA_fnc_addClientToServerEventhandler."; + if (!isServer) exitWith {}; + + private _eventsVar = format [QGVAR(CTS:%1), _this select 0]; + + if (isNil _eventsVar) then { + // store all eh ids. Needed for backwards comp, because CBA_fnc_removeClientToServerEvent removes all ehs with this name. No IDs. + missionNamespace setVariable [_eventsVar, []]; + }; + + (missionNamespace getVariable _eventsVar) pushBack ([_eventsVar, _this select 1] call CBA_fnc_addEventHandler); + + nil // no ID returned for this function +}; + +CBA_fnc_clientToServerEvent = { + [format [QGVAR(CTS:%1), _this select 0], _this select 1] call CBA_fnc_serverEvent; +}; + +CBA_fnc_removeClientToServerEvent = { + diag_log text "[CBA]: Usage of deprecated CBA_fnc_removeClientToServerEvent."; + if (!isServer) exitWith {}; + + private _eventsVar = format [QGVAR(CTS:%1), _this]; + + if (!isNil _eventsVar) then { + { + [_eventsVar, _x] call CBA_fnc_removeEventHandler; + } forEach (missionNamespace getVariable _eventsVar); + + missionNamespace setVariable [_eventsVar, nil]; + }; +}; + +// imitate deprecated receiverOnlyEvent +CBA_fnc_addReceiverOnlyEventhandler = { + diag_log text "[CBA]: Usage of deprecated CBA_fnc_addReceiverOnlyEventhandler."; + private _eventsVar = format [QGVAR(TOR:%1), _this select 0]; + + if (isNil _eventsVar) then { + // store all eh ids. Needed for backwards comp, because CBA_fnc_removeReceiverOnlyEvent removes all ehs with this name. No IDs. + missionNamespace setVariable [_eventsVar, []]; + }; + + (missionNamespace getVariable _eventsVar) pushBack ([_eventsVar, _this select 1] call CBA_fnc_addEventHandler); + + nil // no ID returned for this function +}; + +CBA_fnc_receiverOnlyEvent = { + (_this select 1) params ["_target"]; + + // emulate bug with this event: publicVariableServer does not trigger PVEH when called on the server - publicVariable does + if (isServer && {!local _target}) exitWith {}; + + [format [QGVAR(TOR:%1), _this select 0], _this select 1, _target] call CBA_fnc_targetEvent; +}; + +CBA_fnc_removeReceiverOnlyEvent = { + diag_log text "[CBA]: Usage of deprecated CBA_fnc_removeReceiverOnlyEvent."; + private _eventsVar = format [QGVAR(TOR:%1), _this]; + + if (!isNil _eventsVar) then { + { + [_eventsVar, _x] call CBA_fnc_removeEventHandler; + } forEach (missionNamespace getVariable _eventsVar); + + missionNamespace setVariable [_eventsVar, nil]; + }; +}; + +// imitate deprecated whereLocalEvent / remoteLocalEvent +CBA_fnc_addLocalEventHandler = { + diag_log text "[CBA]: Usage of deprecated CBA_fnc_addLocalEventHandler."; + private _eventsVar = format [QGVAR(WL:%1), _this select 0]; + + if (isNil _eventsVar) then { + // store all eh ids. Needed for backwards comp, because CBA_fnc_removeClientToServerEvent removes all ehs with this name. No IDs. + missionNamespace setVariable [_eventsVar, []]; + }; + + (missionNamespace getVariable _eventsVar) pushBack ([_eventsVar, _this select 1] call CBA_fnc_addEventHandler) // return handler id +}; + +CBA_fnc_whereLocalEvent = { + (_this select 1) params ["_target"]; + + [format [QGVAR(WL:%1), _this select 0], _this select 1, _target] call CBA_fnc_targetEvent; +}; + +// CBA_fnc_remoteLocalEvent, FUNC(remoteLocalEvent) + +CBA_fnc_removeLocalEventHandler = { + diag_log text "[CBA]: Usage of deprecated CBA_fnc_removeLocalEventHandler."; + private _eventsVar = format [QGVAR(WL:%1), _this select 0]; + + if (!isNil _eventsVar) then { + [_eventsVar, _this select 1] call CBA_fnc_removeEventHandler; + }; +}; diff --git a/addons/events/config.cpp b/addons/events/config.cpp index 3f47d1f99..6fda4995b 100644 --- a/addons/events/config.cpp +++ b/addons/events/config.cpp @@ -1,17 +1,15 @@ #include "script_component.hpp" -class CfgPatches -{ - class ADDON - { + +class CfgPatches { + class ADDON { units[] = {}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = { "CBA_common" }; + requiredAddons[] = {"CBA_common"}; version = VERSION; - author[] = {"Spooner", "Sickboy", "Xeno"}; + author[] = {"Spooner","Sickboy","Xeno","commy2"}; authorUrl = "https://github.com/CBATeam/CBA_A3"; }; }; + #include "CfgEventHandlers.hpp" #include "CfgFunctions.hpp" - - diff --git a/addons/events/fnc_NetRunEventCTS.sqf b/addons/events/fnc_NetRunEventCTS.sqf deleted file mode 100644 index 950b911a7..000000000 --- a/addons/events/fnc_NetRunEventCTS.sqf +++ /dev/null @@ -1,21 +0,0 @@ -/* ---------------------------------------------------------------------------- -Description: - Internal function only - -Author: - Xeno ----------------------------------------------------------------------------- */ - -#include "script_component.hpp" -SCRIPT(NetRunEventCTS); - -private ["_ea", "_p", "_pa"]; -_ea = GVAR(event_holderCTS) getVariable (_this select 0); -if (!isNil "_ea") then { - _pa = _this select 1; - if (!isNil "_pa") then { - {_pa call _x} forEach _ea; - } else { - {call _x} forEach _ea; - }; -}; diff --git a/addons/events/fnc_NetRunEventTOR.sqf b/addons/events/fnc_NetRunEventTOR.sqf deleted file mode 100644 index 35a8569b3..000000000 --- a/addons/events/fnc_NetRunEventTOR.sqf +++ /dev/null @@ -1,45 +0,0 @@ -/* ---------------------------------------------------------------------------- -Description: - Internal function only - -Author: - Xeno ----------------------------------------------------------------------------- */ - -#include "script_component.hpp" -SCRIPT(NetRunEventTOR); - -private ["_ea", "_p", "_pa", "_obj", "_tt", "_islocal", "_isgrp"]; -_tt = _this select 1; -_obj = if (typeName _tt == "ARRAY") then {_tt select 0} else {_tt}; -if (isNil "_obj" || {isNull _obj}) exitWith {}; -_islocal = if (typeName _obj != "GROUP") then { - _isgrp = false; - local _obj -} else { - _isgrp = true; - local (leader _obj) -}; -if (_islocal) then { - _ea = GVAR(event_holderToR) getVariable (_this select 0); - if (!isNil "_ea") then { - _pa = _this select 1; - if (!isNil "_pa") then { - {_pa call _x} forEach _ea; - } else { - {call _x} forEach _ea; - }; - }; -} else { - CBA_ntor = _this; - if (isServer) then { - _owner = if (!_isgrp) then { - owner _obj - } else { - owner (leader _obj) - }; - _owner publicVariableClient "CBA_ntor"; - } else { // not needed... redundant, who cares - publicVariableServer "CBA_ntor"; - }; -}; \ No newline at end of file diff --git a/addons/events/fnc_addClientToServerEventhandler.sqf b/addons/events/fnc_addClientToServerEventhandler.sqf deleted file mode 100644 index 74be28a88..000000000 --- a/addons/events/fnc_addClientToServerEventhandler.sqf +++ /dev/null @@ -1,27 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: CBA_fnc_addClientToServerEventhandler - -Description: - Registers an event handler for a client to server event which only runs on the server (thus is only needed on the server) - -Parameters: - _eventType - Type of event to handle [String]. - _handler - Function to call when event is raised [Code]. - -Returns: - Nothing - -Author: - Xeno ----------------------------------------------------------------------------- */ - -#include "script_component.hpp" -SCRIPT(addClientToServerEventhandler); - -if (!isServer) exitWith {}; - -private ["_ea"]; -_ea = GVAR(event_holderCTS) getVariable (_this select 0); -if (isNil "_ea") then {_ea = []}; -_ea pushBack (_this select 1); -GVAR(event_holderCTS) setVariable [_this select 0, _ea]; \ No newline at end of file diff --git a/addons/events/fnc_addDisplayHandler.sqf b/addons/events/fnc_addDisplayHandler.sqf index 7c77eecbd..e8e8bbb56 100644 --- a/addons/events/fnc_addDisplayHandler.sqf +++ b/addons/events/fnc_addDisplayHandler.sqf @@ -2,37 +2,39 @@ Function: CBA_fnc_addDisplayHandler Description: - Adds an action to a displayHandler + Adds an action to the main display. + They are reapplied after loading a save game. Actions only persist for the mission and are removed after restart. Parameters: - _type - Displayhandler type to attach to [String]. - _code - Code to execute upon event [String]. + _type - Display handler type to attach. + _code - Code to execute upon event. Returns: - the id of the attached handler + _id - The ID of the attached handler. Used to remove with "CBA_fnc_removeDisplayHandler" Examples: (begin example) - _id = ["KeyDown", "_this call myKeyDownEH"] call CBA_fnc_addDisplayHandler; + _id = ["KeyDown", {_this call myKeyDownEH}] call CBA_fnc_addDisplayHandler; (end) Author: - Sickboy + Sickboy, commy2 ---------------------------------------------------------------------------- */ -// #define DEBUG_MODE_FULL #include "script_component.hpp" SCRIPT(addDisplayHandler); -private ["_ar", "_id", "_idx"]; -params ["_type","_code"]; +if (!hasInterface) exitWith {-1}; + +params [["_type", "", [""]], ["_code", "", ["", {}]]]; _type = toLower _type; -// TODO: Verify if the eventhandler type exists? -_ar = [GVAR(handler_hash), _type] call CBA_fnc_hashGet; -if (typeName _ar != "ARRAY") then { _ar = [] }; -_id = if (isDedicated || {isNull (findDisplay 46)} || {!CBA_EVENTS_DONE}) then { nil } else { (findDisplay 46) displayAddEventhandler [_type, _code] }; -_idx = count _ar; -_ar set [_idx, [if (isNil "_id") then { nil } else { _id }, _code]]; -[GVAR(handler_hash), _type, _ar] call CBA_fnc_hashSet; -if (isNil "_id" && {!isDedicated} && {CBA_EVENTS_DONE}) then { SLX_XEH_STR spawn FUNC(attach_handler) }; -_idx; + +private _handlers = [GVAR(handlerHash), _type] call CBA_fnc_hashGet; + +private _handlerId = (uiNamespace getVariable ["CBA_missionDisplay", displayNull]) displayAddEventHandler [_type, _code]; + +private _id = _handlers pushBack [_handlerId, _code]; + +[GVAR(handlerHash), _type, _handlers] call CBA_fnc_hashSet; + +_id diff --git a/addons/events/fnc_addEventHandler.sqf b/addons/events/fnc_addEventHandler.sqf index 0b9904c5c..d1f13393d 100644 --- a/addons/events/fnc_addEventHandler.sqf +++ b/addons/events/fnc_addEventHandler.sqf @@ -5,35 +5,50 @@ Description: Registers an event handler for a specific CBA event. Parameters: - _eventType - Type of event to handle [String]. - _handler - Function to call when event is raised [Code]. + _eventName - Type of event to handle. + _eventFunc - Function to call when event is raised. Returns: - Index of the event handler (can be used with ). + _eventId - Unique ID of the event handler (can be used with ). + +Examples: + (begin example) + _id = ["test", {systemChat str _this}] call CBA_fnc_addEventHandler; + (end) Author: - Spooner + Spooner, commy2 ---------------------------------------------------------------------------- */ - #include "script_component.hpp" - SCRIPT(addEventHandler); -// ----------------------------------------------------------------------------- +params [["_eventName", "", [""]], ["_eventFunc", nil, [{}]]]; + +{ + if (_eventName isEqualTo "" || isNil "_eventFunc") exitWith {-1}; + + private _events = GVAR(eventNamespace) getVariable _eventName; + private _eventHash = GVAR(eventHashes) getVariable _eventName; + + // generate event name on logic + if (isNil "_events") then { + _events = []; + GVAR(eventNamespace) setVariable [_eventName, _events]; + + _eventHash = [[], -1] call CBA_fnc_hashCreate; + GVAR(eventHashes) setVariable [_eventName, _eventHash]; + }; -params ["_eventType","_handler"]; + private _internalId = _events pushBack _eventFunc; -private ["_handlers", "_handlerIndex"]; + // get last id + private _eventId = [_eventHash, "#lastId"] call CBA_fnc_hashGet; -_handlers = CBA_eventHandlers getVariable _eventType; + // inc id + _eventId = _eventId + 1; -if (isNil "_handlers") exitwith { - // No handlers for this event already exist, so make a new event type. - CBA_eventHandlers setVariable [_eventType, [_handler]]; - 0; -}; -// Handlers already recorded, so add another one. -_handlerIndex = _handlers pushBack _handler; -TRACE_2("Added",_eventType,_handlerIndex); + [_eventHash, "#lastId", _eventId] call CBA_fnc_hashSet; + [_eventHash, _eventId, _internalId] call CBA_fnc_hashSet; -_handlerIndex; + _eventId +} call CBA_fnc_directCall; diff --git a/addons/events/fnc_addKeyHandler.sqf b/addons/events/fnc_addKeyHandler.sqf index af9315751..c73d635c4 100644 --- a/addons/events/fnc_addKeyHandler.sqf +++ b/addons/events/fnc_addKeyHandler.sqf @@ -2,62 +2,79 @@ Function: CBA_fnc_addKeyHandler Description: - Adds an action to a keyhandler + Adds an action to a keybind. Parameters: - _key - Numerical key to attach action to [Integer]. - _settings - Shift, Ctrl, Alt required [Array]. - _code - Code to execute upon event [Code]. - _type - "keydown" (default) = keyDown, "keyup" = keyUp [String]. - _hashKey - used to identify this handler, randomly generated if not supplied [String]. - _holdKey - Will the key fire every frame while down [Bool] - _holdDelay - How long after keydown will the key event fire, in seconds. [Float] + _key - Key (DIK-Code) to attach action to. + _settings - Shift, Ctrl, Alt required. (default: [false, false, false]) + _code - Code to execute upon event. + _type - "keydown" or "keyup". [optional] (default: "keydown") + _hashKey - Key handler identifier. Randomly generated if not supplied. [optional] + _allowHold - Will the key fire every frame while hold down? [optional] (default: true) + _holdDelay - How long after keydown will the key event fire, in seconds. [optional] Returns: - Hash key [String] + _hashKey - Key handler identifier. Used to remove or change the key handler. Examples: (begin example) - [47, [true, false, false], { _this call myAction }] call CBA_fnc_addKeyHandler; + _id = [47, [true, false, false], { _this call myAction }] call CBA_fnc_addKeyHandler; (end) Author: - Sickboy - + Sickboy, commy2 ---------------------------------------------------------------------------- */ -// #define DEBUG_MODE_FULL #include "script_component.hpp" SCRIPT(addKeyHandler); -private ["_ar", "_entry", "_type", "_handlers", "_hashKey", "_holdDelay"]; -params ["_key","_settings","_code"]; -_type = if (count _this > 3) then { _this select 3 } else { "keydown" }; +if (!hasInterface) exitWith {""}; + +params [ + ["_key", 0, [0]], + ["_settings", [false, false, false], [[]], 3], + ["_code", {}, [{}]], + ["_type", "keydown", [""]], + ["_hashKey", "", [""]], + ["_allowHold", true, [false]], + ["_holdDelay", 0, [0]] +]; + _type = toLower _type; -_hashKey = if (count _this > 4) then { _this select 4 } else { format["%1%2%3%4%5%6%7%8", floor(random 100), floor(random 100), floor(random 100), floor(random 100), floor(random 100), floor(random 100), floor(random 100), floor(random 100)] }; -_hashKey = toLower(_hashKey); -_holdKey = if (count _this > 5) then { _this select 5 } else { true }; -_holdDelay = if (count _this > 6) then { _this select 6 } else { 0 }; - -if (_type in KEYS_ARRAY_WRONG) then { _type = ("key" + _type) }; -if !(_type in KEYS_ARRAY) exitWith { ERROR("Type does not exist") }; - -if(_type == "keydown") then { - _upHandlerArgs = +_this; - _upHandlerArgs set[2, FUNC(handleKeyDownUp)]; - _upHandlerArgs set[3, "keyup"]; - _upHandlerArgs set[4, _hashKey+"_cbadefaultuphandler"]; - _upHandlerArgs call cba_fnc_addKeyHandler; + +// add "key" prefix to "down" and "up" +if (_type in ["down", "up"]) then { + _type = "key" + _type; +}; + +// check if type is either "keydown" or "keyup" +if !(_type in ["keydown", "keyup"]) exitWith { + ERROR("Type does not exist"); + "" +}; + +// create random hash if none was supplied +if (_hashKey isEqualTo "") then { + _hashKey = format ["%1%2%3%4%5%6%7%8", floor random 100, floor random 100, floor random 100, floor random 100, floor random 100, floor random 100, floor random 100, floor random 100]; }; -[if (_type == "keydown") then { GVAR(keyhandlers_down) } else { GVAR(keyhandlers_up) }, _hashKey, [_key, _settings, _code, _holdKey, _holdDelay]] call CBA_fnc_hashSet; +_hashKey = toLower _hashKey; + +// add default keyup handler to keydown +if (_type isEqualTo "keydown") then { + private _params = + _this; + _params set [2, FUNC(handleKeyDownUp)]; + _params set [3, "keyup"]; + _params set [4, _hashKey + "_cbadefaultuphandler"]; + _params call CBA_fnc_addKeyHandler; +}; +private _hash = [GVAR(keyHandlersDown), GVAR(keyHandlersUp)] select (_type == "keyup"); +_hash setVariable [_hashKey, [_key, _settings, _code, _allowHold, _holdDelay]]; -_handlers = [GVAR(keyhandler_hash), _type] call CBA_fnc_hashGet; +private _keyHandlers = [GVAR(keyDownStates), GVAR(keyUpStates)] select (_type == "keyup"); -if (_key > count _handlers) then {_handlers resize(_key + 1)}; -_ar = _handlers select _key; -if (isNil"_ar")then{_ar=[]}; -_ar pushBack _hashKey; -_handlers set [_key, _ar]; +private _hashKeys = _keyHandlers param [_key, []]; +_hashKeys pushBackUnique _hashKey; // pushBackUnique. Fixes using addKeyHander twice with the same keyHash/id executing the newly added action twice. +_keyHandlers set [_key, _hashKeys]; -_hashKey; +_hashKey diff --git a/addons/events/fnc_addKeyHandlerFromConfig.sqf b/addons/events/fnc_addKeyHandlerFromConfig.sqf index 06e6b900b..ec857a746 100644 --- a/addons/events/fnc_addKeyHandlerFromConfig.sqf +++ b/addons/events/fnc_addKeyHandlerFromConfig.sqf @@ -2,15 +2,16 @@ Function: CBA_fnc_addKeyHandlerFromConfig Description: - Adds an action to a keyhandler, read from config + Adds an action to a keybind from config. Parameters: - _component - Classname under "CfgSettings" >> "CBA" >> "events" [String]. - _action - Action classname [String]. - _code - Code to execute upon event [Code]. - _type - "keydown" (default) = keyDown, "keyup" = keyUp [String]. + _component - Classname under "CfgSettings" >> "CBA" >> "events" + _action - Action name + _code - Code to execute upon event. + _type - "keydown" or "keyup". [optional] (default: "keydown") Returns: + _hashKey - Key handler identifier. Used to remove or change the key handler. Examples: (begin example) @@ -18,24 +19,37 @@ Examples: (end) Author: - Sickboy + Sickboy, commy2 ---------------------------------------------------------------------------- */ -// #define DEBUG_MODE_FULL #include "script_component.hpp" SCRIPT(addKeyHandlerFromConfig); -private ["_key", "_type"]; -params ["_component","_action","_code"]; -_type = if (count _this > 3) then { _this select 3 } else { "keydown" }; +if (!hasInterface) exitWith {""}; + +params [ + ["_component", "", [""]], + ["_action", "", [""]], + ["_code", {}, [{}]], + ["_type", "keydown", [""]] +]; + _type = toLower _type; -if (_type in KEYS_ARRAY_WRONG) then { _type = ("key" + _type) }; -if !(_type in KEYS_ARRAY) exitWith { ERROR("Type does not exist") }; -_hashKey = toLower(format["%1_%2", _component, _action]); - -_key = [_component, _action] call CBA_fnc_readKeyFromConfig; -if (_key select 0 > -1) exitWith { - [_key select 0, _key select 1, _code, _type, _hashKey] call CBA_fnc_addKeyHandler; - _hashKey; + +// add "key" prefix to "down" and "up" +if (_type in ["down", "up"]) then { + _type = "key" + _type; +}; + +// check if type is either "keydown" or "keyup" +if !(_type in ["keydown", "keyup"]) exitWith { + ERROR("Type does not exist"); + "" }; -""; +private _hashKey = toLower format ["%1_%2", _component, _action]; + +([_component, _action] call CBA_fnc_readKeyFromConfig) params ["_key", "_settings"]; + +if (_key <= 0) exitWith {""}; + +[_key, _settings, _code, _type, _hashKey] call CBA_fnc_addKeyHandler // return diff --git a/addons/events/fnc_addLocalEventHandler.sqf b/addons/events/fnc_addLocalEventHandler.sqf deleted file mode 100644 index ca6231377..000000000 --- a/addons/events/fnc_addLocalEventHandler.sqf +++ /dev/null @@ -1,42 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: CBA_fnc_addLocalEventHandler - -Description: - Registers an event handler for a specific CBA event which only runs where the first parameter (object) is local. - -Parameters: - _eventType - Type of event to handle [String]. - _handler - Function to call when event is raised [Code]. - -Returns: - Index of the event handler (can be used with ). - -Author: - Xeno ----------------------------------------------------------------------------- */ - -#include "script_component.hpp" - -SCRIPT(addLocalEventHandler); - -// ----------------------------------------------------------------------------- - -params ["_eventType","_handler"]; - -private ["_handlers", "_handlerIndex"]; - -_handlers = CBA_eventHandlersLocal getVariable _eventType; - -if (isNil "_handlers") then { - // No handlers for this event already exist, so make a new event type. - CBA_eventHandlersLocal setVariable [_eventType, [_handler]]; - _handlerIndex = 0; -} else { - // Handlers already recorded, so add another one. - _handlerIndex = count _handlers; - _handlers pushBack _handler; -}; - -TRACE_2("Added",_eventType,_handlerIndex); - -_handlerIndex; // Return. diff --git a/addons/events/fnc_addReceiverOnlyEventhandler.sqf b/addons/events/fnc_addReceiverOnlyEventhandler.sqf deleted file mode 100644 index ff3f70c2d..000000000 --- a/addons/events/fnc_addReceiverOnlyEventhandler.sqf +++ /dev/null @@ -1,25 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: CBA_fnc_addReceiverOnlyEventhandler - -Description: - Registers an event handler for an CBA event which is only broadcasted to the receiver (and no other clients) - -Parameters: - _eventType - Type of event to handle [String]. - _handler - Function to call when event is raised [Code]. - -Returns: - Nothing - -Author: - Xeno ----------------------------------------------------------------------------- */ - -#include "script_component.hpp" -SCRIPT(addReceiverOnlyEventhandler); - -private ["_ea"]; -_ea = GVAR(event_holderToR) getVariable (_this select 0); -if (isNil "_ea") then {_ea = []}; -_ea pushBack (_this select 1); -GVAR(event_holderToR) setVariable [_this select 0, _ea]; \ No newline at end of file diff --git a/addons/events/fnc_changeKeyHandler.sqf b/addons/events/fnc_changeKeyHandler.sqf index 63cb5b80e..62dfad5da 100644 --- a/addons/events/fnc_changeKeyHandler.sqf +++ b/addons/events/fnc_changeKeyHandler.sqf @@ -2,62 +2,65 @@ Function: CBA_fnc_changeKeyHandler Description: - Changes an action to a keyhandler + Changes the key of a key handler. Parameters: - _hashKey - String - _key - New key [integer] - _settings - Array of settings (shift, alt etc) - _type - Type of keyevent [String] - default keydown + _hashKey - Key handler identifier. + _key - New key (DIK-Code). + _settings - New Settings. Shift, Ctrl, Alt required. (default: [false, false, false]) + _type - "keydown" or "keyup". [optional] (default: "keydown") Returns: + None Examples: (begin example) - ["cba_somesystem_keyevent", 44, [false,false,false]] call CBA_fnc_changeKeyHandler; + [_id, 44, [false,false,false]] call CBA_fnc_changeKeyHandler; (end) Author: - Sickboy - + Sickboy, commy2 ---------------------------------------------------------------------------- */ -// #define DEBUG_MODE_FULL #include "script_component.hpp" SCRIPT(changeKeyHandler); -private ["_type", "_keyData", "_handlers", "_idx", "_myHandlers", "_ar"]; -params ["_hashKey","_key","_settings"]; -_type = if (count _this > 3) then { _this select 3 } else { "keydown" }; + +if (!hasInterface) exitWith {}; + +params [ + ["_hashKey", "", [""]], + ["_key", 0, [0]], + ["_settings", [false, false, false], [[]], 3], + ["_type", "keydown", [""]] +]; + _type = toLower _type; -if (_type in KEYS_ARRAY_WRONG) then { _type = ("key" + _type) }; -if !(_type in KEYS_ARRAY) exitWith { ERROR("Type does not exist") }; -_hashKey = toLower _hashKey; -_keyData = [if (_type == "keydown") then { GVAR(keyhandlers_down) } else { GVAR(keyhandlers_up) }, _hashKey] call CBA_fnc_hashGet; - -_handlers = [GVAR(keyhandler_hash), _type] call CBA_fnc_hashGet; - -// Remove existing key. -_exit = true; // Doesn't exis? -_idx = _keyData select 0; -if (count _handlers > _idx) then { - _myHandlers = _handlers select _idx; - if (_hashKey in _myHandlers) then { - _myHandlers = _myHandlers - [_hashKey]; - _handlers set [_idx, _myHandlers]; - _exit = false; // does exist - }; + +// add "key" prefix to "down" and "up" +if (_type in ["down", "up"]) then { + _type = "key" + _type; }; -if (_exit) exitWith { false }; +// check if type is either "keydown" or "keyup" +if !(_type in ["keydown", "keyup"]) exitWith { + ERROR("Type does not exist"); +}; + +_hashKey = toLower _hashKey; -// Add to new key. -if(_key>(count _handlers))then{_handlers resize(_key+1);}; -_ar = _handlers select _key; -if(isNil"_ar")then{_ar=[]}; -_ar pushBack _hashKey; -_handlers set [_key, _ar]; +private _hash = [GVAR(keyHandlersDown), GVAR(keyHandlersUp)] select (_type == "keyup"); +private _keyData = _hash getVariable _hashKey; +private _key = _keyData select 0; -// Update keydata -_keyData set [0, _key]; -_keyData set [1, _settings]; +private _keyHandlers = [GVAR(keyDownStates), GVAR(keyUpStates)] select (_type == "keyup"); + +if (count _keyHandlers > _key) then { + private _hashKeys = _keyHandlers select _key; + _hashKeys = _hashKeys - [_hashKey]; + _hashKeys pushBack _hashKey; + _keyHandlers set [_key, _hashKeys]; + + _keyData set [0, _key]; + _keyData set [1, _settings]; +}; -true; +nil diff --git a/addons/events/fnc_clientToServerEvent.sqf b/addons/events/fnc_clientToServerEvent.sqf deleted file mode 100644 index 76cb21acf..000000000 --- a/addons/events/fnc_clientToServerEvent.sqf +++ /dev/null @@ -1,26 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: CBA_fnc_clientToServerEvent - -Description: - Raises an CBA event only on the server (only broadcasted to server and not to other clients) - -Parameters: - _eventType - Type of event to publish [String]. - _params - Parameters to pass to the event handlers [Array]. - -Returns: - nil - -Author: - Xeno ----------------------------------------------------------------------------- */ - -#include "script_component.hpp" -SCRIPT(clientToServerEvent); - -if (isServer) then { // for hosted environment - _this call FUNC(NetRunEventCTS); -} else { - CBA_ncts = _this; - publicVariableServer "CBA_ncts"; -}; \ No newline at end of file diff --git a/addons/events/fnc_globalEvent.sqf b/addons/events/fnc_globalEvent.sqf index bc6042f17..5e4801286 100644 --- a/addons/events/fnc_globalEvent.sqf +++ b/addons/events/fnc_globalEvent.sqf @@ -5,23 +5,26 @@ Description: Raises a CBA event on all machines, including the local one. Parameters: - _eventType - Type of event to publish [String]. - _params - Parameters to pass to the event handlers [Array]. + _eventName - Type of event to publish. + _params - Parameters to pass to the event handlers. Returns: - nil + None + +Examples: + (begin example) + ["test", ["global"]] call CBA_fnc_globalEvent; + (end) Author: - Spooner + Spooner, commy2 ---------------------------------------------------------------------------- */ - #include "script_component.hpp" - SCRIPT(globalEvent); -// ---------------------------------------------------------------------------- +params [["_eventName", "", [""]], ["_params", []]]; -_this call CBA_fnc_remoteEvent; -_this call CBA_fnc_localEvent; +CALL_EVENT(_params,_eventName); +SEND_EVENT_TO_OTHERS(_params,_eventName); -nil; // Return. +nil diff --git a/addons/events/fnc_keyHandler.sqf b/addons/events/fnc_keyHandler.sqf index f9cee6b3c..e35b073c3 100644 --- a/addons/events/fnc_keyHandler.sqf +++ b/addons/events/fnc_keyHandler.sqf @@ -1,200 +1,14 @@ /* ---------------------------------------------------------------------------- Internal Function: CBA_events_fnc_keyHandler - Description: - Executes the key's handler - + Executes the key's handler, bwc for ace interaction menu Author: - Sickboy + commy2 ---------------------------------------------------------------------------- */ // #define DEBUG_MODE_FULL #include "script_component.hpp" SCRIPT(keyHandler); -private ["_settings", "_code", "_handled", "_result", "_handlers", "_myHandlers", "_idx", "_data", "_keyhandlers"]; -#ifdef DEBUG_MODE_FULL - private ["_ar"]; - _ar = []; -#endif - -params ["_keyData","_type"]; -_type = toLower _type; - -_idx = _keyData select 1; -if(_idx == 0) exitWith {}; - -GVAR(keypressed) = time; - -_handled = false; // If true, suppress the default handling of the key. -_result = false; - -_keyhandlers = if(_type == "keydown") then { GVAR(keyhandlers_down) } else { GVAR(keyhandlers_up) }; - - -if(_type == "keydown") then { - _handlers = [GVAR(keyhandler_hash), "keydown"] call CBA_fnc_hashGet; - if (count _handlers > _idx) then { - - _myHandlers = _handlers select _idx; - if (isNil "_myHandlers") exitWith {}; - if (typeName _myHandlers != "ARRAY") exitWith {}; - { - _data = [GVAR(keyhandlers_down), _x] call CBA_fnc_hashGet; - TRACE_2("",_data,_x); - _settings = _data select 1; - _code = _data select 2; - - // Verify if the required modifier keys are present - _valid = true; - // Cannot compare booleans, so must use ! && etc. - for "_i" from 0 to 2 do { if (((_settings select _i) && {!(_keyData select (_i + 2))}) || {(!(_settings select _i) && {(_keyData select (_i + 2))})}) exitWith { _valid = false } }; - if (_valid) then { - #ifdef DEBUG_MODE_FULL - _ar pushBack _code; - #endif - - _holdKey = _data select 3; - _execute = true; - - _holdDelay = _data select 4; - _holdTime = 0; - if(_holdDelay > 0) then { - if(!([GVAR(keyHoldTimers), (_x + "_cbadefaultuphandler")] call cba_fnc_hashHasKey)) then { - [GVAR(keyHoldTimers), (_x + "_cbadefaultuphandler"), diag_tickTime + _holdDelay] call cba_fnc_hashSet; - }; - _holdTime = [GVAR(keyHoldTimers), (_x + "_cbadefaultuphandler")] call cba_fnc_hashGet; - if(diag_tickTime < _holdTime) then { - _execute = false; - }; - }; - if(_execute) then { - if(!_holdKey) then { - if((_x + "_cbadefaultuphandler") in GVAR(keyDownList)) then { - _execute = false; - } else { - GVAR(keyDownList) pushBack (_x + "_cbadefaultuphandler"); - }; - }; - if(_execute) then { - _args = +_keyData; - _args pushBack +_data; - _args pushBack _x; - _result = _args call _code; - - if (isNil "_result") then { - TRACE_1("WARNING: Non-boolean result from handler.",_result); - _result = false; - } - else { - if (typeName _result != "BOOL") then { - TRACE_1("WARNING: Non-boolean result from handler.",_result); - _result = false; - }; - }; - - // If any handler says that it has completely _handled_ the keypress, - // then don't allow other handlers to be tried at all. - }; - }; - if (_result) exitWith { _handled = true }; - }; - } forEach _myHandlers; - }; - /* - Too have a valid key up we first need to have a valid key down of the same combo! - - If we do, we add it to a list of pressed key up combos, then on key up we check that - list to see if we have a valid key up. - */ - _handlers = [GVAR(keyhandler_hash), "keyup"] call CBA_fnc_hashGet; - if (count _handlers > _idx) then { - _myHandlers = _handlers select _idx; - if (isNil "_myHandlers") exitWith {}; - if (typeName _myHandlers != "ARRAY") exitWith {}; - { - if(!(_x in GVAR(keyUpDownList))) then { - _data = [GVAR(keyhandlers_up), _x] call CBA_fnc_hashGet; - TRACE_2("",_data,_x); - _settings = _data select 1; - _code = _data select 2; - // Verify if the required modifier keys are present - _valid = true; - // Cannot compare booleans, so must use ! && etc. - for "_i" from 0 to 2 do { if (((_settings select _i) && {!(_keyData select (_i + 2))}) || {(!(_settings select _i) && {(_keyData select (_i + 2))})}) exitWith { _valid = false } }; - if (_valid) then { - #ifdef DEBUG_MODE_FULL - _ar pushBack _code; - #endif - - GVAR(keyUpDownList) pushBack _x; - }; - }; - } forEach _myHandlers; - }; -} else { - _handlers = [GVAR(keyhandler_hash), "keyup"] call CBA_fnc_hashGet; - - _ignoredUpKeys = []; - _remHandlers = []; - { - _data = [GVAR(keyhandlers_up), _x] call CBA_fnc_hashGet; - TRACE_2("",_data,_x); - _key = _data select 0; - _settings = _data select 1; - _code = _data select 2; - // Verify if the required modifier keys are present - if (_key == _idx || - {_idx == 0x2A} || {_idx == 0x36} || // shift - {_idx == 0x1D} || {_idx == 0x9D} || // ctrl - {_idx == 0x38} || {_idx == 0xB8} // alt - ) then { - if(!(_key in _ignoredUpKeys)) then { - _valid = false; - // Cannot compare booleans, so must use ! && etc. - if(_idx != _key) then { - if((_settings select 0) && {_idx == 0x2A} || {_idx == 0x36}) then { - _valid = true; - } else { - if((_settings select 1) && {_idx == 0x1D} || {_idx == 0x9D}) then { - _valid = true; - } else { - if((_settings select 2) && {_idx == 0x38} || {_idx == 0xB8}) then { - _valid = true; - }; - }; - }; - } else { - _valid = true; - }; - if (_valid) then { - _args = +_keyData; - _args pushBack +_data; - _args pushBack _x; - _result = _args call _code; - - if (isNil "_result") then { - WARNING("Nil result from handler."); - _result = false; - } - else { - if (typeName _result != "BOOL") then { - TRACE_1("WARNING: Non-boolean result from handler.",_result); - _result = false; - }; - }; - _remHandlers pushBack _x; - // If any handler says that it has completely _handled_ the keypress, - // then don't allow other handlers to be tried at all. - if (_result) then { _ignoredUpKeys pushBack _key; }; - }; - } else { - _remHandlers pushBack _x; - }; - - }; - } forEach GVAR(keyUpDownList); - GVAR(keyUpDownList) = GVAR(keyUpDownList) - _remHandlers; -}; -TRACE_4("keyPressed",_this,_ar,_myHandlers,_handled); +params ["_args", "_type"]; -_handled; +_args call ([FUNC(keyHandlerDown), FUNC(keyHandlerUp)] select (_type == "keyUp")); diff --git a/addons/events/fnc_keyHandlerDown.sqf b/addons/events/fnc_keyHandlerDown.sqf new file mode 100644 index 000000000..9c804fd36 --- /dev/null +++ b/addons/events/fnc_keyHandlerDown.sqf @@ -0,0 +1,70 @@ +/* ---------------------------------------------------------------------------- +Internal Function: CBA_events_fnc_keyHandlerDown +Description: + Executes the key's handler +Author: + Sickboy, commy2 +---------------------------------------------------------------------------- */ +// #define DEBUG_MODE_FULL +#include "script_component.hpp" +SCRIPT(keyHandlerDown); + +params ["", "_inputKey"]; + +if (_inputKey == 0) exitWith {}; + +private _inputSettings = _this select [2,3]; + +private _blockInput = false; + +{ + private _keybindParams = GVAR(keyHandlersDown) getVariable _x; + + _keybindParams params ["", "_keybindSettings", "_code", "_allowHold", "_holdDelay"]; + + // Verify if the required modifier keys are present + if (_keybindSettings isEqualTo _inputSettings) then { + private _xUp = _x + "_cbadefaultuphandler"; + private _execute = true; + private _holdTime = 0; + + if (_holdDelay > 0) then { + _holdTime = GVAR(keyHoldTimers) getVariable _xUp; + + if (isNil "_holdTime") then { + _holdTime = diag_tickTime + _holdDelay; + GVAR(keyHoldTimers) setVariable [_xUp, _holdTime]; + }; + + if (diag_tickTime < _holdTime) then { + _execute = false; + }; + }; + + // check if either holding down a key is enabled or if the key wasn't already held down + if (_execute && {_allowHold || {GVAR(keyUpActiveList) pushBackUnique _xUp != -1}}) then { + private _params = + _this; + _params pushBack + _keybindParams; + _params pushBack _x; + + _blockInput = _params call _code; + }; + + if (_blockInput isEqualTo true) exitWith {}; + }; +} forEach (GVAR(keyDownStates) param [_inputKey, []]); + +// To have a valid key up we first need to have a valid key down of the same combo! +// If we do, we add it to a list of pressed key up combos, then on key up we check that list to see if we have a valid key up. +{ + private _keybindParams = GVAR(keyHandlersUp) getVariable _x; + + _keybindParams params ["", "_keybindSettings"]; + + // Verify if the required modifier keys are present + if (_keybindSettings isEqualTo _inputSettings) then { + GVAR(keyDownActiveList) pushBackUnique _x; + }; +} forEach (GVAR(keyUpStates) param [_inputKey, []]); + +_blockInput diff --git a/addons/events/fnc_keyHandlerUp.sqf b/addons/events/fnc_keyHandlerUp.sqf new file mode 100644 index 000000000..bdb436ebf --- /dev/null +++ b/addons/events/fnc_keyHandlerUp.sqf @@ -0,0 +1,53 @@ +/* ---------------------------------------------------------------------------- +Internal Function: CBA_events_fnc_keyHandlerUp +Description: + Executes the key's handler +Author: + Sickboy, commy2 +---------------------------------------------------------------------------- */ +// #define DEBUG_MODE_FULL +#include "script_component.hpp" +SCRIPT(keyHandlerUp); + +params ["", "_inputKey"]; + +if (_inputKey == 0) exitWith {}; + +private _blockedUpKeys = []; +private _removeHandlers = []; + +{ + private _keybindParams = GVAR(keyHandlersUp) getVariable _x; + + _keybindParams params ["_keybind", "_keybindSettings", "_code"]; + + // Verify if the required modifier keys are present + if (_inputKey in [_keybind, DIK_LSHIFT, DIK_RSHIFT, DIK_LCONTROL, DIK_RCONTROL, DIK_LMENU, DIK_RMENU]) then { + if !(_keybind in _blockedUpKeys) then { + if ( + _inputKey == _keybind + || {(_keybindSettings select 0 && {_inputKey in [DIK_LSHIFT, DIK_RSHIFT]}) + || {(_keybindSettings select 1 && {_inputKey in [DIK_LCONTROL, DIK_RCONTROL]}) + || {(_keybindSettings select 2 && {_inputKey in [DIK_LMENU, DIK_RMENU]})}}} + ) then { + private _params = + _this; + _params pushBack + _keybindParams; + _params pushBack _x; + + private _blockInput = _params call _code; + + if (_blockInput isEqualTo true) then { + _blockedUpKeys pushBack _keybind; + }; + + _removeHandlers pushBack _x; + }; + } else { + _removeHandlers pushBack _x; + }; + }; +} forEach GVAR(keyDownActiveList); + +GVAR(keyDownActiveList) = GVAR(keyDownActiveList) - _removeHandlers; + +false diff --git a/addons/events/fnc_localEvent.sqf b/addons/events/fnc_localEvent.sqf index 64efe6098..aea61985c 100644 --- a/addons/events/fnc_localEvent.sqf +++ b/addons/events/fnc_localEvent.sqf @@ -2,42 +2,26 @@ Function: CBA_fnc_localEvent Description: - Raises a CBA event only on the local machine. + Raises a CBA event on the local machine. Parameters: - _eventType - Type of event to publish [String]. - _params - Parameters to pass to the event handlers [Array, defaults to nil]. + _eventName - Type of event to publish. + _params - Parameters to pass to the event handlers. Returns: - nil + _return - return value of the last added event function. + +Examples: + (begin example) + ["test", ["local"]] call CBA_fnc_localEvent; + (end) Author: - Spooner + Spooner, commy2 ---------------------------------------------------------------------------- */ - #include "script_component.hpp" - SCRIPT(localEvent); -// ---------------------------------------------------------------------------- - -params ["_eventType", ["_params",nil]]; - -private "_handlers"; - -// Run locally. -_handlers = CBA_eventHandlers getVariable _eventType; - -if (!isNil "_handlers") then { - { - if (!isNil "_x") then { - if (isNil "_params") then { - call _x; - } else { - _params call _x; - }; - }; - } forEach _handlers; -}; +params [["_eventName", "", [""]], ["_params", []]]; -nil; // Return. +CALL_EVENT(_params,_eventName) // return diff --git a/addons/events/fnc_readKeyFromConfig.sqf b/addons/events/fnc_readKeyFromConfig.sqf index e9bb5d6dc..a4e10ee56 100644 --- a/addons/events/fnc_readKeyFromConfig.sqf +++ b/addons/events/fnc_readKeyFromConfig.sqf @@ -2,13 +2,15 @@ Function: CBA_fnc_readKeyFromConfig Description: - Reads key setting from config + Reads key setting from config. Parameters: - _component - Classname under "CfgSettings" >> "CBA" >> "events" [String]. - _action - Action classname [String]. + _component - Classname under "CfgSettings" >> "CBA" >> "events" + _action - Action name Returns: + _key - Key (DIK-Code) + _settings - Shift, Ctrl, Alt modifiers Examples: (begin example) @@ -16,25 +18,32 @@ Examples: (end) Author: - Sickboy + Sickboy, commy2 ---------------------------------------------------------------------------- */ #include "script_component.hpp" SCRIPT(readKeyFromConfig); -private ["_settings"]; -params ["_component","_action"]; -_settings = [false, false, false]; -if (isNumber(CFGSETTINGS >> _component >> _action)) exitWith { - TRACE_2("",_this,getNumber(CFGSETTINGS >> _component >> _action)); - [getNumber(CFGSETTINGS >> _component >> _action), _settings]; +params [["_component", "", [""]], ["_action", "", [""]]]; + +private _config = CFGSETTINGS >> _component >> _action; + +private _key = -1; +private _settings = [false, false, false]; + +if (isNumber _config) then { + TRACE_2("",_this,getNumber _config); + _key = getNumber _config; }; -if (isClass(CFGSETTINGS >> _component >> _action)) exitWith { - TRACE_2("",_this,getNumber(CFGSETTINGS >> _component >> _action >> "key")); +if (isClass _config) then { + TRACE_2("",_this,getNumber (_config >> "key")); + _key = getNumber (_config >> "key"); + { - if (getNumber(CFGSETTINGS >> _component >> _action >> _x) == 1) then { _settings set [_forEachIndex, true] }; + if (getNumber (_config >> _x) == 1) then { + _settings set [_forEachIndex, true]; + }; } forEach ["shift", "ctrl", "alt"]; - [getNumber(CFGSETTINGS >> _component >> _action >> "key"), _settings]; }; -[-1, _settings]; +[_key, _settings] diff --git a/addons/events/fnc_receiverOnlyEvent.sqf b/addons/events/fnc_receiverOnlyEvent.sqf deleted file mode 100644 index 03dc496fa..000000000 --- a/addons/events/fnc_receiverOnlyEvent.sqf +++ /dev/null @@ -1,38 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: CBA_fnc_receiverOnlyEvent - -Description: - Raises an CBA event only on the receiver and is only broadcasted there - Can be called on any client or on the server. - If called on a client the params are broadcasted to the server first, server then checks the owner and sends the params only to that specific client - -Parameters: - _eventType - Type of event to publish [String]. - _params - Parameters to pass to the event handlers [Array]. First param must be an object to check for the owner!!! - - -Returns: - nil - -Author: - Xeno ----------------------------------------------------------------------------- */ - -#include "script_component.hpp" -SCRIPT(receiverOnlyEvent); - -private ["_tt", "_obj", "_isLocal"]; -_tt = _this select 1; -_obj = if (typeName _tt == "ARRAY") then {_tt select 0} else {_tt}; -if (isNil "_obj" || {isNull _obj}) exitWith {}; -_islocal = if (typeName _obj != "GROUP") then { - local _obj -} else { - local (leader _obj) -}; -if (!_isLocal) then { - CBA_ntor = _this; - publicVariableServer "CBA_ntor"; -} else { - _this call FUNC(NetRunEventTOR); -}; \ No newline at end of file diff --git a/addons/events/fnc_remoteEvent.sqf b/addons/events/fnc_remoteEvent.sqf index f63d27e7f..0c3ddfc5f 100644 --- a/addons/events/fnc_remoteEvent.sqf +++ b/addons/events/fnc_remoteEvent.sqf @@ -2,26 +2,28 @@ Function: CBA_fnc_remoteEvent Description: - Raises a CBA event on all machines EXCEPT the local one. + Raises a CBA event on all machines, except the local one. Parameters: - _eventType - Type of event to publish [String]. - _params - Parameters to pass to the event handlers [Array]. + _eventName - Type of event to publish. + _params - Parameters to pass to the event handlers. Returns: - nil + None + +Examples: + (begin example) + ["test", ["remote"]] call CBA_fnc_remoteEvent; + (end) Author: - Spooner + Spooner, commy2 ---------------------------------------------------------------------------- */ - #include "script_component.hpp" - SCRIPT(remoteEvent); -// ---------------------------------------------------------------------------- -// Run remotely. -CBA_e = _this; -publicVariable "CBA_e"; // Nasty short name to limit bandwidth. +params [["_eventName", "", [""]], ["_params", []]]; + +SEND_EVENT_TO_OTHERS(_params,_eventName); -nil; // Return. +nil diff --git a/addons/events/fnc_remoteLocalEvent.sqf b/addons/events/fnc_remoteLocalEvent.sqf deleted file mode 100644 index b1ef0b22c..000000000 --- a/addons/events/fnc_remoteLocalEvent.sqf +++ /dev/null @@ -1,51 +0,0 @@ -/* ---------------------------------------------------------------------------- -Internal Function - -Description: - Raises a CBA event only on the machine where parameter one is local. - -Parameters: - _eventType - Type of event to publish [String]. - _params - Parameters to pass to the event handlers. First param must be the object to check - -Returns: - nil - -Author: - Xeno ----------------------------------------------------------------------------- */ - -#include "script_component.hpp" - -SCRIPT(remoteLocalEvent); - -// ---------------------------------------------------------------------------- -params ["_eventType", ["_params",nil]]; - -private "_locobj"; -_locobj = if (typeName _params == typeName []) then {_params select 0} else {_params}; - -// doing a local check first -if (!local _locobj) exitWith { - TRACE_1("Not local",_locobj); - nil -}; - -TRACE_1("",_locobj); - -private "_handlers"; -_handlers = CBA_eventHandlersLocal getVariable _eventType; - -if (!isNil "_handlers") then { - { - if (!isNil "_x") then { - if (isNil "_params") then { - call _x; - } else { - _params call _x; - }; - }; - } forEach _handlers; -}; - -nil; // Return. diff --git a/addons/events/fnc_removeClientToServerEvent.sqf b/addons/events/fnc_removeClientToServerEvent.sqf deleted file mode 100644 index c20d28ef5..000000000 --- a/addons/events/fnc_removeClientToServerEvent.sqf +++ /dev/null @@ -1,20 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: CBA_fnc_removeClientToServerEvent - -Description: - Removes an event handler previously registered with CBA_fnc_addClientToServerEventhandler. - -Parameters: - _eventType - Type of event to remove [String]. - -Returns: - nil - -Author: - Xeno ----------------------------------------------------------------------------- */ - -#include "script_component.hpp" -SCRIPT(removeClientToServerEvent); - -if (!isNil {GVAR(event_holderCTS) getVariable _this}) then {GVAR(event_holderCTS) setVariable [_this, nil]}; diff --git a/addons/events/fnc_removeDisplayHandler.sqf b/addons/events/fnc_removeDisplayHandler.sqf index e436b3a88..47a828949 100644 --- a/addons/events/fnc_removeDisplayHandler.sqf +++ b/addons/events/fnc_removeDisplayHandler.sqf @@ -2,13 +2,14 @@ Function: CBA_fnc_removeDisplayHandler Description: - Removes an action to a displayHandler + Removes an action from the main display. Parameters: - _type - Displayhandler type to attach to [String]. - _id - Displayhandler ID to remove [Code]. + _type - Display handler type to remove. + _id - Display handler ID to remove. Returns: + None Examples: (begin example) @@ -16,22 +17,29 @@ Examples: (end) Author: - Sickboy + Sickboy, commy2 ---------------------------------------------------------------------------- */ #include "script_component.hpp" SCRIPT(removeDisplayHandler); -private ["_ar", "_entry"]; -params ["_type","_index"]; +if (!hasInterface) exitWith {}; + +params [["_type", "", [""]], ["_id", -1, [0]]]; _type = toLower _type; -_ar = [GVAR(handler_hash), _type] call CBA_fnc_hashGet; -if (typeName _ar == "ARRAY") then { - if (count _ar <= _index) exitWith {}; // Doesn't exist - _entry = _ar select _index; - if (count _entry > 1) then { - if !(isDedicated) then { (findDisplay 46) displayRemoveEventhandler [_type, _entry select 0] }; - _ar set [_index, [nil]]; - [GVAR(handler_hash), _type, _ar] call CBA_fnc_hashSet; - }; + +if (_id < 0) exitWith {}; + +private _handlers = [GVAR(handlerHash), _type] call CBA_fnc_hashGet; + +private _handler = _handlers param [_id]; + +if (!isNil "_handler") then { + (uiNamespace getVariable ["CBA_missionDisplay", displayNull]) displayRemoveEventHandler [_type, _handler param [0, -1]]; + + _handlers set [_id, []]; + + [GVAR(handlerHash), _type, _handlers] call CBA_fnc_hashSet; }; + +nil diff --git a/addons/events/fnc_removeEventHandler.sqf b/addons/events/fnc_removeEventHandler.sqf index a376d7e9a..6f5dd71f6 100644 --- a/addons/events/fnc_removeEventHandler.sqf +++ b/addons/events/fnc_removeEventHandler.sqf @@ -5,45 +5,46 @@ Description: Removes an event handler previously registered with CBA_fnc_addEventHandler. Parameters: - _eventType - Type of event to remove [String]. - _handlerIndex - Index of the event handler to remove [Number]. + _eventName - Type of event to remove. + _eventId - Unique ID of the event handler to remove. Returns: - nil + None -TODO: - Use Hash to store handlers as a sparse array, to save on lots of empty - elements in the array if lots of removes are made. +Examples: + (begin example) + ["test", _id] call CBA_fnc_removeEventHandler; + (end) Author: - Spooner + Spooner, commy2 ---------------------------------------------------------------------------- */ - #include "script_component.hpp" - SCRIPT(removeEventHandler); -// ----------------------------------------------------------------------------- +params [["_eventName", "", [""]], ["_eventId", -1, [0]]]; + +{ + if (_eventId < 0) exitWith {}; + + private _events = GVAR(eventNamespace) getVariable _eventName; + private _eventHash = GVAR(eventHashes) getVariable _eventName; -params ["_eventType","_handlerIndex"]; + if (isNil "_events") exitWith {}; -private "_handlers"; + private _internalId = [_eventHash, _eventId] call CBA_fnc_hashGet; -_handlers = CBA_eventHandlers getVariable _eventType; + if (_internalId != -1) then { + _events deleteAt _internalId; + [_eventHash, _eventId] call CBA_fnc_hashRem; -if (isNil "_handlers") then { - WARNING("Event type not registered: " + (str _eventType)); -} else { - if (count _handlers > _handlerIndex) then { - if (isNil { _handlers select _handlerIndex } ) then { - WARNING("Handler for event " + (str _eventType) + " index " + (str _handlerIndex) + " already removed."); - } else { - _handlers set [_handlerIndex, nil]; - TRACE_2("Removed",_eventType,_handlerIndex); - }; - } else { - WARNING("Handler for event " + (str _eventType) + " index " + (str _handlerIndex) + " never set."); + // decrement all higher internal ids, to adjust to new array position, _key == _eventId, _value == _internalId + [_eventHash, { + if (_value > _internalId && {!(_key isEqualTo "#lastId")}) then { + [_eventHash, _key, _value - 1] call CBA_fnc_hashSet; + }; + }] call CBA_fnc_hashEachPair; }; -}; +} call CBA_fnc_directCall; -nil; // Return. +nil diff --git a/addons/events/fnc_removeKeyHandler.sqf b/addons/events/fnc_removeKeyHandler.sqf index 249cc75b2..88f2f0c51 100644 --- a/addons/events/fnc_removeKeyHandler.sqf +++ b/addons/events/fnc_removeKeyHandler.sqf @@ -2,49 +2,62 @@ Function: CBA_fnc_removeKeyHandler Description: - Removes an action to a keyhandler + Removes an action from a keybind. Parameters: - _hashKey - handler identifier [String]. - _type - "keydown" (default) = keyDown, "keyup" = keyUp [String]. - + _hashKey - Key handler identifier. + _type - "keydown" or "keyup". [optional] (default: "keydown") Returns: + None Examples: (begin example) - ["cba_somesystem_keyevent"] call CBA_fnc_removeKeyHandler; + _id call CBA_fnc_removeKeyHandler; ["cba_anothersystem_keyup", "keyup"] call CBA_fnc_removeKeyHandler; (end) Author: - Sickboy - + Sickboy, commy2 ---------------------------------------------------------------------------- */ -// #define DEBUG_MODE_FULL #include "script_component.hpp" SCRIPT(removeKeyHandler); -params ["_hashKey", ["_type","keydown"]]; -private ["_keyData", "_handlers", "_idx", "_myHandlers"]; + +if (!hasInterface) exitWith {}; + +params [ + ["_hashKey", "", [""]], + ["_type", "keydown", [""]] +]; + _type = toLower _type; -if (_type in KEYS_ARRAY_WRONG) then { _type = ("key" + _type) }; -if !(_type in KEYS_ARRAY) exitWith { ERROR("Type does not exist") }; + +// add "key" prefix to "down" and "up" +if (_type in ["down", "up"]) then { + _type = "key" + _type; +}; + +// check if type is either "keydown" or "keyup" +if !(_type in ["keydown", "keyup"]) exitWith { + ERROR("Type does not exist"); +}; + _hashKey = toLower _hashKey; -_keyData = [if (_type == "keydown") then { GVAR(keyhandlers_down) } else { GVAR(keyhandlers_up) }, _hashKey] call CBA_fnc_hashGet; - -_handlers = [GVAR(keyhandler_hash), _type] call CBA_fnc_hashGet; - -// Remove existing key. -_idx = _keyData select 0; -if (count _handlers > _idx) then { - _myHandlers = _handlers select _idx; - if (_hashKey in _myHandlers) then { - _myHandlers = _myHandlers - [_hashKey]; - _handlers set [_idx, _myHandlers]; - }; + +// remove default keyup handler from keydown +if (_type == "keydown") then { + [_hashKey + "_cbadefaultuphandler", "keyup"] call CBA_fnc_removeKeyHandler; }; -if(_type == "keydown") then { - [_hashKey+"_CBADEFAULTUPHANDLER", "keyup"] call cba_fnc_removeKeyHandler; + +private _hash = [GVAR(keyHandlersDown), GVAR(keyHandlersUp)] select (_type == "keyup"); +private _key = (_hash getVariable _hashKey) select 0; + +private _keyHandlers = [GVAR(keyDownStates), GVAR(keyUpStates)] select (_type == "keyup"); + +if (count _keyHandlers > _key) then { + private _hashKeys = _keyHandlers select _key; + _hashKeys = _hashKeys - [_hashKey]; + _keyHandlers set [_key, _hashKeys]; }; -true; +nil diff --git a/addons/events/fnc_removeLocalEventHandler.sqf b/addons/events/fnc_removeLocalEventHandler.sqf deleted file mode 100644 index 51a22178a..000000000 --- a/addons/events/fnc_removeLocalEventHandler.sqf +++ /dev/null @@ -1,49 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: CBA_fnc_removeLocalEventHandler - -Description: - Removes an event handler previously registered with CBA_fnc_addLocalEventHandler. - -Parameters: - _eventType - Type of event to remove [String]. - _handlerIndex - Index of the event handler to remove [Number]. - -Returns: - nil - -TODO: - Use Hash to store handlers as a sparse array, to save on lots of empty - elements in the array if lots of removes are made. - -Author: - Xeno ----------------------------------------------------------------------------- */ - -#include "script_component.hpp" - -SCRIPT(removeLocalEventHandler); - -// ----------------------------------------------------------------------------- - -params ["_eventType","_handlerIndex"]; - -private "_handlers"; - -_handlers = CBA_eventHandlersLocal getVariable _eventType; - -if (isNil "_handlers") then { - WARNING("Event type not registered: " + (str _eventType)); -} else { - if (count _handlers > _handlerIndex) then { - if (isNil { _handlers select _handlerIndex } ) then { - WARNING("Handler for event " + (str _eventType) + " index " + (str _handlerIndex) + " already removed."); - } else { - _handlers set [_handlerIndex, nil]; - TRACE_2("Removed",_eventType,_handlerIndex); - }; - } else { - WARNING("Handler for event " + (str _eventType) + " index " + (str _handlerIndex) + " never set."); - }; -}; - -nil; // Return. diff --git a/addons/events/fnc_removeReceiverOnlyEvent.sqf b/addons/events/fnc_removeReceiverOnlyEvent.sqf deleted file mode 100644 index 55d0822f0..000000000 --- a/addons/events/fnc_removeReceiverOnlyEvent.sqf +++ /dev/null @@ -1,20 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: CBA_fnc_removeReceiverOnlyEvent - -Description: - Removes an event handler previously registered with CBA_fnc_addReceiverOnlyEventhandler. - -Parameters: - _eventType - Type of event to remove [String]. - -Returns: - nil - -Author: - Xeno ----------------------------------------------------------------------------- */ - -#include "script_component.hpp" -SCRIPT(removeReceiverOnlyEvent); - -if (!isNil {GVAR(event_holderToR) getVariable _this}) then {GVAR(event_holderToR) setVariable [_this, nil]}; diff --git a/addons/events/fnc_serverEvent.sqf b/addons/events/fnc_serverEvent.sqf new file mode 100644 index 000000000..a7ffbc1d7 --- /dev/null +++ b/addons/events/fnc_serverEvent.sqf @@ -0,0 +1,33 @@ +/* ---------------------------------------------------------------------------- +Function: CBA_fnc_serverEvent + +Description: + Raises a CBA event on the server machine. + +Parameters: + _eventName - Type of event to publish. + _params - Parameters to pass to the event handlers. + +Returns: + None + +Examples: + (begin example) + ["test", ["server"]] call CBA_fnc_serverEvent; + (end) + +Author: + commy2 +---------------------------------------------------------------------------- */ +#include "script_component.hpp" +SCRIPT(serverEvent); + +params [["_eventName", "", [""]], ["_params", []]]; + +if (isServer) then { + CALL_EVENT(_params,_eventName); +} else { + SEND_EVENT_TO_SERVER(_params,_eventName); +}; + +nil diff --git a/addons/events/fnc_targetEvent.sqf b/addons/events/fnc_targetEvent.sqf new file mode 100644 index 000000000..224e795ba --- /dev/null +++ b/addons/events/fnc_targetEvent.sqf @@ -0,0 +1,59 @@ +/* ---------------------------------------------------------------------------- +Function: CBA_fnc_targetEvent + +Description: + Raises a CBA event on all machines where this object or at least one of these objects are local. + +Parameters: + _eventName - Type of event to publish. + _params - Parameters to pass to the event handlers. + _targets - Where to execute events. + +Returns: + None + +Examples: + (begin example) + ["test", ["target"], cursorTarget] call CBA_fnc_targetEvent; + (end) + +Author: + commy2 +---------------------------------------------------------------------------- */ +#include "script_component.hpp" +SCRIPT(targetEvent); + +params [["_eventName", "", [""]], ["_params", []], ["_targets", objNull, [objNull, grpNull, []]]]; + +if !(_targets isEqualType []) then { + _targets = [_targets]; +}; + +private _remoteTargets = _targets select {!local GETOBJ(_x)}; + +// do local events if there is a local target +if (count _targets > count _remoteTargets) then { + CALL_EVENT(_params,_eventName); +}; + +// no networking when no targets are remote +if (_remoteTargets isEqualTo []) exitWith {}; + +if (isServer) then { + private _sentOwners = []; + + { + private _owner = owner GETOBJ(_x); + + // only send event once each time this function is called, even if multipe targets are local to the same machine + if !(_owner in _sentOwners) then { + _sentOwners pushBack _owner; + SEND_EVENT_TO_CLIENT(_params,_eventName,_owner); + }; + } forEach _remoteTargets; +} else { + // only server knows object owners. let server handle the event. + SEND_TEVENT_TO_SERVER(_params,_eventName,_remoteTargets); +}; + +nil diff --git a/addons/events/fnc_whereLocalEvent.sqf b/addons/events/fnc_whereLocalEvent.sqf deleted file mode 100644 index 40e78be67..000000000 --- a/addons/events/fnc_whereLocalEvent.sqf +++ /dev/null @@ -1,54 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: CBA_fnc_whereLocalEvent - -Description: - Raises a CBA event only on the machine where parameter one is local. - -Parameters: - _eventType - Type of event to publish [String]. - _params - Parameters to pass to the event handlers. First param must be the object to check - -Returns: - nil - -Author: - Xeno ----------------------------------------------------------------------------- */ - -#include "script_component.hpp" - -SCRIPT(whereLocalEvent); - -// ---------------------------------------------------------------------------- - -DEFAULT_PARAM(1,_params,nil); - -if (isNil "_params") exitWith { - WARNING("Locality check parameter in CBA_fnc_whereLocalEvent function is missing!"); -}; - -private "_locobj"; -_locobj = if (typeName _params == typeName []) then {_params select 0} else {_params}; - -if (typeName _locobj != "OBJECT") exitWith { - WARNING("Locality check parameter is not an object!"); - nil -}; - -TRACE_1("",_locobj); - -if (isNil "_locobj" || {isNull _locobj}) exitWith { - WARNING("Locality check object is nil or null!"); - nil -}; - -// doing a local check first -if (!local _locobj) exitWith { - CBA_l = _this; - publicVariable "CBA_l"; - nil -}; - -_this call FUNC(remoteLocalEvent); - -nil; // Return. diff --git a/addons/events/script_component.hpp b/addons/events/script_component.hpp index 2c71aa520..75750b189 100644 --- a/addons/events/script_component.hpp +++ b/addons/events/script_component.hpp @@ -1,10 +1,7 @@ #define COMPONENT events #include "\x\cba\addons\main\script_mod.hpp" -#define KEYS_ARRAY_WRONG ['down', 'up'] -#define KEYS_ARRAY ['keydown', 'keyup'] - -// #define DEBUG_ENABLED_EVENTS +//#define DEBUG_ENABLED_EVENTS #ifdef DEBUG_ENABLED_EVENTS #define DEBUG_MODE_FULL @@ -15,3 +12,31 @@ #endif #include "\x\cba\addons\main\script_macros.hpp" + +#define KEYS_ARRAY_WRONG ['down', 'up'] +#define KEYS_ARRAY ['keydown', 'keyup'] + +// event system +#define EVENT_PVAR CBAr +#define EVENT_PVAR_STR QUOTE(EVENT_PVAR) + +#define SYS_SEND_EVENT(params,name,command) EVENT_PVAR = [name, params]; command EVENT_PVAR_STR +#define SEND_EVENT_TO_OTHERS(params,name) SYS_SEND_EVENT(params,name,publicVariable) +#define SEND_EVENT_TO_SERVER(params,name) SYS_SEND_EVENT(params,name,publicVariableServer) +#define SEND_EVENT_TO_CLIENT(params,name,client) SYS_SEND_EVENT(params,name,client publicVariableClient) + +// target events +#define TEVENT_PVAR CBAt +#define TEVENT_PVAR_STR QUOTE(TEVENT_PVAR) + +#define SEND_TEVENT_TO_SERVER(params,name,targets) TEVENT_PVAR = [name, params, targets]; publicVariableServer TEVENT_PVAR_STR + +#define CALL_EVENT(params,event) {\ + if !(isNil "_x") then {\ + params call _x;\ + };\ +} forEach (GVAR(eventNamespace) getVariable event) + +#define GETOBJ(obj) (if (obj isEqualType grpNull) then {leader obj} else {obj}) + +#include "\a3\editor_f\Data\Scripts\dikCodes.h" diff --git a/addons/keybinding/gui/gui.hpp b/addons/keybinding/gui/gui.hpp index c9e155754..e9005f850 100644 --- a/addons/keybinding/gui/gui.hpp +++ b/addons/keybinding/gui/gui.hpp @@ -174,8 +174,3 @@ class RscDisplayConfigure { }; }; }; - -class RscDisplayCurator { - onLoad = "['CBA_curatorOpened', _this] call CBA_fnc_localEvent; [""onLoad"",_this,""RscDisplayCurator"",'CuratorDisplays'] call (uinamespace getvariable 'BIS_fnc_initDisplay')"; - onUnload = "['CBA_curatorClosed', _this] call CBA_fnc_localEvent; [""onUnload"",_this,""RscDisplayCurator"",'CuratorDisplays'] call (uinamespace getvariable 'BIS_fnc_initDisplay')"; -}; diff --git a/addons/xeh/fnc_postInit_unscheduled.sqf b/addons/xeh/fnc_postInit_unscheduled.sqf index d868773f8..e940b8b80 100644 --- a/addons/xeh/fnc_postInit_unscheduled.sqf +++ b/addons/xeh/fnc_postInit_unscheduled.sqf @@ -16,7 +16,7 @@ Author: ---------------------------------------------------------------------------- */ #include "script_component.hpp" -XEH_LOG("XEH: PostInit started."); +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 { diff --git a/addons/xeh/fnc_preInit.sqf b/addons/xeh/fnc_preInit.sqf index 38ca0b552..9f36cec20 100644 --- a/addons/xeh/fnc_preInit.sqf +++ b/addons/xeh/fnc_preInit.sqf @@ -18,7 +18,7 @@ Author: SLX_XEH_DisableLogging = uiNamespace getVariable ["SLX_XEH_DisableLogging", false]; // get from preStart -XEH_LOG("XEH: PreInit started. v" + getText (configFile >> "CfgPatches" >> "cba_common" >> "version") + ". " + PFORMAT_7("MISSIONINIT",missionName,worldName,isMultiplayer,isServer,isDedicated,hasInterface,didJIP)); +XEH_LOG("XEH: PreInit started. v" + getText (configFile >> "CfgPatches" >> "cba_common" >> "version")); SLX_XEH_STR = ""; // does nothing, never changes, backwards compatibility SLX_XEH_COMPILE = compileFinal "compile preprocessFileLineNumbers _this"; //backwards comps @@ -44,6 +44,8 @@ SLX_XEH_MACHINE = [ // backwards compatibility, deprecated 3 // 15 - Product+Version, always Arma 3 ]; +CBA_isHeadlessClient = !hasInterface && !isDedicated; + // make case insensitive list of all supported events GVAR(EventsLowercase) = []; {