refactor(golibs/bait): use 1 map for listeners

new-emitter
TorchedSammy 2022-08-01 22:34:59 -04:00
parent b13062316a
commit ea2791859c
Signed by: sammyette
GPG Key ID: 904FC49417B44DCD
1 changed files with 47 additions and 36 deletions

View File

@ -7,20 +7,30 @@ import (
"github.com/arnodel/golua/lib/packagelib" "github.com/arnodel/golua/lib/packagelib"
) )
type listenerType int
const (
goListener listenerType = iota
luaListener
)
type Recoverer func(event string, handler, err interface{}) type Recoverer func(event string, handler, err interface{})
type Listener struct{
typ listenerType
caller func(...interface{})
luaCaller *rt.Closure
}
type Bait struct{ type Bait struct{
Loader packagelib.Loader Loader packagelib.Loader
recoverer Recoverer recoverer Recoverer
luaHandlers map[string][]*rt.Closure handlers map[string][]*Listener
handlers map[string][]func(...interface{})
rtm *rt.Runtime rtm *rt.Runtime
} }
func New(rtm *rt.Runtime) Bait { func New(rtm *rt.Runtime) Bait {
b := Bait{ b := Bait{
luaHandlers: make(map[string][]*rt.Closure), handlers: make(map[string][]*Listener),
handlers: make(map[string][]func(...interface{})),
rtm: rtm, rtm: rtm,
} }
b.Loader = packagelib.Loader{ b.Loader = packagelib.Loader{
@ -33,33 +43,19 @@ func New(rtm *rt.Runtime) Bait {
func (b *Bait) Emit(event string, args ...interface{}) { func (b *Bait) Emit(event string, args ...interface{}) {
handles := b.handlers[event] handles := b.handlers[event]
luaHandles := b.luaHandlers[event] if handles == nil {
if handles == nil && luaHandles == nil {
return return
} }
if handles != nil { for _, handle := range handles {
for _, handle := range handles { defer func() {
defer func() { if err := recover(); err != nil {
if err := recover(); err != nil { b.callRecoverer(event, handle, err)
b.callRecoverer(event, handle, err) }
} }()
}()
handle(args...)
}
}
if luaHandles != nil { if handle.typ == luaListener {
for _, handle := range luaHandles { funcVal := rt.FunctionValue(handle.luaCaller)
defer func() {
if err := recover(); err != nil {
b.callRecoverer(event, handle, err)
}
}()
funcVal := rt.FunctionValue(handle)
var luaArgs []rt.Value var luaArgs []rt.Value
for _, arg := range args { for _, arg := range args {
var luarg rt.Value var luarg rt.Value
@ -72,31 +68,46 @@ func (b *Bait) Emit(event string, args ...interface{}) {
_, err := rt.Call1(b.rtm.MainThread(), funcVal, luaArgs...) _, err := rt.Call1(b.rtm.MainThread(), funcVal, luaArgs...)
if err != nil { if err != nil {
// panicking here won't actually cause hilbish to panic and instead will // 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) // print the error and remove the hook. reference the recoverer function in lua.go
panic(err) panic(err)
} }
} else {
handle.caller(args...)
} }
} }
} }
func (b *Bait) On(event string, handler func(...interface{})) { func (b *Bait) On(event string, handler func(...interface{})) *Listener {
if b.handlers[event] == nil { listener := &Listener{
b.handlers[event] = []func(...interface{}){} typ: goListener,
caller: handler,
} }
b.handlers[event] = append(b.handlers[event], handler)
b.addListener(event, listener)
return listener
} }
func (b *Bait) OnLua(event string, handler *rt.Closure) { func (b *Bait) OnLua(event string, handler *rt.Closure) *Listener {
if b.luaHandlers[event] == nil { listener :=&Listener{
b.luaHandlers[event] = []*rt.Closure{} typ: luaListener,
luaCaller: handler,
} }
b.luaHandlers[event] = append(b.luaHandlers[event], handler) b.addListener(event, listener)
return listener
} }
func (b *Bait) SetRecoverer(recoverer Recoverer) { func (b *Bait) SetRecoverer(recoverer Recoverer) {
b.recoverer = recoverer b.recoverer = recoverer
} }
func (b *Bait) addListener(event string, listener *Listener) {
if b.handlers[event] == nil {
b.handlers[event] = []*Listener{}
}
b.handlers[event] = append(b.handlers[event], listener)
}
func (b *Bait) callRecoverer(event string, handler, err interface{}) { func (b *Bait) callRecoverer(event string, handler, err interface{}) {
if b.recoverer == nil { if b.recoverer == nil {
panic(err) panic(err)