dr-scripts icon indicating copy to clipboard operation
dr-scripts copied to clipboard

[script][events] - Create concept of event history

Open asechrest opened this issue 2 years ago • 7 comments

(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)

asechrest avatar Jun 19 '22 17:06 asechrest

Also, a thanks to @rcuhljr for significant help conceptually and programmatically.

asechrest avatar Jun 19 '22 17:06 asechrest

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.

asechrest avatar Jun 19 '22 17:06 asechrest

This approach seems reasonable to me. A few questions:

  1. Are there concrete plans now to use this functionality, or is this just in case someone wants it later?
  2. 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.

asechrest avatar Jun 20 '22 14:06 asechrest

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

rpherbig avatar Jun 20 '22 14:06 rpherbig

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.

asechrest avatar Jun 20 '22 15:06 asechrest

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

asechrest avatar Jul 02 '22 14:07 asechrest

This is still on my radar.

asechrest avatar Jan 22 '23 14:01 asechrest