Home   Help Search Login Register  

Author Topic: HeritableEventHandlers  (Read 3101 times)

0 Members and 1 Guest are viewing this topic.

Offline Denisko-Redisko

  • Members
  • *
HeritableEventHandlers
« on: 17 Dec 2009, 21:38:23 »
I want to submit to testing addon implements inheritable Events Handlers.
Features:
  • + An easy and concise syntax. Very similar to the syntax of BIS.
  • + Fast, native call handlers (used addEventHandler).
  • + Addon doesn't use global variables, doesn't write the variables in the units.
  • + Very small code in the addon.
  • - Command removeAllEventHandlers can remove the all the handlers.
  • - Not tested on the network.

Example using HeritableEventHandlers:
Code: [Select]
class CfgVehicles {
    class USMC_Soldier;
    class HEH_Unit_1 : USMC_Soldier {
        displayName = "-- HEH_Unit_1";
        class HeritableEventHandlers {
            class HEH_Unit_1 {
                init = "diag_log ['init', typeof (_this select 0), 'HEH_Unit_1']";
                fired = "diag_log ['fired', typeof (_this select 0), 'HEH_Unit_1']";
            };
        };
        class HeritableEventHandlersFiles {
            class HEH_Unit_1 {
                init = "\HEH_test\HEH_Unit_1_init.sqf";
                fired = "\HEH_test\HEH_Unit_1_fired.sqf";
            };
        };
    };
    class HEH_Unit_2 : HEH_Unit_1 {
        displayName = "-- HEH_Unit_2";
    };
    class HEH_Unit_3 : HEH_Unit_2 {
        displayName = "-- HEH_Unit_3";
    };
    class HEH_Unit_4 : HEH_Unit_3 {
        displayName = "-- HEH_Unit_4";
        class HeritableEventHandlers {
            class HEH_Unit_4 {
                init = "diag_log ['init', typeof (_this select 0), 'HEH_Unit_4']";
                fired = "diag_log ['fired', typeof (_this select 0), 'HEH_Unit_4']";
            };
        };
    };
};
How it works:
Code: [Select]
class CfgVehicles {
    access = ReadAndCreate;
    class All;
    class AllVehicles: All {
        class EventHandlers {
            init = "_this call compile preprocessFile '\HeritableEventHandlers\init.sqf'";
        };
    };
};
Code: [Select]
// \HeritableEventHandlers\init.sqf
{ call _x } foreach (call {
    _unit = _this select 0;
    _ehList = [];
    _ehInitList = [];
    _confVehicle = configFile >> "CfgVehicles" >> typeof _unit;

    _readEH = {
        if( isClass _confEHGroup ) then {
            for "_i" from 0 to count _confEHGroup -1 do {
                _confEH = _confEHGroup select _i;
                if( isText _confEH ) then {
                    _ehName = configName _confEH;
                    if( _ehName == "init" ) then {
                        _ehInitList = [(getText _confEH) call _compile] + _ehInitList;
                    } else {
                        _ehList = [[_ehName, (getText _confEH) call _compile]] + _ehList;
                    };
                };
            };
        };
    };

    while { isClass _confVehicle } do {

        _configName = configName _confVehicle;

        _confEHGroup = _confVehicle >> "HeritableEventHandlers" >> _configName;
        _compile = { compile _this };
        call _readEH;

        _confEHGroup = _confVehicle >> "HeritableEventHandlersFiles" >> _configName;
        _compile = { compile preprocessFileLineNumbers _this };
        call _readEH;

        _confVehicle = inheritsFrom _confVehicle;
    };

    {
        _unit addEventHandler [_x select 0, _x select 1];
    } foreach _ehList;

    _ehInitList;
});
« Last Edit: 17 Dec 2009, 21:46:28 by Denisko-Redisko »
sorry for my english

Offline i0n0s

  • Moderator
  • *****
Re: HeritableEventHandlers
« Reply #1 on: 17 Dec 2009, 23:41:17 »
What's the difference between this addon and the extended eventhandlers?

Offline Denisko-Redisko

  • Members
  • *
Re: HeritableEventHandlers
« Reply #2 on: 18 Dec 2009, 01:10:49 »
Quote
An easy and concise syntax. Very similar to the syntax of BIS.
* XEH has a syntax that is different from the syntax of BIS.
Quote
Fast, native call handlers (used addEventHandler).
* XEH performs extra code every time the event is fired.
Quote
Addon doesn't use global variables, doesn't write the variables in the units.
* XEH uses global variables, and wrote in my units its data :)
Quote
Very small code in the addon.
* XEH consists of more than one function. XEH not only solves the stated problem.
Quote
Command removeAllEventHandlers can remove the all the handlers.
+ XEH handlers can't be removed by calling removeAllEventHandlers.
Quote
Not tested on the network.
+++ XEH well-known solution, and in fact, the standard solution.
sorry for my english

Offline i0n0s

  • Moderator
  • *****
Re: HeritableEventHandlers
« Reply #3 on: 18 Dec 2009, 01:38:36 »
Thanks for the diff.
But aside of the syntax, I can't find an advantage of it.
The faster is a nice thing, but not that advantage I would switch.
Especially since CBA and HEH are incompatible.
But: You can ask to Sickboy, that they implement the nicer syntax and the new addEventhandler command to make it better.

Offline Denisko-Redisko

  • Members
  • *
Re: HeritableEventHandlers
« Reply #4 on: 18 Dec 2009, 03:58:22 »
Thank i0n0s. This is exactly the case when the well-established solution is better than any other. I well understand that :)
But, if possible, XEH could begin to support similar syntax, and reduce the code by using new commands. To eventually and gradually move to the new format in an evolutionary way. And it would be nice if XEH will be supported something like HeritableEventHandlersFiles.
sorry for my english

Offline Sick

  • Members
  • *
    • Dev-Heaven.net
Re: HeritableEventHandlers
« Reply #5 on: 18 Dec 2009, 10:00:04 »
Hey,

Nice compact clean code.

addEventhandler isn't new, XEH doesn't use it because they can be removed with removeEventHandlers.
Like BIS standard config based events, XEH added events cannot be removed, and therefore is compliant with the standard workflow;
script eventhandlers can be removed, addon eventhandlers not.
Too many missions use removeAllEventhandlers etc :)

  • "Extra code" run at events: the code we run for example in the fired EH, actually improves upon the default, especially incase of multiple stacked fired eventhandlers, simply because the nearestObject is only searched for once.
  • Global Variables; Could you explain the downsides of the few global variables XEH uses ?
  • Writing into variables on your units; Could you explain the downsides?
  • Amount of code; Could you explain the downsides? Realworld difference?
  • Fast Native eventhandlers; XEH events are precompiled code, and are called from the config eh; what benefits have you measured ?

Glad to see others give it a go too, but the design choices were made to stick as close as possible to bi, and still provide advanced options and possibilities.

Anyway, just sharing why XEH's setup the way it is, very low time, nothing bad intended :)
« Last Edit: 18 Dec 2009, 10:24:40 by Sick »

Offline DeanosBeano

  • Addons Depot Staff
  • *****
  • SirDeanosbeano bstowed on me by sui ;)
    • Fraghaus
Re: HeritableEventHandlers
« Reply #6 on: 18 Dec 2009, 16:53:32 »
 Nice one Denisko
 I am working on a small pack of different  Aspects  i will give this a try and give you some feedback .
 Will be in Janurary now tho to be honest .

 
I love ofp

Offline Denisko-Redisko

  • Members
  • *
Re: HeritableEventHandlers
« Reply #7 on: 19 Dec 2009, 01:09:56 »
Thank Sick.
Too many missions use removeAllEventhandlers etc :)
This is indeed a big problem. But in any case, the missionmaker has plenty of possibilities to break the work of game.
Quote
  • "Extra code" run at events: the code we run for example in the fired EH, actually improves upon the default, especially incase of multiple stacked fired eventhandlers, simply because the nearestObject is only searched for once.
Superfluous nearestObject call, on every shot in the game. Also, execution of code on every event in the game. Even for those units that don't have event handlers. This improves performance? This can improve the performance of a specific mod, but not any other addon.
  • Global Variables; Could you explain the downsides of the few global variables XEH uses ?
  • Writing into variables on your units; Could you explain the downsides?
  • Amount of code; Could you explain the downsides? Realworld difference?
Downsides of global variables and amount of code? Theirs quantity and theirs amount :)
These are the questions of the same ilk as "why goto should be avoided". Units and global namespaces are shared resources, and if possible, better not to touch them.
"Realworld difference" -- I haven't conducted tests, but anyway the script takes some time.
Quote
  • Fast Native eventhandlers; XEH events are precompiled code, and are called from the config eh; what benefits have you measured ?
For example:
XEH does follows (for all units in game):
animChanged="_this call((_this select 0)getVariable'Extended_AnimChangedEH')"
HeritableEventHandlers does follows (actually, for those units that have handlers):
addEventHandler ["animChanged", compile getText _confEH];
Quote
Anyway, just sharing why XEH's setup the way it is, very low time, nothing bad intended :)
Perhaps. But XEH-code runs at each event in the game for all units.
I don't want to say that this is bad, but I'm not sure that this is what the user expects.


Quote from: DeanosBeano
i will give this a try and give you some feedback .
Thanks, DeanosBeano :)
« Last Edit: 19 Dec 2009, 01:13:38 by Denisko-Redisko »
sorry for my english

Offline DeanosBeano

  • Addons Depot Staff
  • *****
  • SirDeanosbeano bstowed on me by sui ;)
    • Fraghaus
Re: HeritableEventHandlers
« Reply #8 on: 19 Dec 2009, 17:34:43 »

 No problem mate,

 To speed things up pls could you give me a quick example  in laymans so i may progress.

 For instance i have some CQB units .
DBO_cqbafghan.

 when fired near i would like  lesser skilled low moral units (obviously i define which ones in the config much like your HEH_1 and  _2 etc)   to access this FSM

  at moment it will be

firedNear = "_this execFSM ""dbo\scripts\ScaredHigh.fsm"";";

 

I love ofp

Offline Denisko-Redisko

  • Members
  • *
Re: HeritableEventHandlers
« Reply #9 on: 20 Dec 2009, 03:56:56 »
DeanosBeano, this will help?
Code: [Select]
class CfgVehicles {
    class USMC_Soldier;
    class MyUnit : USMC_Soldier {
        displayName = "-- MyUnit --";
        class HeritableEventHandlersFiles {
            class MyUnit { // This class should be named exactly the same as a your vehicle class
                firedNear = "/addonname/firedNearEH.sqf";
            };
        };
    };
};
Script "/addonname/firedNearEH.sqf"
Code: [Select]
#define __fsmRunned "MY_MOD_PREFIX:MY_MODULE_PREFIX::FSM_COWARD_IS_RUNNING"
_unit = _this select 0;
if (isNil (_unit getVariable __fsmRunned)) then {
    // !!! if "SUPER_AI" mode is active, then all units have the skill == 1
    if (morale _unit < 0 && skill _unit < .5) then {
        _unit setVariable [__fsmRunned, 1];
        _this execFSM "dbo\scripts\ScaredHigh.fsm";
    };
};

Full example of config:
Code: [Select]
class CfgVehicles {
    class USMC_Soldier;
    class HEH_Unit_diag_log : USMC_Soldier {
        displayName = "-- HEH_Unit_diag_log";
        class HeritableEventHandlers {
            class HEH_Unit_diag_log { // This class should be named exactly the same as a your vehicle class
                animChanged = "diag_log ['animChanged', _this select 0]";
                animDone = "diag_log ['animDone', _this select 0]";
                animStateChanged = "diag_log ['animStateChanged', _this select 0]";
                dammaged = "diag_log ['dammaged', _this select 0]";
                engine = "diag_log ['engine', _this select 0]";
                fired = "diag_log ['fired', _this select 0]";
                firedNear = "diag_log ['firedNear', _this select 0]";
                fuel = "diag_log ['fuel', _this select 0]";
                gear = "diag_log ['gear', _this select 0]";
                getIn = "diag_log ['getIn', _this select 0]";
                getOut = "diag_log ['getOut', _this select 0]";
                handleDamage = "diag_log ['handleDamage', _this select 0]";
                handleHeal = "diag_log ['handleHeal', _this select 0]";
                hit = "diag_log ['hit', _this select 0]";
                incomingMissile = "diag_log ['incomingMissile', _this select 0]";
                init = "diag_log ['init', _this select 0]";
                killed = "diag_log ['killed', _this select 0]";
                landedStopped = "diag_log ['landedStopped', _this select 0]";
                landedTouchDown = "diag_log ['landedTouchDown', _this select 0]";
            };
        };
    };
};
sorry for my english