Dispatches events to registered callback functions, in registration levels.
Handlers are kept as an ordered list of levels. Dispatch walks the levels from
first to last, calls every handler in a level whose pattern matches, and stops as
soon as a level contains a matching non-passthrough handler that returned
:handled. Registration decides the order: :top puts a handler in a new first
level, :bottom in a new last one, and {:after, pid} in a new level directly
after the level containing that owner's handler.
Drafter.EventHandler.register_handler({:type, :key}, &handle/1, self())
Drafter.EventHandler.dispatch_event_sync({:key, :escape})
#=> :handledEvent patterns:
:any— every event{:type, type}— any two-element event tuple taggedtype{type, sub_type}— a two-element event tuple taggedtypewhose payload is a map withtype: sub_type, which is how a mouse sub-kind is selected
A handler function takes the event and returns :handled to consume it or
anything else to let dispatch continue. Exceptions raised inside it are caught and
turned into {:error, exception}, which does not count as handled.
Handlers are removed when their owner process exits; owners are monitored at registration. Dead owners are also swept on every dispatch.
The functions here resolve the handler process through Drafter.Session.Context
under the :event_handler key, except register_handler/4 which accepts an
explicit :target.
Summary
Functions
Returns a specification to start this module under a supervisor.
Dispatch event without waiting for the handlers to run.
Dispatch event and return once every handler that ran has returned.
Register handler_fn for events matching event_pattern, owned by owner_pid.
Start a handler process.
Remove handlers owned by owner_pid.
Functions
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec dispatch_event(term()) :: :ok
Dispatch event without waiting for the handlers to run.
Returns :ok immediately and discards whether anything handled the event; use
dispatch_event_sync/1 when that matters.
@spec dispatch_event_sync(term()) :: :handled | :passthrough
Dispatch event and return once every handler that ran has returned.
:handled means a matching non-passthrough handler consumed the event and later
levels were skipped. :passthrough means it was not consumed, whether or not
handlers ran.
Register handler_fn for events matching event_pattern, owned by owner_pid.
event_pattern is :any, {:type, type} or {type, sub_type}. handler_fn
takes the event and returns :handled to consume it.
Options:
:passthrough— whentruethe handler never consumes the event, whatever it returns. Defaultfalse.:level—:top(default) inserts a new first level,:bottoma new last one,{:after, pid}a new level right after the one holdingpid's handler.:target— the handler process to register with; defaults to the session's.
Returns {:ok, handler_process}, or {:error, :dead_process} if owner_pid is
not alive. The registration is dropped when owner_pid exits.
@spec start_link(keyword()) :: GenServer.on_start()
Start a handler process.
Options:
:name— registered name, defaultDrafter.EventHandler. Passnilto start it unregistered, which is what a session other than the local terminal does.
Remove handlers owned by owner_pid.
With event_pattern nil (the default) every handler that owner registered is
removed and the monitor on it is released. With a pattern, only handlers
registered under exactly that pattern are removed. Levels left empty are dropped.