Skip to content

Commit

Permalink
Add event get; support event off w/no callback
Browse files Browse the repository at this point in the history
  • Loading branch information
pjeby committed Nov 18, 2018
1 parent 1d3184c commit 72dea58
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 4 deletions.
26 changes: 24 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Practical Event Listeners for Bash

`bashup.events` is an event listener/callback API for creating extensible bash programs. It's small (<2k), fast (~10k events/second), and highly portable (no bash4-isms or external programs used). Events can be one-time or repeated, listeners can be added or removed, and any string can be an event name. (You can even have "[promises](#promise-like-events)", of a sort!) Callbacks can be any command or function plus any number of arguments, and can even opt to receive [additional arguments supplied by the event](#passing-arguments-to-callbacks).
`bashup.events` is an event listener/callback API for creating extensible bash programs. It's small (<2.2k), fast (~10k events/second), and highly portable (no bash4-isms or external programs used). Events can be one-time or repeated, listeners can be added or removed, and any string can be an event name. (You can even have "[promises](#promise-like-events)", of a sort!) Callbacks can be any command or function plus any number of arguments, and can even opt to receive [additional arguments supplied by the event](#passing-arguments-to-callbacks).

Other features include:

Expand Down Expand Up @@ -34,6 +34,7 @@ Other features include:
* [event once](#event-once)
* [event encode](#event-encode)
* [event decode](#event-decode)
* [event get](#event-get)
* [event list](#event-list)
* [event quote](#event-quote)
* [event error](#event-error)
Expand Down Expand Up @@ -84,12 +85,16 @@ Event names can be any string, but performance is best if you limit them to pure

#### event off

`event off` *event cmd [args...]* unsubscribes the *cmd args...* callback from *event*
`event off` *event [cmd [args...]]* unsubscribes the *cmd args...* callback from *event*. If no callback is given, *all* callbacks are removed.

````sh
$ event off "event1" echo "got event1"
$ event emit "event1"
is this cool or what?

$ event on "event2" echo foo
$ event off "event2"
$ event emit "event2"
````

#### event has
Expand Down Expand Up @@ -374,6 +379,23 @@ For performance reasons, the function that handles event encoding is JITted. Ev
+spam
````

#### event get

`event get` *event* sets `$REPLY` to a string that can be `eval`'d to do the equivalent of `event emit "event" "${@:2}"`. This can be used for debugging, or to allow callbacks like `local` to be run in a specific calling context. An error 70 is returned if *event* is resolved.

~~~sh
$ event get lookup && echo "$REPLY"
match a got\ one\! "${@:2:1}"
match b number\ two "${@:2:1}"
match c third\ time\'s\ the\ charm "${@:2:1}"

$ event get "promised" && echo "$REPLY"
event "promised" already resolved
[70]
~~~

(Notice that the encoded commands in `$REPLY` reference parameters beginning with `"$2"`, which means that if you want to eval them with `"$@"` you'll need to unshift a dummy argument.)

#### event list

`event list` *prefix* sets `REPLY` to an array of currently-defined event names beginning with *prefix*. events that currently have listeners are returned, as are resolved events.
Expand Down
5 changes: 3 additions & 2 deletions bashup.events
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@ event(){ case $1 in error|quote|encode|decode);; *)
case "${3-}" in @_) n='$#';; @*[^0-9]*);; @[0-9]*) n=$((${3#@}));; esac; ${n:+
set -- "$1" "$2" "${@:4}" }
case $1/$# in
has/[12]) REPLY=;; */[12]) set -- error "${2-}: missing callback";;
on*/[12]) set -- error "${2-}: missing callback";; */[12]) REPLY=;;
*) __ev.quote "${@:3}";((${n/\$#/1}))&&REPLY+=' "${@:2:'"$n"'}"';REPLY+=$'\n'
esac
esac
esac ;__ev."$@";}
__ev.error(){ echo "$1">&2;return "${2:-64}";}
__ev.quote(){ REPLY=; ${@+printf -v REPLY ' %q' "$@"}; REPLY=${REPLY# };}
__ev.has(){ [[ ${!e-} && $'\n'"${!e}" == *$'\n'"$REPLY"* && ! ${!f-} ]];}
__ev.get(){ ${!f-};REPLY=${!e-};}
__ev.on(){ __ev.has && return;if [[ ! ${!f-} ]];then eval "$e"+='$REPLY';else eval "${!e-};$REPLY";fi;}
__ev.off(){ __ev.has||return 0; n="${!e}"; n=${n#"$REPLY"}; eval "$e"=$'"${n//\n"$REPLY"/\n}"';[[ ${!e} ]]||unset "${e%\[1]}";}
__ev.off(){ __ev.has||return 0; n="${!e}"; n=${REPLY:+"${n#"$REPLY"}"}; eval "$e"=$'"${n//\n"$REPLY"/\n}"';[[ ${!e} ]]||unset "${e%\[1]}";}
__ev.fire(){ ${!f-};set -- "$e" "${@:2}"; while [[ ${!1-} ]];do eval "unset ${1%\[1]};${!1}"; done ;}
__ev.all(){ ${!f-};e=${!e-};eval "${e//$'\n'/||return; }";}
__ev.any(){ ${!f-};e=${!e-};eval "${e//$'\n'/&&return|| } ! :";}
Expand Down

0 comments on commit 72dea58

Please sign in to comment.