mirror of
https://github.com/gookit/event
synced 2025-09-27 03:15:58 +08:00
Merge branch 'master' into ReflectValueListenCompareKey
This commit is contained in:
40
listener_key.go
Normal file
40
listener_key.go
Normal file
@@ -0,0 +1,40 @@
|
||||
// Package event is lightweight event manager and dispatcher implements by Go.
|
||||
package event
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"unsafe"
|
||||
_ "unsafe" // go linkname
|
||||
)
|
||||
|
||||
func getReflectRawPointer(v reflect.Value) uintptr {
|
||||
switch v.Kind() {
|
||||
case reflect.Func:
|
||||
return uintptr(getNativePointerLink(&v))
|
||||
case reflect.Pointer, reflect.Chan, reflect.Map, reflect.UnsafePointer:
|
||||
return v.Pointer()
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
// only validate in reflect.Pointer, reflect.Chan, reflect.Map, reflect.UnsafePointer, reflect.Func
|
||||
//go:linkname getNativePointerLink reflect.(*Value).pointer
|
||||
func getNativePointerLink(*reflect.Value) unsafe.Pointer
|
||||
|
||||
type listenerCompareKey struct {
|
||||
strData string
|
||||
ptrData uintptr
|
||||
}
|
||||
|
||||
func getListenCompareKey(src Listener) listenerCompareKey {
|
||||
ret := listenerCompareKey{
|
||||
ptrData: getReflectRawPointer(reflect.ValueOf(src)),
|
||||
}
|
||||
if ret.ptrData == 0 {
|
||||
//ret.strData = fmt.Sprintf("%v", src)
|
||||
ret.strData = fmt.Sprintf("%p", any(src))
|
||||
}
|
||||
return ret
|
||||
}
|
77
listener_key_test.go
Normal file
77
listener_key_test.go
Normal file
@@ -0,0 +1,77 @@
|
||||
package event
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/require"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_getListenCompareKey(t *testing.T) {
|
||||
t.Run("ptr", func(t *testing.T) {
|
||||
makeFn := func(a int) ListenerFunc {
|
||||
return func(e Event) error {
|
||||
_ = a
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
f1 := makeFn(11)
|
||||
f2 := makeFn(22)
|
||||
f2same := makeFn(22)
|
||||
f2copy := f2
|
||||
require.NotEqual(t, getListenCompareKey(f1), getListenCompareKey(f2))
|
||||
require.NotEqual(t, getListenCompareKey(f2), getListenCompareKey(f2same))
|
||||
require.NotEqual(t, getListenCompareKey(f2same), getListenCompareKey(f2copy))
|
||||
require.Equal(t, getListenCompareKey(f2copy), getListenCompareKey(f2))
|
||||
|
||||
f3ptr := &testListener{userData: "3"}
|
||||
ptr4 := &testListener{userData: "4"}
|
||||
ptr4Same := &testListener{userData: "4"}
|
||||
ptr4Copy := ptr4
|
||||
|
||||
require.NotEqual(t, getListenCompareKey(f3ptr), getListenCompareKey(ptr4))
|
||||
require.NotEqual(t, getListenCompareKey(ptr4), getListenCompareKey(ptr4Same))
|
||||
require.NotEqual(t, getListenCompareKey(ptr4Same), getListenCompareKey(ptr4Copy))
|
||||
require.Equal(t, getListenCompareKey(ptr4Copy), getListenCompareKey(ptr4Copy))
|
||||
|
||||
})
|
||||
|
||||
t.Run("same value", func(t *testing.T) {
|
||||
|
||||
f5struct := testListenerReadOnly{userData: "5"}
|
||||
struct6 := testListenerReadOnly{userData: "6"}
|
||||
struct6same := testListenerReadOnly{userData: "6"}
|
||||
struct6copy := struct6
|
||||
|
||||
require.NotEqual(t, getListenCompareKey(f5struct), getListenCompareKey(struct6))
|
||||
require.Equal(t, getListenCompareKey(struct6), getListenCompareKey(struct6same)) // equal when struct data
|
||||
require.Equal(t, getListenCompareKey(struct6same), getListenCompareKey(struct6copy)) // equal when struct data
|
||||
require.Equal(t, getListenCompareKey(struct6copy), getListenCompareKey(struct6))
|
||||
|
||||
f7func := ListenerFunc(testEmptyFunc1)
|
||||
func8 := ListenerFunc(testEmptyFunc2)
|
||||
func8same := ListenerFunc(testEmptyFunc2)
|
||||
func8copy := func8
|
||||
|
||||
require.NotEqual(t, getListenCompareKey(f7func), getListenCompareKey(func8))
|
||||
require.Equal(t, getListenCompareKey(func8), getListenCompareKey(func8same)) // equal when struct data
|
||||
require.Equal(t, getListenCompareKey(func8same), getListenCompareKey(func8copy)) // equal when struct data
|
||||
require.Equal(t, getListenCompareKey(func8copy), getListenCompareKey(func8))
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func testEmptyFunc1(e Event) error {
|
||||
return nil
|
||||
}
|
||||
func testEmptyFunc2(e Event) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type testListenerReadOnly struct {
|
||||
userData string
|
||||
}
|
||||
|
||||
func (l testListenerReadOnly) Handle(e Event) error {
|
||||
return nil
|
||||
}
|
@@ -70,6 +70,36 @@ func Test_RemoveListener(t *testing.T) {
|
||||
require.Equal(t, global.n, 6+4+3+2)
|
||||
require.Equal(t, global.sum, 605) // 528+33+44=605
|
||||
})
|
||||
|
||||
t.Run("same value struct", func(t *testing.T) {
|
||||
global := &globalTestVal{}
|
||||
f1 := testListenerCalc{bind: 11, owner: global}
|
||||
f2 := testListenerCalc{bind: 22, owner: global}
|
||||
f2same := testListenerCalc{bind: 22, owner: global}
|
||||
f2copy := f2 // testListenerCalc{bind: 22, owner: global}
|
||||
|
||||
evBus := NewManager("")
|
||||
const evName = "ev1"
|
||||
evBus.On(evName, f1)
|
||||
evBus.On(evName, f2)
|
||||
evBus.On(evName, f2same)
|
||||
evBus.On(evName, f2copy)
|
||||
|
||||
evBus.MustFire(evName, nil)
|
||||
require.Equal(t, global.n, 4)
|
||||
require.Equal(t, global.sum, 77) //11+22+22+22=77
|
||||
|
||||
evBus.RemoveListener(evName, f1)
|
||||
evBus.MustFire(evName, nil)
|
||||
require.Equal(t, global.n, 7)
|
||||
require.Equal(t, global.sum, 143) // 77+22+22+22=143
|
||||
|
||||
evBus.RemoveListener(evName, f2)
|
||||
evBus.MustFire(evName, nil)
|
||||
require.Equal(t, global.n, 7)
|
||||
require.Equal(t, global.sum, 143) //
|
||||
})
|
||||
|
||||
t.Run("same func", func(t *testing.T) {
|
||||
global := &globalStatic
|
||||
|
||||
|
Reference in New Issue
Block a user