1. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  2. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still havn't received your rank award? Then please contact the administration.
    Dismiss Notice
  3. The Lich King demands your service! We've reached the 19th edition of the Icon Contest. Come along and make some chilling servants for the one true king.
    Dismiss Notice
  4. The 4th SFX Contest has started. Be sure to participate and have a fun factor in it.
    Dismiss Notice
  5. The poll for the 21st Terraining Contest is LIVE. Be sure to check out the entries and vote for one.
    Dismiss Notice
  6. The results are out! Check them out.
    Dismiss Notice
  7. Don’t forget to sign up for the Hive Cup. There’s a 555 EUR prize pool. Sign up now!
    Dismiss Notice
  8. The Hive Workshop Cup contest results have been announced! See the maps that'll be featured in the Hive Workshop Cup tournament!
    Dismiss Notice
  9. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

[Snippet] RegisterEvent pack

Discussion in 'JASS Resources' started by Bannar, Apr 4, 2014.

  1. edo494

    edo494

    Joined:
    Apr 16, 2012
    Messages:
    3,846
    Resources:
    5
    Spells:
    1
    JASS:
    4
    Resources:
    5
    interesting, didnt know that(very apparently from my post :D)

    I am for approval of this, and maybe even potential deprecation/graveyarding of RPUE, since this achieves the same thing and more, and the script is right there ready to be copy-pasted(yes I do understand that RPUE is widely used, but this is superior version of event registration in my opinion)
     
  2. Bannar

    Bannar

    Joined:
    Mar 19, 2008
    Messages:
    3,087
    Resources:
    20
    Spells:
    5
    Tutorials:
    1
    JASS:
    14
    Resources:
    20
    Due to fact that I've been working with Table very closely (when writing List<T>/ Vector<T>) I knew about allocating method for TableArray. Still, allocating unnecessarily big array just doesn't apeal to me - guess due to how I'm used to handle containers in c++.

    Global on top of RPUE enables user to control its API syntax, but honestly, ctrl+R isn't that hard and sticking to Blizzard native syntax seems like the right thing to do - it's very intuitive, especially for new users.
     
  3. IcemanBo

    IcemanBo

    Joined:
    Sep 6, 2013
    Messages:
    6,166
    Resources:
    22
    Maps:
    3
    Spells:
    11
    Template:
    1
    Tutorials:
    4
    JASS:
    3
    Resources:
    22
    This actually.

    Edit:

    It's quite a step but I would make this the new standard resource for event registrations.
    It would be still okay that people use(d) others, as they work, but this is superior and more generic.

    I would approve this soon and deprecate Maggy's snippet if noone jumps in.
     
    Last edited: Oct 16, 2016
  4. IcemanBo

    IcemanBo

    Joined:
    Sep 6, 2013
    Messages:
    6,166
    Resources:
    22
    Maps:
    3
    Spells:
    11
    Template:
    1
    Tutorials:
    4
    JASS:
    3
    Resources:
    22
    Submission: RegisterNativeEvent v1.0.0.0
    Date: 18 October 16
    Status: Approved
    Note:

    A nice and generic snipptet for event registration. It's better to have everything similar bundled than splitting same concept for different events seperatly. Good job, approved.
     
  5. Aniki

    Aniki

    Joined:
    Nov 7, 2014
    Messages:
    522
    Resources:
    4
    Spells:
    1
    JASS:
    3
    Resources:
    4
    Am I mistaken or this can be (arguably) more concisely written as:
    Code (vJASS):

    library SingleTriggerPerEvent

    globals
        private trigger array trgs
    endglobals

    function GetEventTrigger takes eventid ee returns trigger
        return trgs[GetHandleId(ee)]
    endfunction

    function RegisterAnyPlayerEvent takes playerevent ee, code f returns nothing
        local integer e = GetHandleId(ee)
        local integer p

        if trgs[e] == null then
            set trgs[e] = CreateTrigger()

            set p = 0
            loop
                exitwhen p > 15 // could use PlayerArray.PlayingPlayers
                call TriggerRegisterPlayerEvent(trgs[e], Player(p), ee)
                set p = p + 1
            endloop
        endif

        call TriggerAddAction(trgs[e], f)
    endfunction

    function RegisterGameEvent takes gameevent ee, code f returns nothing
        local integer e = GetHandleId(ee)

        if trgs[e] == null then
            set trgs[e] = CreateTrigger()
            call TriggerRegisterGameEvent(trgs[e], ee)
        endif

        call TriggerAddAction(trgs[e], f)
    endfunction

    function RegisterAnyPlayerUnitEvent takes playerunitevent ee, code f returns nothing
        local integer e = GetHandleId(ee)
        local integer p

        if trgs[e] == null then
            set trgs[e] = CreateTrigger()

            set p = 0
            loop
                exitwhen p > 15 // could use PlayerArray.PlayingPlayers
                call TriggerRegisterPlayerUnitEvent(trgs[e], Player(p), ee, null)
                set p = p + 1
            endloop
        endif

        call TriggerAddAction(trgs[e], f)
    endfunction


    globals
        private hashtable ht = InitHashtable()
    endglobals

    function RegisterPlayerEvent takes player pp, playerevent ee, code f returns nothing
        local integer e = GetHandleId(ee)
        local integer p = GetPlayerId(pp)
        local trigger t

        set t = LoadTriggerHandle(ht, e, p)
        if t == null then
            set t = CreateTrigger()
            call SaveTriggerHandle(ht, e, p, t)
            call TriggerRegisterPlayerEvent(t, pp, ee)
        endif

        call TriggerAddAction(t, f)
        set t = null
    endfunction
    function GetPlayerEventTrigger takes player pp, playerevent ee returns trigger
        return LoadTriggerHandle(ht, GetHandleId(ee), GetPlayerId(pp))
    endfunction

    function RegisterUnitEvent takes unit uu, unitevent ee, code f returns nothing
        local integer e = GetHandleId(ee)
        local integer u = GetHandleId(uu)
        local trigger t

        set t = LoadTriggerHandle(ht, e, u)
        if t == null then
            set t = CreateTrigger()
            call SaveTriggerHandle(ht, e, u, t)
            call TriggerRegisterUnitEvent(t, uu, ee)
        endif

        call TriggerAddAction(t, f)
        set t = null
    endfunction
    function GetUnitEventTrigger takes unit uu, playerevent ee returns trigger
        return LoadTriggerHandle(ht, GetHandleId(ee), GetHandleId(uu))
    endfunction

    function RegisterPlayerUnitEvent takes player pp, playerunitevent ee, code f returns nothing
        local integer e = GetHandleId(ee)
        local integer p = GetHandleId(pp)
        local trigger t

        set t = LoadTriggerHandle(ht, e, p)
        if t == null then
            set t = CreateTrigger()
            call SaveTriggerHandle(ht, e, p, t)
            call TriggerRegisterPlayerUnitEvent(t, pp, ee, null)
        endif

        call TriggerAddAction(t, f)
        set t = null
    endfunction
    function GetPlayerUnitEventTrigger takes unit uu, playerevent ee returns trigger
        return LoadTriggerHandle(ht, GetHandleId(ee), GetHandleId(uu))
    endfunction

    endlibrary

     
     
    Last edited: Nov 14, 2016
  6. Trokkin

    Trokkin

    Joined:
    Jan 23, 2015
    Messages:
    98
    Resources:
    1
    Tutorials:
    1
    Resources:
    1
    I noticed that Maggy's RPUE has a bit different order of arguments in
    RegisterPlayerUnitEventForPlayer
    than yours. That's bad actually since any system written with Maggy's RPUE would not be able to exist in one map with another system written using yours RPUE because of that different order without additional help which would also make any fixed system unoriginal.
    I would be annoyed changing systems just to have them in my map because they use different RPUEs both because of dirty work and because that systems are no more original and the action would be repeated on next system's update.
    I think else should force everyone using Maggy's to update to yours RPUE, else you should update your RPUE to Maggy's format and then force to update everyone using yours old one.
     
    Last edited: Feb 11, 2017
  7. IcemanBo

    IcemanBo

    Joined:
    Sep 6, 2013
    Messages:
    6,166
    Resources:
    22
    Maps:
    3
    Spells:
    11
    Template:
    1
    Tutorials:
    4
    JASS:
    3
    Resources:
    22
    if constant boolean RPUE_VERSION_NEW = false, then you should be able to use Mag's API style.
     
  8. Trokkin

    Trokkin

    Joined:
    Jan 23, 2015
    Messages:
    98
    Resources:
    1
    Tutorials:
    1
    Resources:
    1
    Arguments order, please
    function RegisterPlayerUnitEvent$SPECIFIC$ takes player whichPlayer, playerunitevent whichEvent, code cb returns nothing
    - that's Bannar's code
    function RegisterPlayerUnitEventForPlayer takes playerunitevent p, code c, player pl returns nothing
    - that's Maggy's code
    As you can see, order (player, event, code) isn't (event, code, player)
    That's what I'm talking about and this almost as bad as different function name is. It breaks usage of new snippet where Maggy's snippet is supposed to be.
     
  9. IcemanBo

    IcemanBo

    Joined:
    Sep 6, 2013
    Messages:
    6,166
    Resources:
    22
    Maps:
    3
    Spells:
    11
    Template:
    1
    Tutorials:
    4
    JASS:
    3
    Resources:
    22
    True, the wrong argument order is probably not intended. @Bannar , could you fix it?
     
  10. Strikest

    Strikest

    Joined:
    Aug 27, 2012
    Messages:
    332
    Resources:
    1
    Maps:
    1
    Resources:
    1
    Hey, I was able to get this working, but I am confused about this warning:

    What does this mean? Is there some kind of leak I have to get rid of?

    Also, is there a way to "deregister" an object in the callback? In case I only want the trigger to fire once per object.
     
    Last edited: Mar 17, 2017
  11. AGD

    AGD

    Joined:
    Mar 29, 2016
    Messages:
    397
    Resources:
    13
    Spells:
    7
    Tutorials:
    1
    JASS:
    5
    Resources:
    13
    Ok, I just realized there is a terrible bug with the RegisterPlayerUnitEvent and RegisterPlayerEvent. A single trigger for both 'certain' playerunit event and 'any' playerunit event won't work as intended because for example:
    Code (vJASS):

    call RegisterPlayerUnitEventForPlayer(Player(0), function Func, EVENT_PLAYER_UNIT_SELECTED)
    call RegisterPlayerUnitEventForPlayer(Player(1), function Func, EVENT_PLAYER_UNIT_SELECTED)
    call RegisterPlayerUnitEventForPlayer(Player(2), function Func, EVENT_PLAYER_UNIT_SELECTED)
     

    1 trigger is shared for Players 1, 2, & 3 therefore, whenever a unit is selected from either of the three players, the trigger will run for all of them.
    The same goes for specific playerevents. So we still need 1 trigger for each player for the specific player events and 1 shared trigger for the generic player event.
     
  12. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,048
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    That's true. For some reason he adds all the player specific triggers onto one.
     
  13. Bannar

    Bannar

    Joined:
    Mar 19, 2008
    Messages:
    3,087
    Resources:
    20
    Spells:
    5
    Tutorials:
    1
    JASS:
    14
    Resources:
    20
    Updated:

    RegisterNativeEvent to 1.0.1.0:

    - Now offers new GetPlayerIdNativeEventTrigger function.
    - Fixed bug when creating/attaching trigger to event for specific player id.

    RegisterPlayerEvent to 1.0.1.0:
    - Now offers new GetPlayerEventTriggerForPlayer function.
    - Fixed bug when creating/attaching trigger to event for specific player id.
    - Improved loop behavior for generic register method, now always registers for ANY-player id (16).

    RegisterGameEvent to 1.0.0.2:
    - Now always registers for ANY-player id (16) rather than 0.

    RegisterPlayerUnitEvent to 1.0.2.0:
    - Now offers new GetPlayerUnitEventTriggerForPlayer function.
    - Fixed bug when creating/attaching trigger to event for specific player id.
    - Improved loop behavior for generic register method, now always registers for ANY-player id (16).
    - Fixed macro usage i.e. compatibility with old RPUE. Trigger retrieval functions no longer located within macro.

    Thank you for spotting this out. Addressed in RegisterPlayerUnitEvent 1.0.2.0.

    Four-five years ago I had spoken with Maggy about the naming convention, and he agreed that different one should be chosen. However, he realized that late thus that was no longer possible without breaking the compatibility (meaby that should be done anyway, that many years ago?).
    This is why from the start, script is provided with global for users to choose their preference.

    User has access to any trigger registered via this system, thus theoretically one could call DestroyTrigger function on trigger retrieved. Note is here to warn anyone doing so.

    There is no method for deregistering an already registered event, sorry.

    Thank you for spotting this out. Addressed in RegisterPlayerUnitEvent 1.0.2.0, RegisterPlayerEvent 1.0.1.0 and RegisterNativeEvent 1.0.1.0.
     
  14. Bannar

    Bannar

    Joined:
    Mar 19, 2008
    Messages:
    3,087
    Resources:
    20
    Spells:
    5
    Tutorials:
    1
    JASS:
    14
    Resources:
    20
    Patch 1.29 update, now accounts for new 24 player limit.
     
  15. Bannar

    Bannar

    Joined:
    Mar 19, 2008
    Messages:
    3,087
    Resources:
    20
    Spells:
    5
    Tutorials:
    1
    JASS:
    14
    Resources:
    20
    Updated - mainly RegisterNativeEvent, to 1.1.0.0.
    Simplified main library, removed unnecessary private methods, removed global trigger array. Now fully Table/hashtable dependent. TableArray now of size 0x2000 to allow for custom event registration.

    GetPlayerIdNativeEventTrigger renamed to GetIndexNativeEventTrigger. The former was very young (few days) and did not match the spirit of the function.
    New convenience method:
    function CreateNativeEvent takes nothing returns integer

    Purpose: prevent custom (declared within imported library) event-id ambiguity. In most cases, those start at 0, thus having array/table EVENT-id dependent is impossible. Since this is a RegisterEvent pack, having such convenient function is reasonable. Read last line for more info.

    The explicit "any player" index typing has been replaced by
    bj_MAX_PLAYER_SLOTS
    , to be Warcraft-patch resistant. The bj_ equals 28 for current patch and 16 for pre-1.29. In other words, it's
    PLAYER_NEUTRAL_PASSIVE + 1
    which has been commonly used explicitly in the past as "any-player" index.

    Updated reference event-ids in OP to match state official 1.29 list. Three new player events available, and several more has had their id changed (all events which used to start from index 268).
    Code (vJASS):

        constant playerevent        EVENT_PLAYER_MOUSE_DOWN                 = ConvertPlayerEvent(269)
        constant playerevent        EVENT_PLAYER_MOUSE_UP                   = ConvertPlayerEvent(270)
        constant playerevent        EVENT_PLAYER_MOUSE_MOVE                 = ConvertPlayerEvent(271)
     

    Verified for pre-1.29 and 1.29 itself.
    Verified to be Wurst-friendly. TriggerRegisterVariableEvent is unacceptable by wurst, thus custom event should be interpreted by id-trigger pair, and calling such must be done by
    TriggerEvaluate
    rather than real variable setting.
     
    Last edited: Apr 15, 2018
  16. Bannar

    Bannar

    Joined:
    Mar 19, 2008
    Messages:
    3,087
    Resources:
    20
    Spells:
    5
    Tutorials:
    1
    JASS:
    14
    Resources:
    20
    The time has come to shatter this clockwork universe forever!
    Let us no longer be slaves of the hourglass!
    I warn you: those who do not embrace the greater path shall become victims of its passing!

    -Aoenus

    After over four years of deprecation, the streamlining of function naming finally commences. Both, RegisterPlayerUnitEvent and RegisterPlayerEvent now match Blizzard alike function naming convention.
    Reference to old, obsolete snippets can still be found at the bottom of OP but will be removed in the future.
    With the increased activity on Warcraft3 forums and chat servers due to visible interest from Blizzard side, I decided that this is the right time to finally make word flesh.

    RegisterNativeEvent:
    - CreateNativeEvent function now immediately registers ANY-PLAYER trigger by default before returning to caller
    - Added RegisterNativeEvent and RegisterIndexNativeEvent which have the exact same purpose as RegisterPlayerUnitEvent and the rest, but are targeted for user-defined events

    RegisterPlayerUnitEvent:

    - Removed constant boolean RPUE_VERSION_NEW
    - Removed textmacro DEFINE_REGISTER_PLAYER_UNIT_EVENT
    - Register function names streamlined to RegisterAnyPlayerUnitEvent and RegisterPlayerUnitEvent. The same pattern has been used for trigger retrieval functions
    - Appended missing credits

    RegisterPlayerEvent:

    - Register function names streamlined to RegisterAnyPlayerEvent and RegisterPlayerEvent. The same pattern has been used for trigger retrieval functions

    RegisterUnitEvent:
    - RegisterUnitEvent function now properly assigns separate trigger for each unit handle, rather than registering event for event-generic trigger

    General:
    - All snippets have been adjusted to reflect API changes made to RegisterNativeEvent
    - Updated documentation
     
    Last edited: May 8, 2018
  17. AGD

    AGD

    Joined:
    Mar 29, 2016
    Messages:
    397
    Resources:
    13
    Spells:
    7
    Tutorials:
    1
    JASS:
    5
    Resources:
    13
    Any chance that this would support unregistering code handlers from an event in the future? It would be nice.
     
  18. Bannar

    Bannar

    Joined:
    Mar 19, 2008
    Messages:
    3,087
    Resources:
    20
    Spells:
    5
    Tutorials:
    1
    JASS:
    14
    Resources:
    20
    Even if so, I'd probably add it as extension snippet rather than append new code to existing one.
    RegisterNativeEvent is supposed to provide one simple functionality without any real overhead in form of blizzard-like streamlined api. Anything that comes after is what I call the noise.

    Idk if it's even worth it, core-arrays are on the horizon : )
     
  19. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,048
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Did they say anything about that, or any other JASS functionality they want to incorporate?
     
  20. AGD

    AGD

    Joined:
    Mar 29, 2016
    Messages:
    397
    Resources:
    13
    Spells:
    7
    Tutorials:
    1
    JASS:
    5
    Resources:
    13
    Makes sense. I guess I should just ask you to return the triggerconditions from the registering functions instead.

    EDIT:
    And a simple
    UnregisterNativeEventHandler(integer whichEvent, triggercondition handler)
    in conjunction would also be favorable.
     
    Last edited: Jul 17, 2018