2
2
mirror of https://github.com/Hilbis/Hilbish synced 2025-04-25 06:53:22 +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
### Added
- 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
### Fixed

View File

@ -47,7 +47,7 @@ type Recoverer func(event string, handler *Listener, err interface{})
type Listener struct{
typ listenerType
once bool
caller func(...interface{})
caller func(...interface{}) rt.Value
luaCaller *rt.Closure
}
@ -73,10 +73,11 @@ func New(rtm *rt.Runtime) *Bait {
}
// 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]
if handles == nil {
return
return nil
}
for idx, handle := range handles {
@ -97,28 +98,37 @@ func (b *Bait) Emit(event string, args ...interface{}) {
}
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 event != "error" {
b.Emit("error", event, handle.luaCaller, err.Error())
return
return nil
}
// if there is an error in an error event handler, panic instead
// (calls the go recoverer function)
panic(err)
}
if luaRet != rt.NilValue {
returns = append(returns, luaRet)
}
} else {
handle.caller(args...)
ret := handle.caller(args...)
if ret != rt.NilValue {
returns = append(returns, ret)
}
}
if handle.once {
b.removeListener(event, idx)
}
}
return returns
}
// 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{
typ: goListener,
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.
func (b *Bait) OnLua(event string, handler *rt.Closure) *Listener {
listener :=&Listener{
listener := &Listener{
typ: luaListener,
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.
func (b *Bait) Once(event string, handler func(...interface{})) *Listener {
func (b *Bait) Once(event string, handler func(...interface{}) rt.Value) *Listener {
listener := &Listener{
typ: goListener,
once: true,
@ -226,27 +236,6 @@ func (b *Bait) loaderFunc(rtm *rt.Runtime) (rt.Value, func()) {
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)
// Catches an event. This function can be used to act on events.
// #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() {
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)
// Add Ctrl-C handler
hooks.On("signal.sigint", func(...interface{}) {
hooks.On("signal.sigint", func(...interface{}) rt.Value {
if !interactive {
os.Exit(0)
}
return rt.NilValue
})
lr.rl.RawInputCallback = func(r []rune) {