SotA Event System Addon

Discussion in 'Player Created Lua Script Repository' started by Tirrag, Jun 9, 2022.

  1. Tirrag

    Tirrag Avatar

    Messages:
    854
    Likes Received:
    1,824
    Trophy Points:
    93
    Location:
    Iowa, USA
    Greetings and welcome to the SotA Event System (SES) addon! In my rewrite of the BMS addon, I converted it to separate the events engine from the UI and in doing so I needed a couple of things... An events system that could handle custom events and also a way to hook the code in the modules I was creating to some base SotA ShroudOn events. I had first written something specific to BMS but realized this is actually a pretty cool thing so decided to make it into its own utility addon. So really, what does it do? It exposes a way for you to send and receive Shroud or custom events across addons and inside your code (whether it be a module or right in a root lua file). NOTE: this is loosely based on the events system from libsota so a big thank you to @CatweazleX.

    API

    The addon has the following functions:

    SES.on(eventName, callback) - allows you to start listening for an event, calling the callback any time it is invoked. returns a callback index.

    SES.off(eventName, callbackIndex) - stops the callback from listening to the event. if you do not pass a callbackIndex then all callbacks for the event will be stopped.

    SES.invoke(eventName, ...) - allows your code to invoke an event which sends the dynamic parameter list to the registered callbacks.

    SES.mute(eventName) - disables notifications to the listening callbacks for an event

    SES.unmute(eventName) - enables notifications to the listening callbacks for an event

    SES.enabled(isEnabled) - enables or disables the event system

    SES.utility.loadmodule(modulename) - based on the libsota loadmodule function, allows you to load a lua script as a module.

    SES.utility.deepcopy(original) - performs a deepcopy on a lua table.

    Built-in Events

    The addon has the following built-in events. Note some of the events have ObjectID and possible ObjectKind. These are convenience events so you can directly listen to Shroud events for a specific UI object. Use tostring() to convert the ObjectID and ObjectKind to the values needed for the event name.

    ShroudOnStart
    ShroudOnUpdate
    ShroudOnGUI
    ShroudOnConsoleInput
    ShroudOnMouseClickObjectIDObjectKind
    ShroudOnMouseClick
    ShroudOnMouseOverObjectIDObjectKind
    ShroudOnMouseOver
    ShroudOnMouseOutObjectIDObjectKind
    ShroudOnMouseOut
    ShroudOnSceneLoaded
    ShroudOnSceneUnloaded
    ShroudOnLogout
    ShroudOnInputChangeObjectID
    ShroudOnInputChange
    ShroudOnToggleChangeObjectID
    ShroudOnToggleChange
    ShroudOnPlayFX
    ShroudOnPlaySound
    ShroudOnExperienceGain
    ShroudOnDisableScript (just notifies if SES has been disabled)
    ShroudOnStopSound (custom event notifying when a sound has stopped playing. passes soundName and soundChannel)
    ShroudOnSoundLoaded (custom event notifying when a sound is done loading. passes soundID and soundName as parameters)
    ShroudOnSceneChange (custom event notifying when the scene changes. passes sceneName and rawSceneName as parameters)
    ShroudOnUIActiveChange (custom event notifying when the UI active status changes. passes isActive as a parameter)

    Getting Started

    To get started you will need to download the SES addon at:

    https://shroudoftheavatar.tools/lua/sota_event_system_v1_05.zip

    Please extract the file from the zip download into your Lua SotA folder. If prompted to overwrite say Yes as all updates to this addon will be backwards compatible. When installed properly you should see a file called:

    sota_event_system.lua

    in your root Lua folder. If you cannot find your lua folder, while in-game in the local chat type:

    /datafolder

    This will open up a dialog showing your SotA data folder of which one subdirectory will be the Lua folder.

    If you extracted the files into your Lua folder while in-game they will not be active yet until you either restart the game or in the local chat type:

    /lua reload

    Upon reload, you should see messages in the lua chatbox (be sure lua is checked for that tab) indicating that the addon is active.

    [​IMG]

    If you did not see those messages, then you will need to enable it through the new lua addon menu option within SotA. In the upper-right of the SotA interface click the Window selector icon and select the LUA Add-On(s) Manager option.

    [​IMG]

    In the Lua Add-Ons Manager dialog, find SotA Event System (SES) and click the "Off" button.

    [​IMG]

    The button should change to a green "On" and you should see Lua messages indicating the SES addon is ready and enabled.

    Usage


    To register a callback for an event you will need to call the SES.on function passing the event name you want to listen to and the function that will receive the events. For example, if you want to listen for the ShroudOnStart event you can call:

    Code:
        SES.on("ShroudOnStart", function()
            ConsoleLog("received ShroudOnStart")
        end)
    
    This can be used anywhere in your code, whether its a module or within code in your main lua file.

    Here is an example of using a mouse click convenience event to bind a click function for a panel directly so it only receives the click event when it is clicked (and not any other mouse click events).

    Code:
    local testPanel = nil
    function ShroudOnStart()
     
        testPanel = {
            objectID = ShroudUIPanel(500, 500, 200, 200),
            onClick = function()
                ConsoleLog("panel clicked")
            end
        }
     
        SES.on("ShroudOnMouseClick" .. tostring(testPanel.objectID) .. tostring(UI.Panel), testPanel.onClick)
    end
    
    You can also listen for custom events created by you:

    Code:
        SES.on("MyCustomEvent", function(text)
            ConsoleLog("received MyCustomEvent with text: " .. text)
        end)
    
    To call your custom event you simply need to call the invoke function with any parameters:

    Code:
        SES.invoke("MyCustomEvent", "this is the text to send to the listeners")
    
    For your custom events I would recommend prefixing the event name with something unique to your addon. For example, for my BMS lua addon I prefix all custom events with "BMS." so the registration and invoke would look like:

    Code:
        SES.on("BMS.MyCustomEvent", function(text)
            ConsoleLog("received MyCustomEvent with text: " .. text)
        end)
    
        SES.invoke("BMS.MyCustomEvent", "this is the text to send to the listeners")
    
    This way I can help avoid event name collisions with other lua addons using SES.

    If you have any questions or need any assistance utilizing this addon, please do not hesitate to ask. Constructive suggestions and feedback is always welcome :)
     
    Last edited: Nov 5, 2022
  2. Tirrag

    Tirrag Avatar

    Messages:
    854
    Likes Received:
    1,824
    Trophy Points:
    93
    Location:
    Iowa, USA
    Update List

    2022-11-05 v1.05 - Added missing isStart parameters to ShroudOnPlayFX and ShroudOnPlaySound events.

    2022-08-09 v1.04 - Added ShroudOnSceneChange and ShroudOnUIActiveChange events.

    2022-07-04 v1.03 - Added ShroudOnStopSound event, making use of the new ShroudIsChannelPlaying function. This event allows you to receive the soundName and soundChannel for a sound that was playing via the ShroudPlaySound() function and has stopped playing. Parameters sent by the event are soundName and soundChannel.

    2022-06-10 v1.02 - Added ShroudOnSoundLoaded event. This event allows you to receive the soundID for a sound you loaded via the ShroudLoadSound() function (which does not return the ID since it loads asynchronously). Parameters sent by the event are soundID and soundName.
     
    Last edited: Nov 5, 2022
    FrostII likes this.
  3. Tirrag

    Tirrag Avatar

    Messages:
    854
    Likes Received:
    1,824
    Trophy Points:
    93
    Location:
    Iowa, USA
    just an fyi this addon has been updated. see notes in update list post for details.
     
  4. Duursyrras

    Duursyrras Avatar

    Messages:
    111
    Likes Received:
    76
    Trophy Points:
    18
    i apologize, but i don't get it; could someone provide an example of what this does/allows? :confused::)
     
  5. Tirrag

    Tirrag Avatar

    Messages:
    854
    Likes Received:
    1,824
    Trophy Points:
    93
    Location:
    Iowa, USA
    greetings Duursyrras! no apologies needed i will do my best to explain :)

    At its core this module is simply an event system and is meant to help you implement the observer pattern and loose coupling in your coding. The event system allows for code to watch for an event and then do something if that event occurs. I utilized loose coupling with the rewrite of the buff monitor system (BMS) keeping the UI completely separate from the core of the monitor system. The core simply sends events not caring who is listening for them. The UI is listening for events not caring who is sending them. Neither the core nor the UI know anything about each other. Because they are loosely coupled, someone else who may not like the UI I created can create their own by simply listening to the same events my UI listens to. They could also leverage the core in their own addons by listening for those events and do whatever they want when the events occur. Any one event can have multiple listeners which can all do something different when the event is received.

    The other piece of this addon involves the built-in Shroud events. These events are available only from the main lua file placed in the root SotA lua directory. I utilize modules a lot, trying to keep the main lua file as small as possible. Inside of module code though, you cannot use the Shroud events. I needed a way to pass those events to my module code. While implementing that I have added some convenience events on top of what Shroud events are provided. These convenience events include:

    An event to notify when a sound is actually loaded. Sounds are loaded asynchronously so it is possible to try to use a sound that has not fully loaded yet. By listening for this event you will know when your sound is loaded and ready to be played.

    An event to let you know when a sound has stopped playing.

    Events that are more specific helping to avoid if statements inside of just one big event handler. For example, the ShroudOnMouseClick event will give you ObjectID and ObjectKind as parameters. You can easily use if statements to perform an action specific to the UI element that was clicked and that works just fine. SES though has an event that a specific control can listen for its specific event. Eliminating the need for any if statements.

    Another big advantage is cross-addon communication. Any other addon can listen for the events generated by your code allowing you to build useful data to provide to other addon developers.

    Hopefully this helps and I am the right track to answering your question :) If you need more detail or examples please let me know.
     
    Winfield and Anpu like this.
  6. Tirrag

    Tirrag Avatar

    Messages:
    854
    Likes Received:
    1,824
    Trophy Points:
    93
    Location:
    Iowa, USA
    Last edited: Aug 9, 2022
    FrostII and that_shawn_guy like this.
  7. FrostII

    FrostII Bug Hunter

    Messages:
    5,890
    Likes Received:
    11,039
    Trophy Points:
    153
    Gender:
    Male
    Location:
    Pacific Northwest
    Ok, I'm confused (not that unusual)......
    The "update list post" shows "
    2022-07-04 v1.04 - Added ShroudOnSceneChange and ShroudOnUIActiveChange events."
    07/04 is the date, not today ??
     
    Tirrag likes this.
  8. Tirrag

    Tirrag Avatar

    Messages:
    854
    Likes Received:
    1,824
    Trophy Points:
    93
    Location:
    Iowa, USA
    copy/paste bug :) thanks for the heads up!
     
    FrostII likes this.
  9. Tirrag

    Tirrag Avatar

    Messages:
    854
    Likes Received:
    1,824
    Trophy Points:
    93
    Location:
    Iowa, USA