2
2
mirror of https://github.com/Hilbis/Hilbish synced 2025-04-25 15:03:23 +00:00

feat: return values returned by bait hooks (closes #297)

This commit is contained in:
sammyette 2025-04-23 20:10:08 -04:00
parent 6827940466
commit 80d72a29bb
Signed by: sammyette
GPG Key ID: 904FC49417B44DCD
3 changed files with 24 additions and 33 deletions

View File

@ -3,6 +3,7 @@
## Unreleased ## Unreleased
### Added ### Added
- Forward/Right arrow key will fill in hint text (#327) - Forward/Right arrow key will fill in hint text (#327)
- Values returned by bait hooks will be passed to the `throw` caller
## [2.3.4] - 2024-12-28 ## [2.3.4] - 2024-12-28
### Fixed ### Fixed

View File

@ -47,7 +47,7 @@ type Recoverer func(event string, handler *Listener, err interface{})
type Listener struct{ type Listener struct{
typ listenerType typ listenerType
once bool once bool
caller func(...interface{}) caller func(...interface{}) rt.Value
luaCaller *rt.Closure luaCaller *rt.Closure
} }
@ -73,10 +73,11 @@ func New(rtm *rt.Runtime) *Bait {
} }
// Emit throws an event. // Emit throws an event.
func (b *Bait) Emit(event string, args ...interface{}) { func (b *Bait) Emit(event string, args ...interface{}) []rt.Value {
var returns []rt.Value
handles := b.handlers[event] handles := b.handlers[event]
if handles == nil { if handles == nil {
return return nil
} }
for idx, handle := range handles { for idx, handle := range handles {
@ -97,28 +98,37 @@ func (b *Bait) Emit(event string, args ...interface{}) {
} }
luaArgs = append(luaArgs, luarg) luaArgs = append(luaArgs, luarg)
} }
_, err := rt.Call1(b.rtm.MainThread(), funcVal, luaArgs...) luaRet, err := rt.Call1(b.rtm.MainThread(), funcVal, luaArgs...)
if err != nil { if err != nil {
if event != "error" { if event != "error" {
b.Emit("error", event, handle.luaCaller, err.Error()) b.Emit("error", event, handle.luaCaller, err.Error())
return return nil
} }
// if there is an error in an error event handler, panic instead // if there is an error in an error event handler, panic instead
// (calls the go recoverer function) // (calls the go recoverer function)
panic(err) panic(err)
} }
if luaRet != rt.NilValue {
returns = append(returns, luaRet)
}
} else { } else {
handle.caller(args...) ret := handle.caller(args...)
if ret != rt.NilValue {
returns = append(returns, ret)
}
} }
if handle.once { if handle.once {
b.removeListener(event, idx) b.removeListener(event, idx)
} }
} }
return returns
} }
// On adds a Go function handler for an event. // On adds a Go function handler for an event.
func (b *Bait) On(event string, handler func(...interface{})) *Listener { func (b *Bait) On(event string, handler func(...interface{}) rt.Value) *Listener {
listener := &Listener{ listener := &Listener{
typ: goListener, typ: goListener,
caller: handler, caller: handler,
@ -130,7 +140,7 @@ func (b *Bait) On(event string, handler func(...interface{})) *Listener {
// OnLua adds a Lua function handler for an event. // OnLua adds a Lua function handler for an event.
func (b *Bait) OnLua(event string, handler *rt.Closure) *Listener { func (b *Bait) OnLua(event string, handler *rt.Closure) *Listener {
listener :=&Listener{ listener := &Listener{
typ: luaListener, typ: luaListener,
luaCaller: handler, luaCaller: handler,
} }
@ -162,7 +172,7 @@ func (b *Bait) OffLua(event string, handler *rt.Closure) {
} }
// Once adds a Go function listener for an event that only runs once. // Once adds a Go function listener for an event that only runs once.
func (b *Bait) Once(event string, handler func(...interface{})) *Listener { func (b *Bait) Once(event string, handler func(...interface{}) rt.Value) *Listener {
listener := &Listener{ listener := &Listener{
typ: goListener, typ: goListener,
once: true, once: true,
@ -226,27 +236,6 @@ func (b *Bait) loaderFunc(rtm *rt.Runtime) (rt.Value, func()) {
return rt.TableValue(mod), nil return rt.TableValue(mod), nil
} }
func handleHook(t *rt.Thread, c *rt.GoCont, name string, catcher *rt.Closure, args ...interface{}) {
funcVal := rt.FunctionValue(catcher)
var luaArgs []rt.Value
for _, arg := range args {
var luarg rt.Value
switch arg.(type) {
case rt.Value: luarg = arg.(rt.Value)
default: luarg = rt.AsValue(arg)
}
luaArgs = append(luaArgs, luarg)
}
_, err := rt.Call1(t, funcVal, luaArgs...)
if err != nil {
e := rt.NewError(rt.StringValue(err.Error()))
e = e.AddContext(c.Next(), 1)
// panicking here won't actually cause hilbish to panic and instead will
// print the error and remove the hook (look at emission recover from above)
panic(e)
}
}
// catch(name, cb) // catch(name, cb)
// Catches an event. This function can be used to act on events. // Catches an event. This function can be used to act on events.
// #param name string The name of the hook. // #param name string The name of the hook.
@ -370,7 +359,7 @@ func (b *Bait) bthrow(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
for i, v := range c.Etc() { for i, v := range c.Etc() {
ifaceSlice[i] = v ifaceSlice[i] = v
} }
b.Emit(name, ifaceSlice...) ret := b.Emit(name, ifaceSlice...)
return c.Next(), nil return c.PushingNext(t.Runtime, ret...), nil
} }

3
lua.go
View File

@ -46,10 +46,11 @@ func luaInit() {
lib.LoadLibs(l, hooks.Loader) lib.LoadLibs(l, hooks.Loader)
// Add Ctrl-C handler // Add Ctrl-C handler
hooks.On("signal.sigint", func(...interface{}) { hooks.On("signal.sigint", func(...interface{}) rt.Value {
if !interactive { if !interactive {
os.Exit(0) os.Exit(0)
} }
return rt.NilValue
}) })
lr.rl.RawInputCallback = func(r []rune) { lr.rl.RawInputCallback = func(r []rune) {