From 02dd4360146c8dff32af8f3aa6902c947bbb8810 Mon Sep 17 00:00:00 2001 From: Tnze Date: Sat, 28 May 2022 01:48:36 +0800 Subject: [PATCH] fix bitset bugs --- server/clientinfo/clientinfo.go | 2 +- server/ecs/bitset.go | 8 ++++++-- server/ecs/storage.go | 9 +++------ server/ecs/system.go | 32 ++++++++++++++++++-------------- server/player/player.go | 2 +- server/world/world.go | 2 +- 6 files changed, 30 insertions(+), 25 deletions(-) diff --git a/server/clientinfo/clientinfo.go b/server/clientinfo/clientinfo.go index 9ce299c..9c93895 100644 --- a/server/clientinfo/clientinfo.go +++ b/server/clientinfo/clientinfo.go @@ -38,7 +38,7 @@ func (c *ClientInformation) Init(g *server.Game) { return } } - }), "ClientInfoSystem", nil) + }), "go-mc:ClientInfoSystem", nil) g.AddHandler(&server.PacketHandler{ ID: packetid.ServerboundClientInformation, F: func(client *server.Client, player *server.Player, p server.Packet758) error { diff --git a/server/ecs/bitset.go b/server/ecs/bitset.go index 28ab362..8bf9371 100644 --- a/server/ecs/bitset.go +++ b/server/ecs/bitset.go @@ -59,9 +59,13 @@ func (b *BitSet) And(other *BitSet) *BitSet { } func (b *BitSet) AndNot(other BitSet) *BitSet { - result := BitSet{values: make([]uint, max(len(b.values), len(other.values)))} + result := BitSet{values: make([]uint, len(b.values))} for i := range b.values { - result.values[i] = b.values[i] & ^other.values[i] + if i < len(other.values) { + result.values[i] = b.values[i] & ^other.values[i] + } else { + result.values[i] = b.values[i] + } } return &result } diff --git a/server/ecs/storage.go b/server/ecs/storage.go index 12b99f7..f99a766 100644 --- a/server/ecs/storage.go +++ b/server/ecs/storage.go @@ -45,15 +45,12 @@ func (NullStorage[T]) SetValue(eid Index, v T) {} func (NullStorage[T]) DelValue(eid Index) {} type MaskedStorage[T any] struct { - BitSetLike + BitSet Storage[T] Len int } func (m *MaskedStorage[T]) Init() { - if m.BitSetLike == nil { - m.BitSetLike = BitSet{make(map[Index]struct{})} - } m.Storage.Init() } func (m *MaskedStorage[T]) GetValue(eid Index) *T { @@ -64,14 +61,14 @@ func (m *MaskedStorage[T]) GetValue(eid Index) *T { } func (m *MaskedStorage[T]) GetValueAny(eid Index) any { return m.GetValue(eid) } func (m *MaskedStorage[T]) SetValue(eid Index, v T) { - if !m.BitSetLike.Set(eid) { + if !m.BitSet.Set(eid) { m.Len++ } m.Storage.SetValue(eid, v) } func (m *MaskedStorage[T]) SetAny(eid Index, v any) { m.SetValue(eid, v.(T)) } func (m *MaskedStorage[T]) DelValue(eid Index) { - if m.BitSetLike.Unset(eid) { + if m.BitSet.Unset(eid) { m.Len-- } m.Storage.DelValue(eid) diff --git a/server/ecs/system.go b/server/ecs/system.go index d5a41d3..335c45c 100644 --- a/server/ecs/system.go +++ b/server/ecs/system.go @@ -14,8 +14,9 @@ type funcsystem struct { func FuncSystem(F any) System { type Storage interface { - BitSetLike GetValueAny(eid Index) any + And(*BitSet) *BitSet + Range(f func(eid Index)) } f := reflect.ValueOf(F) in := f.Type().NumIn() @@ -37,22 +38,25 @@ func FuncSystem(F any) System { } args := make([]reflect.Value, len(storages)) if len(storages) > 0 { - set := BitSetLike(storages[0]) + set := reflect.ValueOf(storages[0]).FieldByName("BitSet").Addr() for _, v := range storages[1:] { - set = set.And(v) + p := reflect.ValueOf(v).FieldByName("BitSet").Addr() + set = set.MethodByName("And").Call([]reflect.Value{p})[0] } - set.Range(func(eid Index) { - for i := range args { - arg := storages[i].GetValueAny(eid) - if arg == nil { - args[i] = reflect.Zero(argTypes[i]) - } else if needCopy[i] { - args[i] = reflect.ValueOf(arg).Elem() - } else { - args[i] = reflect.ValueOf(arg) + set.MethodByName("Range").Call([]reflect.Value{ + reflect.ValueOf(func(eid Index) { + for i := range args { + arg := storages[i].GetValueAny(eid) + if arg == nil { + args[i] = reflect.Zero(argTypes[i]) + } else if needCopy[i] { + args[i] = reflect.ValueOf(arg).Elem() + } else { + args[i] = reflect.ValueOf(arg) + } } - } - f.Call(args) + f.Call(args) + }), }) } else { f.Call(args) diff --git a/server/player/player.go b/server/player/player.go index 55ab7d3..066011e 100644 --- a/server/player/player.go +++ b/server/player/player.go @@ -23,7 +23,7 @@ func (p playerSpawnSystem) Update(w *ecs.World) { pos, rot := ecs.GetComponent[server.Pos](w), ecs.GetComponent[server.Rot](w) profiles := ecs.GetComponent[PlayerProfile](w) dimensionRes := ecs.GetResource[world.DimensionList](w) - players.AndNot(profiles.BitSetLike).Range(func(eid ecs.Index) { + players.AndNot(profiles.BitSet).Range(func(eid ecs.Index) { player := players.GetValue(eid) client := clients.GetValue(eid) profile, err := p.GetPlayer(player.UUID) diff --git a/server/world/world.go b/server/world/world.go index 45c690f..fbd8240 100644 --- a/server/world/world.go +++ b/server/world/world.go @@ -2,12 +2,12 @@ package world import ( _ "embed" - "github.com/Tnze/go-mc/server" "io" "unsafe" "github.com/Tnze/go-mc/nbt" pk "github.com/Tnze/go-mc/net/packet" + "github.com/Tnze/go-mc/server" "github.com/Tnze/go-mc/server/ecs" )