Add call_once variant of events

This commit is contained in:
Michael Miller 2020-11-14 17:02:24 -07:00
parent b4e74444d1
commit 19d57dd828
No known key found for this signature in database
GPG key ID: F9A0C5C65B162436

View file

@ -9,9 +9,12 @@ module Spectator
# No contextual information (or example) is provided to the hooks.
# The *name* defines the name of the event.
# This must be unique across all events.
# Two methods are defined - one to add a hook and the other to trigger the event which calls every hook.
# Three methods are defined - one to add a hook and the others to trigger the event which calls every hook.
# One trigger method, prefixed with *call_* will always call the event hooks.
# The other trigger method, prefixed with *call_once_* will only call the event hooks on the first invocation.
private macro group_event(name)
@{{name.id}}_hooks = Deque(->).new
@{{name.id}}_called = Atomic::Flag.new
# Defines a hook for the *{{name.id}}* event.
# The block of code given to this method is invoked when the event occurs.
@ -24,6 +27,15 @@ module Spectator
def call_{{name.id}} : Nil
@{{name.id}}_hooks.each(&.call)
end
# Signals that the *{{name.id}}* event has occurred.
# Only calls the hooks if the event hasn't been triggered before by this method.
# Returns true if the hooks were called and false if they weren't (called previously).
def call_once_{{name.id}} : Bool
first = @{{name.id}}_called.test_and_set
call_{{name.id}} if first
first
end
end
# Defines an event for an example.