BIS fnc addStackedEventHandler – Talk

From Bohemia Interactive Community
Jump to navigation Jump to search

Not being able to override default engine behavior was really bumming me out, so I took a look at BIS_fnc_executeStackedEventHandler. By adding 2 variables, I was able to make the function perform as intended (as I see it). Please push this fix to the next hotfix, BIS!

/* Author: Nelson Duarte Edit by: Dread (in bold) Description: This function executes the stacked items, should not be called independently Parameter(s): _this select 0: STRING - The onXxx event handler Returns: BOOL - True if executed code returns true False if executed code returns anything else */ //Parameters private ["_event"]; _event = [_this, 0, "", [""]] call BIS_fnc_param; //Mission namespace id private "_namespaceId"; _namespaceId = "BIS_stackedEventHandlers_"; //Mission namespace event private "_namespaceEvent"; _namespaceEvent = _namespaceId + _event; //The data private "_data"; _data = missionNameSpace getVariable [_namespaceEvent, []]; //Add 2 new variables and define private ["_return","_trash"]; _return = false; _trash = false; //Process data { //Data item parameters private ["_code", "_arguments"]; _code = [_x, 2, "", [{}, ""]] call BIS_fnc_param; _arguments = [_x, 3, []] call BIS_fnc_param; if (typeName _code != typeName "") then { //Execute code _trash = _arguments call _code; //call can return, why waste? } else { //Execute function _trash = _arguments call (call compile _code); //not really sure what's happening here. 2 calls? }; if (typeName _trash == "BOOL") then { if (_trash) then { _return = true; }; }; } forEach _data; //Return _return; Can't get this post formatted correctly. I'm just going to leave it like it is. - DreadedEntity

According to this post http://forums.bistudio.com/showthread.php?167822-Stacked-event-handlers-OnEachFrame-OnPlayerConnected-etc the intention of these functions is for community/official content compatibility, thus the need for consistent functionality - I don't think you'll see them change this (although its easy enough for you to implement yourself for a specific need).
Infact, further down that page is an example of how returning true can break functionality; KK's reply points out that executeStackedEventHandlers used to return true by default, which broke onMapSingleClick for players.--Strangepete (talk) 11:18, 9 December 2014 (CET)
"In addition, your code will only return the bool of the last iterated _data." This is incorrect. My edit functions as intended. I think you mixed up _trash and _return. _trash is redefined on every iteration. _return can only be redefined if _trash = true, and it can only be redefined to true. It's basically a one-way road. Then the function ends with _return, which is false by default.
Although, returning true in any of your SEH's will force the entire statement to return true. Which most likely will cause problems with compatibility. I knew, but I hadn't really considered quite what that meant, you're right, this edit will probably never been seen anywhere other than this page. But what else are we supposed to do? I read that the community has been fighting for SEH's for years. I consider this BIS's failure to add a real way to stack EH's, although Duarte's functions are quite clever in my opinion. Don't consider my edit to be acceptance, I'm still unhappy with how any true returns will override all default behavior for that particular event, but with the current system, it is completely impossible to get it any better. I'm still thinking though...maybe I'll have a breakthrough. - DreadedEntity
You are right, my mistake - sleepy eyes. "But what are we supposed to do" - Write one from the ground-up that works like you expect; luckily all the commands necessary are public, so it is possible. But what you have here would work if all parties using it knew the other party will/could be overridding default behavior (this could be perfectly acceptable for certain situations). What else do you expect the SEH to do that it doesn't (other than overriding default)
Another thought, you could have the return value always a global variable instead, BIS_overrideSEH = false for example. I see this as doing 2 things - allows scripts to check if default engine behavior will be overridden or not (compatibility), and would allow for changing the behavior on the fly during a mission (sometimes you want the default behavior, sometimes maybe not?) --Strangepete (talk) 11:18, 9 December 2014 (CET)