+ Reply to Thread
Page 2 of 4 FirstFirst 1 2 3 4 LastLast
Results 16 to 30 of 57
Like Tree1Likes

  Click here to go to the first Rift Team post in this thread.   Thread: Event API Redesign

  1. #16
    RIFT Community Ambassador the_real_seebs's Avatar
    Join Date
    Jan 2011
    Posts
    16,859

    Default

    Quote Originally Posted by ZorbaTHut View Post
    I'm generally taking the approach that each capital letter is a category, and in situations where splitting up categories into subtables isn't an efficiency problem, I use subtables extensively for categories.
    Fair enough, but I am pretty sure that I have never met anyone in whose cognitive model "leftclick" is "a Left, of the subtype Click".
    You can play WoW in any MMO. You don't have to play WoW in RIFT. Oh, and no, RIFT is not a WoW clone. Not having fun any more? Learn to play, noob! I don't speak for Riftui, but I moderate stuff there. Just came back? Welcome back! Here's what's changed. (Updated for 2.5!)

  2. #17
    Plane Walker Imhothar's Avatar
    Join Date
    Feb 2012
    Posts
    439

    Default

    When I read this yesterday I had the GoF Command Pattern on my mind all the time, which is basically what Zorba's todays suggestion is similar to.

    Let's have each event represented by a table parameter event. Simirarly to how .NET and iOS put all event arguments into a single obejct:
    Code:
    event = {
    	button = "Left",
    	x = 100,
    	y = 200,
    }
    It does not store it's type by intent. This way it is possible for a handler in the first phase to alter the event while it's propagating to its intended target, or even add new information to it if required. The :GetTarget(), :Cancel() and :Halt() methods could be stored in a metatable in order to prevent them being changed, but allowing an event handler to hook or replace them might open doors to interesting event mechanics.

    Whether this is useful for the game logic related event is arguable. Some will probably frown upon event handlers being able to change the event arguments of game related events.

    Now the question remains, whether a frame needs to register methods for the sink/bubble phase or if it gets called automatically by having EventSink(type, event) and EventBubble(type, event) functions. Here the method needs to check the event type manually. Having to register a handler for each event's phase might give a speed increase as the API could create function chains which are simply run in sequence, baring any complex logic or table lookups inbetween, and the handlers (while still getting the type argument) could do without checking the event type. The type argument would always point to one of the global event identifiers (which probably would need to be read-only to prevent addons from replacing them).

    The propagation algorithm itself is fine, though the bubble/sink names change direction depending on how you have the UI in your mind: Based on the rendering order where the Context is at the bottom (layer n+1 is rendered on top of n) (that's how I see it), or the classical relationship graph where the root object is at the top with it's children anchored below.

    I think a temporal name for the bubble/sink mechanic is more descriptive. In that case I would vote for the iOS terminology (for the event object mechanic) EventWillHappen/EventDidHappen.
    Author of the Imhothar's Bags addon.

  3. #18
    Shadowlander
    Join Date
    Nov 2011
    Posts
    36

    Default

    I saw this thread and I had to add my 2cents.

    First off, I haven't really been standing out in the forums, and I had a rather long break from Rift, and now I'm mainly creating a new styling of the UI and this is my first time truly messing around with lua. Let me just add that I would love the ability to reskin native frames, as well as have actionbar functionality in the addon.

    Anyhow, coming from a .NET background, I don't see why the event system couldn't be more like

    Code:
    Events.Unit.Detail.Health:Add(identifier, callback)
    Events.Unit.Detail.Health:Remove(identifier)
    And obviously the event being added with the addon name to the events table at that point. I'm aware Attach() and Detach() are essentially the same thing, but I like thinking with object lists.

    Going into frames, they would have their own separate events table:

    Code:
    frame = UI.CreateFrame(...)
    frame.Events.LeftClick:Add(identifier, callback)
    frame.Events.RightClick:Add(identifier, callback)
    frame.Events.RightClick:Remove(identifier)
    E: And as Imhothar suggested, the parameters given to an event could possibly be in one table, however the type of the event should be declared within the object.

    Code:
    frame.Events.LeftClick = function(eventArgs)
    eventArgs = {
        type = "click",
        button = "left",
        x = 100
    }
    I would also like to take this opportunity to request a surefire way to attach a targetting event on click to any player you wish, but not being able to change it while in combat, even for a non-restricted frame, as managing restrictions is a true pain in the ***. For example:

    Code:
    frame.Events.LeftClick:Add("targetplayer", function() Commands.Unit.Target("player"))
    frame.Events.LeftClick:Add("targetgroup01", function() Commands.Unit.Target("group01"))
    Last edited by Grinderofl; 11-22-2012 at 02:52 PM.

  4. #19
    Telaran
    Join Date
    Mar 2012
    Posts
    72

    Default

    How will Sink and Bubble work (or not work) for secure frames? Specifically the catch/halt? I assume that secure frames won't be allowed to catch/halt, as that could allow programatic changes, eg stick up tree of secure frames and catch on the ability that should be used.

    Or will secure frames (and parents) not be allowed to hook the sink/bubble events?

  5.   Click here to go to the next Rift Team post in this thread.   #20
    Rift Team
    Join Date
    Oct 2010
    Posts
    927

    Default

    Quote Originally Posted by Mere View Post
    How will Sink and Bubble work (or not work) for secure frames? Specifically the catch/halt? I assume that secure frames won't be allowed to catch/halt, as that could allow programatic changes, eg stick up tree of secure frames and catch on the ability that should be used.

    Or will secure frames (and parents) not be allowed to hook the sink/bubble events?
    The current plan is that :Catch() and :Halt() will be disabled if either the target or the current frame is set to restricted mode and the environment is in secure mode (which is basically "in combat"). This is currently equivalent to "the current frame is set to restricted mode and environment is in secure mode", but if the secure-mode-frame-parents-must-be-secure requirement is ever relaxed it should still be secure.
    Last edited by ZorbaTHut; 11-22-2012 at 08:21 PM.

  6. #21
    Champion Lorandii's Avatar
    Join Date
    Jun 2011
    Posts
    516

    Default

    I've been away, having stopped Rift even before my game time ran out, and went back to that "other game." A big reason was because of addon development in Rift; as Zorba pointed out in the first post, the event system in Rift needs a complete overhaul. If I were to guess, and this is just a guess, I'd say many addon authors and potential addon authors looked at Rift's API, compared it to its natural competition, and wondered why basic things were missing, and why what is there is so complicated and thus did not delve into Rift.

    Here are three things that are an absolute must for the redesign:
    1. A way to unregister every event an addon hooks in a single command
    2. Better filters for what you want to hook any addons (see RegisterUnitEvent in WoW)
    3. Scrap Utility.Event.Create and toss the dregs into the fire
    I assume the changes will still use table.add and table.remove, which are fine, but I would switch to Commands instead.
    Code:
    Command.HookEvent(Event.Some.Thing, Identifier, Callback, [CallbackDescriptionString]) -- string is optional
    Command.HookEventOnObject(Event.Some.Thing, Identifier, Callback, Object, [CallbackDecriptionString]) -- Object can be a unit, unitID, or UI object (like the minimap cluster, action bar 1, quest list, etc)
    Command.UnhookEvent(Event.Some.Thing, Identifier, [Object]) -- system removes Callback and string
    Command.UnhookEvents(Identifier) -- wipes the entire event table of everything Identifier touches
    Command.UnhookEvent passes Object as an option, because there may be a case where you want to register the event the traditional way AND register on an object. Conversely, when unhooking, you would want to specify what you want unhooked.

    I would further simply Utility.Event.Create to something like the following, using psuedocode.
    Code:
    local function SomeData()
        local playerName = Inspect.Unit.Detail("player").name
        local playerClass = Inspect.Unit.Detail("player").class
        local playerData = {}
        table.insert(playerData, {name = playerName, class = playerClass})
        Command.Event.Create(Event.Identifier.PlayerData, Callback, playerData, [DescriptionString])
    end

  7. #22
    Champion Lorandii's Avatar
    Join Date
    Jun 2011
    Posts
    516

    Default

    You may wonder why I suggested the ability to hook events on UI elements. Here's some ideas where it would be useful.
    • A guild member logs on/off, and you want to mark their location on the world and minimaps
    • You want the player's castbar events and APIs, ignoring every other unit
    • Rift is gaining 3D? Awesome! Now let me customize my UI graphics on the fly when the 3D event fires on UIParent (yes, in combat too, but elements need to be created beforehand, and this is a IsShown() switch)
    • Buffs have changed on a boss, so why scan through every unit the client can see if all you want is the boss?
    I'm sure you guys can think of other reasons and uses for event hooking on an object.

  8. #23
    Shadowlander
    Join Date
    Nov 2011
    Posts
    36

    Default

    I definitely agree with Lorandii, if only for performance reasons:

    You're only interested in boss buffs, if you have a bossframe, you need to go through all units and find the one you need, the loop of all units might be cheap, but if you have many of those, it adds up.

  9. #24
    Champion Lorandii's Avatar
    Join Date
    Jun 2011
    Posts
    516

    Default

    Upon reflection, I would add that Command.HookEventOnObject also be able to register events on addon created frames. Consider KaruulAlert; it would make things much simpler to do this:
    • Create a frame
    • Assign a buff to the frame
    • Hook buff events to the frame
    • Updates in real time without using system update polling
    • No impact on existing buff frames
    What this may do is cut down tainting across addons and the base UI, even if someone messes up code. You would see right away that MyAddon and KaruulAlert share the same name for a frame, and I forgot to make mine local. When things go south, it would be easy to figure out the problem exists in one or two addons, not twenty or thirty.

  10. #25
    RIFT Community Ambassador the_real_seebs's Avatar
    Join Date
    Jan 2011
    Posts
    16,859

    Default

    I am not sure what the performance cost of hooking an event on everything rather than just some things is. I'd guess tolerable due to LuaJit, but it seems like it might be worth benchmarking; I have no idea how much time we're talking about.
    You can play WoW in any MMO. You don't have to play WoW in RIFT. Oh, and no, RIFT is not a WoW clone. Not having fun any more? Learn to play, noob! I don't speak for Riftui, but I moderate stuff there. Just came back? Welcome back! Here's what's changed. (Updated for 2.5!)

  11. #26
    Telaran
    Join Date
    Jun 2011
    Posts
    82

    Default

    Lorandii's post nailed it! I liked the way..... that other game..... handled events
    Last edited by 0dine; 11-28-2012 at 02:29 PM.

  12.   Click here to go to the next Rift Team post in this thread.   #27
    Rift Team
    Join Date
    Oct 2010
    Posts
    927

    Default

    Summary updated. The biggest changes:

    * The event hierarchy no longer contains functions. Instead, Command.Event.* is used with the event hierarchy as parameters. Similarly, frames no longer have Event*Attach() functions, just EventAttach() that takes a parameter in Event.UI.*. This has a lot of advantages that I described earlier in the thread.
    * "Sink" has been renamed to "Dive" to avoid semantic confusion with "event sinks".

    Quote Originally Posted by Lorandii View Post
    You may wonder why I suggested the ability to hook events on UI elements. Here's some ideas where it would be useful.
    Quote Originally Posted by Lorandii View Post
    Upon reflection, I would add that Command.HookEventOnObject also be able to register events on addon created frames. Consider KaruulAlert; it would make things much simpler to do this:
    I guess I don't understand why you can't do this entirely within addon space. It doesn't feel like most of this requires backend support, and even if I were to provide a way to specifically hook, say, "a buff on unit X has changed", it wouldn't be significantly more efficient than the current solution.

  13. #28
    RIFT Community Ambassador the_real_seebs's Avatar
    Join Date
    Jan 2011
    Posts
    16,859

    Default

    Do we have any benchmark-like information that would make it practical to compare the costs of "register for this event only on unit X" and "register for events, do nothing if they're not on unit X"?

    My sort of quick back of the envelope thought: The cost of checking every unit for additional registered events is probably higher than the cost of discarding uninteresting events. If the game didn't have LuaJIT, it might be that the checks would be in native code, and the discards in Lua, and the discarding would be dramatically slower, but as is, I'm guessing it's not noticably slower, and the improved performance of not having to check units for registered events may actually be a net win.
    You can play WoW in any MMO. You don't have to play WoW in RIFT. Oh, and no, RIFT is not a WoW clone. Not having fun any more? Learn to play, noob! I don't speak for Riftui, but I moderate stuff there. Just came back? Welcome back! Here's what's changed. (Updated for 2.5!)

  14.   Click here to go to the next Rift Team post in this thread.   #29
    Rift Team
    Join Date
    Oct 2010
    Posts
    927

    Default

    Quote Originally Posted by the_real_seebs View Post
    My sort of quick back of the envelope thought: The cost of checking every unit for additional registered events is probably higher than the cost of discarding uninteresting events. If the game didn't have LuaJIT, it might be that the checks would be in native code, and the discards in Lua, and the discarding would be dramatically slower, but as is, I'm guessing it's not noticably slower, and the improved performance of not having to check units for registered events may actually be a net win.
    This is roughly my evaluation as well. Also, I feel like there are much simpler and more beneficial things to implement - even if per-unit hooking were a speed benefit, it wouldn't be enough of a speed benefit to justify the implementation time, given the missing features and API functions that remain to be added.

    The API is specifically designed to make things like unit comparisons easy - dumping an Event.Buff.Add because you're uninterested in the unit should be no more than a single string-compare or table lookup. A single :SetText() is probably one or two orders of magnitude more expensive.

  15. #30
    RIFT Community Ambassador the_real_seebs's Avatar
    Join Date
    Jan 2011
    Posts
    16,859

    Default

    The one use I can think of for a frame info handler of some sort would be some kind of UI which lets you drag spells onto unit frames to target them. Which I don't think works anyway, but it's a thing where a .Move() could conceivably want a macro or something, maybe. Hmm.

    For clicks, etcetera, I would like to be able to distinguish between "fire macro when button goes down", "fire macro when button goes up", and "fire macro on a click". Of course, you presumably want the whole click series to be able to trigger only one macro. This is relevant to trying to make usable UI buttons that could replace the built-in buttons in some way.

    Not sure whether keybinding is relevant to this, but it might be: What should happen for events if I press a key, or if I want to bind a key to a button? My intuition is that there ought to be some kind of equivalence, so that I can bind a key to a given mouse event on a given button -- possibly letting me bind distinct keys to left and right clicks.

    Right now, the macro system seems to have very poor support for modifiers (no way to make a line of macro execute only when no modifiers are down, for instance). If this isn't likely to get fixed, maybe we could get something in the addon API so that we could do something like:

    Frame:Attach(LeftClick, "macro goes here", { modkey = 'control' })
    Frame:Attach(LeftClick, "other macro", { modkey = false })

    where multiple macros can be attached if they have different templates, and only the one whose template matches an event gets fired. (And on a related note, I sort of want to be able to change the icon I display in a frame based on modifier keys...)

    I like :Halt(), I also sort of like :Reject() for that functionality. Dive/Bubble work for me.

    I sort of like the notion that a handler for an actual event should be able to pass the event to a different object entirely, but this creates problems if there's secure frames involved.
    You can play WoW in any MMO. You don't have to play WoW in RIFT. Oh, and no, RIFT is not a WoW clone. Not having fun any more? Learn to play, noob! I don't speak for Riftui, but I moderate stuff there. Just came back? Welcome back! Here's what's changed. (Updated for 2.5!)

+ Reply to Thread
Page 2 of 4 FirstFirst 1 2 3 4 LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts