v0.0.644 exerr.DeregisterListener
Build Docker and Deploy / Run goext test-suite (push) Failing after 1m18s
Build Docker and Deploy / Run goext test-suite (push) Failing after 1m18s
This commit is contained in:
+27
-4
@@ -6,15 +6,28 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// OrderedMap is like a normal map[TKey, TVal] - but its elements stay in order
|
// OrderedMap is like a normal map[TKey, TVal] - but its elements stay in order
|
||||||
|
// NOT THREADSAFE !!!
|
||||||
type OrderedMap[TKey comparable, TVal any] struct {
|
type OrderedMap[TKey comparable, TVal any] struct {
|
||||||
m map[TKey]*TVal
|
m map[TKey]*TVal
|
||||||
a []TKey
|
a []TKey
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewOrderedMap[TKey comparable, TVal any](cap int) *OrderedMap[TKey, TVal] {
|
func NewOrderedMap[TKey comparable, TVal any](caps ...int) *OrderedMap[TKey, TVal] {
|
||||||
|
if len(caps) == 0 {
|
||||||
|
return &OrderedMap[TKey, TVal]{
|
||||||
|
m: make(map[TKey]*TVal),
|
||||||
|
a: make([]TKey, 0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
omcap := 0
|
||||||
|
for _, v := range caps {
|
||||||
|
omcap += v
|
||||||
|
}
|
||||||
|
|
||||||
return &OrderedMap[TKey, TVal]{
|
return &OrderedMap[TKey, TVal]{
|
||||||
m: make(map[TKey]*TVal, cap),
|
m: make(map[TKey]*TVal, omcap),
|
||||||
a: make([]TKey, 0, cap),
|
a: make([]TKey, 0, omcap),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,7 +98,17 @@ func (o *OrderedMap[TKey, TVal]) Remove(key TKey) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *OrderedMap[TKey, TVal]) Iterate() iter.Seq[TVal] {
|
func (o *OrderedMap[TKey, TVal]) Iterate() iter.Seq2[TKey, TVal] {
|
||||||
|
return func(yield func(TKey, TVal) bool) {
|
||||||
|
for _, v := range o.a {
|
||||||
|
if !yield(v, *o.m[v]) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *OrderedMap[TKey, TVal]) IterateValues() iter.Seq[TVal] {
|
||||||
return func(yield func(TVal) bool) {
|
return func(yield func(TVal) bool) {
|
||||||
for _, v := range o.a {
|
for _, v := range o.a {
|
||||||
if !yield(*o.m[v]) {
|
if !yield(*o.m[v]) {
|
||||||
|
|||||||
@@ -15,6 +15,22 @@ func TestOrderedMapNew(t *testing.T) {
|
|||||||
tst.AssertArrayEqual(t, m.Array(), []int{})
|
tst.AssertArrayEqual(t, m.Array(), []int{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestOrderedMapNewNoCap(t *testing.T) {
|
||||||
|
m := NewOrderedMap[string, int]()
|
||||||
|
|
||||||
|
tst.AssertEqual(t, m.Size(), 0)
|
||||||
|
tst.AssertArrayEqual(t, m.Keys(), []string{})
|
||||||
|
tst.AssertArrayEqual(t, m.Array(), []int{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrderedMapNewWIthCap(t *testing.T) {
|
||||||
|
m := NewOrderedMap[string, int](4)
|
||||||
|
|
||||||
|
tst.AssertEqual(t, m.Size(), 0)
|
||||||
|
tst.AssertArrayEqual(t, m.Keys(), []string{})
|
||||||
|
tst.AssertArrayEqual(t, m.Array(), []int{})
|
||||||
|
}
|
||||||
|
|
||||||
func TestOrderedMapAddAndGet(t *testing.T) {
|
func TestOrderedMapAddAndGet(t *testing.T) {
|
||||||
m := NewOrderedMap[string, int](0)
|
m := NewOrderedMap[string, int](0)
|
||||||
|
|
||||||
@@ -238,7 +254,7 @@ func TestOrderedMapIterate(t *testing.T) {
|
|||||||
m.Add("c", 3)
|
m.Add("c", 3)
|
||||||
|
|
||||||
got := make([]int, 0)
|
got := make([]int, 0)
|
||||||
for v := range m.Iterate() {
|
for v := range m.IterateValues() {
|
||||||
got = append(got, v)
|
got = append(got, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,7 +268,7 @@ func TestOrderedMapIterateBreak(t *testing.T) {
|
|||||||
m.Add("c", 3)
|
m.Add("c", 3)
|
||||||
|
|
||||||
got := make([]int, 0)
|
got := make([]int, 0)
|
||||||
for v := range m.Iterate() {
|
for v := range m.IterateValues() {
|
||||||
got = append(got, v)
|
got = append(got, v)
|
||||||
if v == 2 {
|
if v == 2 {
|
||||||
break
|
break
|
||||||
@@ -262,6 +278,61 @@ func TestOrderedMapIterateBreak(t *testing.T) {
|
|||||||
tst.AssertArrayEqual(t, got, []int{1, 2})
|
tst.AssertArrayEqual(t, got, []int{1, 2})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestOrderedMapIterateSeq2(t *testing.T) {
|
||||||
|
m := NewOrderedMap[string, int](0)
|
||||||
|
m.Add("a", 1)
|
||||||
|
m.Add("b", 2)
|
||||||
|
m.Add("c", 3)
|
||||||
|
|
||||||
|
gotKeys := make([]string, 0)
|
||||||
|
gotVals := make([]int, 0)
|
||||||
|
for k, v := range m.Iterate() {
|
||||||
|
gotKeys = append(gotKeys, k)
|
||||||
|
gotVals = append(gotVals, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
tst.AssertArrayEqual(t, gotKeys, []string{"a", "b", "c"})
|
||||||
|
tst.AssertArrayEqual(t, gotVals, []int{1, 2, 3})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrderedMapIterateSeq2Break(t *testing.T) {
|
||||||
|
m := NewOrderedMap[string, int](0)
|
||||||
|
m.Add("a", 1)
|
||||||
|
m.Add("b", 2)
|
||||||
|
m.Add("c", 3)
|
||||||
|
|
||||||
|
gotKeys := make([]string, 0)
|
||||||
|
gotVals := make([]int, 0)
|
||||||
|
for k, v := range m.Iterate() {
|
||||||
|
gotKeys = append(gotKeys, k)
|
||||||
|
gotVals = append(gotVals, v)
|
||||||
|
if k == "b" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tst.AssertArrayEqual(t, gotKeys, []string{"a", "b"})
|
||||||
|
tst.AssertArrayEqual(t, gotVals, []int{1, 2})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrderedMapIterateSeq2AfterReorder(t *testing.T) {
|
||||||
|
m := NewOrderedMap[string, int](0)
|
||||||
|
m.Add("a", 1)
|
||||||
|
m.Add("b", 2)
|
||||||
|
m.Add("c", 3)
|
||||||
|
m.Add("a", 10) // moves "a" to end with new value
|
||||||
|
|
||||||
|
gotKeys := make([]string, 0)
|
||||||
|
gotVals := make([]int, 0)
|
||||||
|
for k, v := range m.Iterate() {
|
||||||
|
gotKeys = append(gotKeys, k)
|
||||||
|
gotVals = append(gotVals, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
tst.AssertArrayEqual(t, gotKeys, []string{"b", "c", "a"})
|
||||||
|
tst.AssertArrayEqual(t, gotVals, []int{2, 3, 10})
|
||||||
|
}
|
||||||
|
|
||||||
func TestOrderedMapIterateKeys(t *testing.T) {
|
func TestOrderedMapIterateKeys(t *testing.T) {
|
||||||
m := NewOrderedMap[string, int](0)
|
m := NewOrderedMap[string, int](0)
|
||||||
m.Add("a", 1)
|
m.Add("a", 1)
|
||||||
|
|||||||
+21
-4
@@ -2,8 +2,15 @@ package exerr
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"git.blackforestbytes.com/BlackForestBytes/goext/dataext"
|
||||||
|
"git.blackforestbytes.com/BlackForestBytes/goext/langext"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type ListenerKey struct {
|
||||||
|
_k string
|
||||||
|
}
|
||||||
|
|
||||||
type ListenerOpt struct {
|
type ListenerOpt struct {
|
||||||
NoLog bool
|
NoLog bool
|
||||||
}
|
}
|
||||||
@@ -11,20 +18,30 @@ type ListenerOpt struct {
|
|||||||
type Listener = func(method Method, v *ExErr, opt ListenerOpt)
|
type Listener = func(method Method, v *ExErr, opt ListenerOpt)
|
||||||
|
|
||||||
var listenerLock = sync.Mutex{}
|
var listenerLock = sync.Mutex{}
|
||||||
var listener = make([]Listener, 0)
|
var listener = dataext.NewOrderedMap[ListenerKey, Listener]()
|
||||||
|
|
||||||
func RegisterListener(l Listener) {
|
func RegisterListener(l Listener) ListenerKey {
|
||||||
listenerLock.Lock()
|
listenerLock.Lock()
|
||||||
defer listenerLock.Unlock()
|
defer listenerLock.Unlock()
|
||||||
|
|
||||||
listener = append(listener, l)
|
k := ListenerKey{_k: langext.MustHexUUID()}
|
||||||
|
|
||||||
|
listener.Add(k, l)
|
||||||
|
return k
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeregisterListener(key ListenerKey) {
|
||||||
|
listenerLock.Lock()
|
||||||
|
defer listenerLock.Unlock()
|
||||||
|
|
||||||
|
listener.Remove(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ee *ExErr) CallListener(m Method, opt ListenerOpt) {
|
func (ee *ExErr) CallListener(m Method, opt ListenerOpt) {
|
||||||
listenerLock.Lock()
|
listenerLock.Lock()
|
||||||
defer listenerLock.Unlock()
|
defer listenerLock.Unlock()
|
||||||
|
|
||||||
for _, v := range listener {
|
for _, v := range listener.Iterate() {
|
||||||
v(m, ee, opt)
|
v(m, ee, opt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
package goext
|
package goext
|
||||||
|
|
||||||
const GoextVersion = "0.0.643"
|
const GoextVersion = "0.0.644"
|
||||||
|
|
||||||
const GoextVersionTimestamp = "2026-05-30T00:07:10+0200"
|
const GoextVersionTimestamp = "2026-05-30T00:13:03+0200"
|
||||||
|
|||||||
Reference in New Issue
Block a user