From f17b0c3152f40a3abe71dae3e74a29c4b733fad3 Mon Sep 17 00:00:00 2001 From: pangdogs Date: Wed, 5 Jun 2024 13:01:51 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ec/entity.go | 5 +- ec/entity_options.go | 5 +- ec/meta.go | 22 ------- entitycreator.go | 3 +- utils/generic/slicemap.go | 126 ++++++++++++++++++++++++++++++++++++++ utils/meta/meta.go | 46 ++++++++++++++ 6 files changed, 180 insertions(+), 27 deletions(-) delete mode 100644 ec/meta.go create mode 100644 utils/generic/slicemap.go create mode 100644 utils/meta/meta.go diff --git a/ec/entity.go b/ec/entity.go index 1855664..49fff5f 100644 --- a/ec/entity.go +++ b/ec/entity.go @@ -6,6 +6,7 @@ import ( "git.golaxy.org/core/internal/gctx" "git.golaxy.org/core/utils/container" "git.golaxy.org/core/utils/iface" + "git.golaxy.org/core/utils/meta" "git.golaxy.org/core/utils/option" "git.golaxy.org/core/utils/reinterpret" "git.golaxy.org/core/utils/uid" @@ -50,7 +51,7 @@ type Entity interface { // GetReflected 获取反射值 GetReflected() reflect.Value // GetMeta 获取Meta信息 - GetMeta() Meta + GetMeta() meta.Meta // DestroySelf 销毁自身 DestroySelf() } @@ -117,7 +118,7 @@ func (entity *EntityBehavior) GetReflected() reflect.Value { } // GetMeta 获取Meta信息 -func (entity *EntityBehavior) GetMeta() Meta { +func (entity *EntityBehavior) GetMeta() meta.Meta { return entity.opts.Meta } diff --git a/ec/entity_options.go b/ec/entity_options.go index 28f50b8..428f78d 100644 --- a/ec/entity_options.go +++ b/ec/entity_options.go @@ -2,6 +2,7 @@ package ec import ( "git.golaxy.org/core/utils/iface" + "git.golaxy.org/core/utils/meta" "git.golaxy.org/core/utils/option" "git.golaxy.org/core/utils/uid" ) @@ -13,7 +14,7 @@ type EntityOptions struct { Scope Scope // 可访问作用域 PersistId uid.Id // 实体持久化Id AwakeOnFirstAccess bool // 开启组件被首次访问时,检测并调用Awake() - Meta Meta // Meta信息 + Meta meta.Meta // Meta信息 } var With _Option @@ -68,7 +69,7 @@ func (_Option) AwakeOnFirstAccess(b bool) option.Setting[EntityOptions] { } // Meta Meta信息 -func (_Option) Meta(m Meta) option.Setting[EntityOptions] { +func (_Option) Meta(m meta.Meta) option.Setting[EntityOptions] { return func(o *EntityOptions) { o.Meta = m } diff --git a/ec/meta.go b/ec/meta.go deleted file mode 100644 index 5d0f2c6..0000000 --- a/ec/meta.go +++ /dev/null @@ -1,22 +0,0 @@ -package ec - -type Meta map[string]any - -func (m Meta) Get(k string) any { - if m == nil { - return nil - } - return m[k] -} - -func (m Meta) Range(fun func(k string, v any) bool) { - if fun == nil { - return - } - - for k, v := range m { - if !fun(k, v) { - return - } - } -} diff --git a/entitycreator.go b/entitycreator.go index d357392..f0c8c9c 100644 --- a/entitycreator.go +++ b/entitycreator.go @@ -8,6 +8,7 @@ import ( "git.golaxy.org/core/runtime" "git.golaxy.org/core/service" "git.golaxy.org/core/utils/iface" + "git.golaxy.org/core/utils/meta" "git.golaxy.org/core/utils/option" "git.golaxy.org/core/utils/uid" ) @@ -59,7 +60,7 @@ func (c EntityCreator) AwakeOnFirstAccess(b bool) EntityCreator { } // Meta 设置Meta信息 -func (c EntityCreator) Meta(m ec.Meta) EntityCreator { +func (c EntityCreator) Meta(m meta.Meta) EntityCreator { c.settings = append(c.settings, ec.With.Meta(m)) return c } diff --git a/utils/generic/slicemap.go b/utils/generic/slicemap.go new file mode 100644 index 0000000..4c233e3 --- /dev/null +++ b/utils/generic/slicemap.go @@ -0,0 +1,126 @@ +package generic + +import ( + "git.golaxy.org/core/utils/types" + "slices" +) + +func MakeSliceMap[K comparable, V any](kvs ...KV[K, V]) SliceMap[K, V] { + kvs = slices.Clone(kvs) + for i := len(kvs) - 1; i >= 0; i-- { + it := kvs[i] + + if !slices.ContainsFunc(kvs[:i], func(kv KV[K, V]) bool { + return kv.K == it.K + }) { + continue + } + + kvs = append(kvs[:i], kvs[i+1:]...) + } + return kvs +} + +func NewSliceMap[K comparable, V any](kvs ...KV[K, V]) *SliceMap[K, V] { + kvs = slices.Clone(kvs) + for i := len(kvs) - 1; i >= 0; i-- { + it := kvs[i] + + if !slices.ContainsFunc(kvs[:i], func(kv KV[K, V]) bool { + return kv.K == it.K + }) { + continue + } + + kvs = append(kvs[:i], kvs[i+1:]...) + } + return (*SliceMap[K, V])(&kvs) +} + +func MakeSliceMapFromGoMap[K comparable, V any](m map[K]V) SliceMap[K, V] { + sm := make(SliceMap[K, V], 0, len(m)) + for k, v := range m { + sm = append(sm, KV[K, V]{K: k, V: v}) + } + return sm +} + +func NewSliceMapFromGoMap[K comparable, V any](m map[K]V) *SliceMap[K, V] { + sm := make(SliceMap[K, V], 0, len(m)) + for k, v := range m { + sm = append(sm, KV[K, V]{K: k, V: v}) + } + return &sm +} + +type KV[K comparable, V any] struct { + K K + V V +} + +type SliceMap[K comparable, V any] []KV[K, V] + +func (m *SliceMap[K, V]) Add(k K, v V) { + idx := slices.IndexFunc(*m, func(kv KV[K, V]) bool { + return kv.K == k + }) + if idx >= 0 { + (*m)[idx] = KV[K, V]{K: k, V: v} + return + } + *m = append(*m, KV[K, V]{K: k, V: v}) +} + +func (m *SliceMap[K, V]) TryAdd(k K, v V) bool { + idx := slices.IndexFunc(*m, func(kv KV[K, V]) bool { + return kv.K == k + }) + if idx >= 0 { + return false + } + *m = append(*m, KV[K, V]{K: k, V: v}) + return true +} + +func (m *SliceMap[K, V]) Delete(k K) bool { + var ok bool + *m = slices.DeleteFunc(*m, func(kv KV[K, V]) bool { + ok = kv.K == k + return ok + }) + return ok +} + +func (m SliceMap[K, V]) Get(k K) (V, bool) { + idx := slices.IndexFunc(m, func(kv KV[K, V]) bool { + return kv.K == k + }) + if idx >= 0 { + return m[idx].V, true + } + return types.ZeroT[V](), false +} + +func (m SliceMap[K, V]) Value(k K) V { + idx := slices.IndexFunc(m, func(kv KV[K, V]) bool { + return kv.K == k + }) + if idx >= 0 { + return m[idx].V + } + return types.ZeroT[V]() +} + +func (m SliceMap[K, V]) Exist(k K) bool { + return slices.ContainsFunc(m, func(kv KV[K, V]) bool { + return kv.K == k + }) +} + +func (m SliceMap[K, V]) ToGoMap() map[K]V { + rv := make(map[K]V, len(m)) + for _, kv := range m { + rv[kv.K] = kv.V + } + return rv +} diff --git a/utils/meta/meta.go b/utils/meta/meta.go new file mode 100644 index 0000000..0898ef4 --- /dev/null +++ b/utils/meta/meta.go @@ -0,0 +1,46 @@ +package meta + +import "git.golaxy.org/core/utils/generic" + +type Meta = generic.SliceMap[string, any] + +type _MetaCtor struct { + meta Meta +} + +func (c _MetaCtor) Add(k string, v any) _MetaCtor { + c.meta.Add(k, v) + return c +} + +func (c _MetaCtor) Delete(k string) _MetaCtor { + c.meta.Delete(k) + return c +} + +func (c _MetaCtor) Combine(m map[string]any) _MetaCtor { + for k, v := range m { + c.meta.TryAdd(k, v) + } + return c +} + +func (c _MetaCtor) Override(m map[string]any) _MetaCtor { + for k, v := range m { + c.meta.Add(k, v) + } + return c +} + +func (c _MetaCtor) Clean() _MetaCtor { + c.meta = c.meta[:0] + return c +} + +func (c _MetaCtor) Get() Meta { + return c.meta +} + +func Make() _MetaCtor { + return _MetaCtor{} +}