From 45287f47d2dc7df9aad959a6c7e38adc4488f0a5 Mon Sep 17 00:00:00 2001 From: adman Date: Sun, 5 Apr 2026 16:07:05 +0200 Subject: [PATCH] Expose lower register functions Added RegisterLow and RegisterUntilLow this gives more power to the user --- event/event_bus.go | 43 +++++++++++++++++++----------------------- proto/smart_convert.go | 31 +++++++++++++----------------- 2 files changed, 32 insertions(+), 42 deletions(-) diff --git a/event/event_bus.go b/event/event_bus.go index d228697..91c7cd4 100644 --- a/event/event_bus.go +++ b/event/event_bus.go @@ -67,8 +67,6 @@ func (e MainHandlerErr) Unwrap() error { // DontForwardErr will stop the event from being forwarded to other handlers, including anything handlers. var DontForwardErr = errors.New("dont forward") var WhileClosingErr = errors.New("error while closing") - -// CloseNonCriticalErr will close even when the event is non-critical var ContextDoneErr = errors.New("context done") var RecvNotOkErr = errors.New("recv not ok") @@ -114,40 +112,37 @@ func (l *Loop) RegisterEventSource(ch <-chan any) { // Instead, it will log it to slog.Error // Warning: If a bad handler is passed in the program will panic. func (l *Loop) Register(h any) { - l.RegisterCustomType(ValidateHandler(h)) + eventType, hv := ValidateHandler(h) + l.RegisterLow(eventType, hv, false) } -// RegisterCustomType registers a handler that will not close the loop if it returns an error. +// RegisterLow registers a handler that will not close the loop if it returns an error. // Instead, it will log it to slog.Error +// This does not hold true for signaling errors like HandlerDoneErr or DontForwardErr // Warning: If a bad handler is passed in the program will panic. -func (l *Loop) RegisterCustomType(eventType reflect.Type, hv reflect.Value) { - handleFunc := func(packet any) error { - v := hv.Call([]reflect.Value{reflect.ValueOf(packet)})[0] - if !v.IsNil() { - err := v.Interface().(error) - if errors.As(err, &HandlerDoneErr{}) || errors.Is(err, DontForwardErr) { - return err +func (l *Loop) RegisterLow(eventType reflect.Type, hv reflect.Value, critical bool) { + handleFunc := hv + if !critical { + handleFunc = reflect.ValueOf(func(packet any) error { + v := hv.Call([]reflect.Value{reflect.ValueOf(packet)})[0] + if !v.IsNil() { + err := v.Interface().(error) + if errors.As(err, &HandlerDoneErr{}) || errors.Is(err, DontForwardErr) { + return err + } + slog.Error("handler failed", "err", err) } - slog.Error("handler failed", "err", err) - } - return nil + return nil + }) } - l.RegisterDirect(eventType, reflect.ValueOf(handleFunc)) + l.HandlerFunctions[eventType] = append(l.HandlerFunctions[eventType], handleFunc) } // RegisterCritical registers a handler that will close the loop if it returns an error. // Warning: If a bad handler is passed in the program will panic. func (l *Loop) RegisterCritical(h any) { eventType, hv := ValidateHandler(h) - l.RegisterDirect(eventType, hv) -} - -func (l *Loop) RegisterDirect(k reflect.Type, h reflect.Value) { - l.HandlerFunctions[k] = append(l.HandlerFunctions[k], h) -} - -func (l *Loop) RegisterIgnore(t any) { - l.RegisterDirect(reflect.TypeOf(t), reflect.ValueOf(func(any) error { return nil })) + l.HandlerFunctions[eventType] = append(l.HandlerFunctions[eventType], hv) } // FireFound triggers all handlers registered for the specified event type and returns if handlers were found or an error occurred. diff --git a/proto/smart_convert.go b/proto/smart_convert.go index d41e575..ded0f74 100644 --- a/proto/smart_convert.go +++ b/proto/smart_convert.go @@ -63,36 +63,35 @@ func SmartConvert(from reflect.Value, to reflect.Type) (ret reflect.Value) { // RegisterUntilLatest registers a handler for all versions between the passed in packet version and the latest supported version. // Warning: If a bad handler is passed in, the program will panic. func (c *Conn) RegisterUntilLatest(h any) { - c.registerUntil(h, LatestVersion, false) + eventType, hv := event.ValidateHandler(h) + c.RegisterUntilLow(eventType, hv, LatestVersion, false) } // RegisterUntil registers a handler for all versions between the passed in packet version and the specified version. // Warning: If a bad handler is passed in, the program will panic. func (c *Conn) RegisterUntil(h any, until string) { - c.registerUntil(h, until, false) + eventType, hv := event.ValidateHandler(h) + c.RegisterUntilLow(eventType, hv, until, false) } // RegisterCriticalUntilLatest registers a handler for all versions between the passed in packet version and the latest supported version. // If this handler returns an error, the connection will be closed. // Warning: If a bad handler is passed in, the program will panic. func (c *Conn) RegisterCriticalUntilLatest(h any) { - c.registerUntil(h, LatestVersion, true) + eventType, hv := event.ValidateHandler(h) + c.RegisterUntilLow(eventType, hv, LatestVersion, true) } // RegisterCriticalUntil registers a handler for all versions between the passed in packet version and the specified version. // If this handler returns an error, the connection will be closed. // Warning: If a bad handler is passed in, the program will panic. func (c *Conn) RegisterCriticalUntil(h any, until string) { - c.registerUntil(h, until, true) + eventType, hv := event.ValidateHandler(h) + c.RegisterUntilLow(eventType, hv, until, true) } -func (c *Conn) registerUntil(h any, until string, critical bool) { - eventType, hv := event.ValidateHandler(h) - if critical { - c.RegisterDirect(eventType, hv) - } else { - c.RegisterCustomType(eventType, hv) - } +func (c *Conn) RegisterUntilLow(eventType reflect.Type, hv reflect.Value, until string, critical bool) { + c.RegisterLow(eventType, hv, critical) if !eventType.Implements(reflect.TypeFor[proto_base.EncodeDecodeAble]()) { panic("expected method with argument that implements proto_base.EncodeDecodeAble") } @@ -110,12 +109,12 @@ func (c *Conn) registerUntil(h any, until string, critical bool) { versionName := proto_generated.SupportedVersions[i] versionInfo, err = data.LookUpVersionByName(versionName) if err != nil { - panic("protocol version not found") + panic("protocol version not found this should not happen even if a wrong type is passed in") } var newPacketInfo proto_base.PacketInfo newPacketInfo, found = LookupPacketInfoByNameProtocolVersionStateAndDirection(packetInfo.Name, versionInfo.Version, packetInfo.State, packetInfo.Direction) if !found { - panic("packet not found") + panic("packet not found in future version") } newT := reflect.TypeOf(newPacketInfo.Type) if !SmartConvertibleTo(newT, reflect.TypeOf(packetInfo.Type)) { @@ -128,10 +127,6 @@ func (c *Conn) registerUntil(h any, until string, critical bool) { } return v.Interface().(error) } - if critical { - c.RegisterDirect(newT, reflect.ValueOf(handleFunc)) - } else { - c.RegisterCustomType(newT, reflect.ValueOf(handleFunc)) - } + c.RegisterLow(newT, reflect.ValueOf(handleFunc), critical) } }