| winter/goblins-utils | fix a bunch of stuff and rename modules | |
| README.md | fix a bunch of stuff and rename modules | |
winter's goblins utils
some assorted utilities i wrote for use with spritely goblins!
(winter goblins-utils signals)
this lets you use a "signals and slots" mechanism in goblins, much like the one
found in qt. in this case, the "signals" are events raised by an actor, and
the "slots" are just regular invocations of any other actor. the only
requirement for an actor to implement signals is that it provides a method
'connect-signal, which can be invoked like this:
(<- actor 'connect-signal signal params target slot)
;; for example:
(<- button 'connect-signal 'clicked '() form '('submit))
;; or:
(<- word-provider 'connect-signal 'word '(the-word)
log '('notice "Got word ~a" the-word))
it also provides a convenient macro that makes the above invocation neater:
(connect-signal (button 'clicked)
(form 'submit))
(connect-signal (word-provider 'word the-word)
(log 'notice "Got word ~a" the-word))
for example, when the word-provider from above triggers the signal 'word
with the argument "meow", it will invoke log as such:
(run-$/<- log 'notice "Got word ~a" "meow")
to add support for signals to an actor, you can use call-with-signals:
(define (^test bcom)
(call-with-signals
(lambda (add-handler trigger-signal)
(methods
[connect-signal add-handler]
;; ... whatever other methods you want ...
;; here you can use (trigger-signal) to do just that:
[(trigger-the-test some-arg)
(trigger-signal 'test some-arg)]))))
or more conveniently using the macro methods-with-signals, which automatically
defines the 'connect-signal method for you:
(define (^test bcom)
(methods-with-signals trigger
[(trigger-the-test some-arg)
(trigger 'test some-arg)]))
(winter goblins-utils logger)
this provides some simple logging utility actors. most likely you just want to log messages in text format to some output port, in which case:
(define log (spawn ^logger (current-error-port)))
($ log 'info "some message, which can use formatting: ~a" 'yippee)
;;=> [timestamp] (info) some message, which can use formatting: yippee
in general, loggers are invoked as (log-level message-format . format-args).
the available log levels, in increasing order of significance, are:
- debug
- notice
- info
- warning
- error
- fatal
when spawning a logger you can also provide a minimum log level like this:
(spawn ^logger port level), e.g.
(spawn ^logger (current-output-port) 'warning). then it will ignore any
messages at a lower level.
you can also create sub-loggers that could be used inside individual subsystems or actors in your program to automatically make their messages more specific:
(define ctx-log (spawn ^context-logger log "the context"))
($ ctx-log 'info "hello from context logger")
;;=> [timestamp] (info) [the context] hello from context logger
these can also be nested (by making a context-logger and passing it another existing context-logger), in which case the contexts will show up next to each other, with the most specific on the right.
if you need to send your log messages somewhere other than a text output port,
you can also use a generic-logger, which just passes them to a procedure:
(define pk-log (spawn ^generic-logger pk))
($ pk-log 'warning "hello! ~a" "yeah")
;; (warning () "hello! yeah")
(define ctx-pk-log (spawn ^context-logger pk-log "wow"))
($ ctx-pk-log 'info "this also works")
;; (info ("wow") "this also works")