dr-scripts
dr-scripts copied to clipboard
[script][events] - Create concept of event history
(Releasing as draft while we discuss)
Currently, Flags have no concept of a history of the events they've seen, and no concept of how many times they've seen the event and been "tripped". This is not a problem and having a history of the events they've seen was not originally contemplated. It was simply "have we seen it one or a dozen times? Ok, flag on".
This PR adds a concept of an event history to the events
script and class Flags. Tracking history is opt-in and history is held in a separate array of MatchData, with an entry for each time events
has seen a match since the user last retrieved the data. A user can retrieve the history and act on it as they wish.
To create a flag with history tracking, a user would call Flags.add_with_history('name', 'matches')
. The history can then be retrieved with Flags.read_matches('name')
. Reading the matches clears the history array.
Why Have This Concept?
The way events
is structured now, it is not truly tracking all specified events. It's just watching for a match, and setting the flag to on. If the flag sees three matches in succession, it's simply reassigning the flag array with the last MatchData seen. Allowing the script to have a history of all events triggered opens up an ability to act on them each and every time on a 1-to-1 level if a user so desires and to know exactly what matches were seen.
Possible Future Uses
- Better
;log
scripts - True Lich-based triggers (I'm working on this, though unsure if I'll release)
Also, a thanks to @rcuhljr for significant help conceptually and programmatically.
Examples in use:
[trigger-watcher: Number of elements in history: 2]
[trigger-watcher: All history is: {"stand"=>[], "peering_up"=>[#<MatchData "Peering up from the edge of the trail" 1:"Peering" 2:"edge" 3:"trail">, #<MatchData "Peering up from the edge of the trail" 1:"Peering" 2:"edge" 3:"trail">]}]
>
>;e echo Flags.read_matches('peering_up')
--- Lich: exec1 active.
[exec1: [#<MatchData "Peering up from the edge of the trail" 1:"Peering" 2:"edge" 3:"trail">, #<MatchData "Peering up from the edge of the trail" 1:"Peering" 2:"edge" 3:"trail">]]
--- Lich: exec1 has exited.
>
# RETRIEVED HISTORY, SO HISTORY ARRAY NOW CLEARED FOR CONTINUED MONITORING
>;e echo Flags.history['peering_up']
--- Lich: exec1 active.
[exec1: []]
--- Lich: exec1 has exited.
# NOW WE'LL TRIGGER THE FLAG AGAIN AND SEE THE HISTORY ARRAY POPULATING AGAIN
>
>l
[Dark Woodlands, Bulen Ond Alcas]
Peering up from the edge of the trail, twin saplings lean gracefully into each other as if attempting to gain added strength as a single unit. Bright pink and white water lilies glide leisurely across the faintly rippling surface of the lake, forming a perfect mirror reflection of themselves against the clear pool, some floating close enough to the shoreline to be captured by an admiring traveler. You also see a pile of rocks.
Also here: Barrask.
Obvious paths: southeast, west.
Room Number: 9518
>
[trigger-watcher: Number of elements in history: 1]
[trigger-watcher: All history is: {"stand"=>[], "peering_up"=>[#<MatchData "Peering up from the edge of the trail" 1:"Peering" 2:"edge" 3:"trail">]}]
[trigger-watcher: Flags are: {"stand"=>false, "peering_up"=>#<MatchData "Peering up from the edge of the trail" 1:"Peering" 2:"edge" 3:"trail">}]
[trigger-watcher: Is history array cleared? [#<MatchData "Peering up from the edge of the trail" 1:"Peering" 2:"edge" 3:"trail">]]
>;e echo Flags.history['peering_up']
--- Lich: exec1 active.
[exec1: [#<MatchData "Peering up from the edge of the trail" 1:"Peering" 2:"edge" 3:"trail">]]
--- Lich: exec1 has exited.
This approach seems reasonable to me. A few questions:
- Are there concrete plans now to use this functionality, or is this just in case someone wants it later?
- Why not make all flags have a history? Current flag usage stays the same because no one checks it, and it's easy to check in the future if we need to. There are some places we use
reget
and I wonder if they could be update to use this approach...
Thanks for reviewing. Answering 1: I have a script I've been working on that implements Genie-style triggers but using Lich. That script would utilize Flags history to trigger a one-to-one response for each trigger match even if they come in rapid succession. I also have an idea to make the ;log
script, or another one like it, more robust, and I would utilize Flags history for that. Other than that, this is sort of a just in case.
2 - I originally coded it have a history by default. But, I was concerned about the possible performance implications of building arrays of MatchData for all flags currently being used. Whether that concern is founded I'm not sure as I have no exposure to that level of programming/benchmarking. What do you think?
PS - Good thought on replacing reget with this. That hadn't occurred to me.
re: performance. I was wondering about that too. I suspect it'll be fine given how little what we do should stress a system, how short of a time most Flags are in existence, and how few times most Flags match. That said, I don't have a better read on it than "it should be fine".
@rcuhljr or one of the other devs may have a better idea
re: performance. I was wondering about that too. I suspect it'll be fine given how little what we do should stress a system, how short of a time most Flags are in existence, and how few times most Flags match. That said, I don't have a better read on it than "it should be fine".
@rcuhljr or one of the other devs may have a better idea
Another thought: as this is currently coded, allowing an existing Flag to have a history is as simple as changing it from Flags.add
to Flags.add_with_history
. And if we were editing legacy implementation of a Flag and wanted it to use history, we'd have to make some edits anyway to make use of said history. So we're touching it anyway, whether we make history opt in or not.
Ready for final review.
After quite a bit of discussion, I'm opting to build a history for all flags. Said history will clear if a user pulls the history for that flag using the read_matches
accessor method, or when the flag is deleted.
Note: I specifically don't delete the history when a Flags.reset
is requested. This is because resetting a Flag simply means clearing a single "hit" on the flag by clearing the MatchData being held, so that we can wait for the next hit. Clearing the history array at that point would defeat the purpose.
We will monitor for any performance hits and I can revert if necessary and go to plan B of building a history only when specifically requested by the user.
@rpherbig @MahtraDR
This is still on my radar.