optimize registry insertion

This commit is contained in:
Tnze
2024-06-16 02:22:10 +08:00
parent 19945a6d0b
commit bbb19c38b7
3 changed files with 26 additions and 37 deletions

View File

@ -2,6 +2,7 @@ package bot
import (
"bytes"
"errors"
"io"
"github.com/Tnze/go-mc/chat"
@ -9,7 +10,6 @@ import (
"github.com/Tnze/go-mc/nbt"
"github.com/Tnze/go-mc/net"
pk "github.com/Tnze/go-mc/net/packet"
"github.com/Tnze/go-mc/registry"
)
type ConfigHandler interface {
@ -159,6 +159,11 @@ func (c *Client) joinConfiguration(conn *net.Conn) error {
return ConfigErr{ErrStage, err}
}
registry := c.Registries.Registry(string(registryID))
if registry == nil {
return ConfigErr{ErrStage, errors.New("unknown registry: " + string(registryID))}
}
for i := 0; i < int(length); i++ {
var entryId pk.Identifier
var hasData pk.Boolean
@ -178,7 +183,7 @@ func (c *Client) joinConfiguration(conn *net.Conn) error {
if err != nil {
return ConfigErr{ErrStage, err}
}
err = registry.InsertNBTDataIntoRegistry(&c.Registries, string(registryID), string(entryId), data)
err = registry.InsertWithNBT(string(entryId), data)
if err != nil {
return ConfigErr{ErrStage, err}
}

View File

@ -1,8 +1,6 @@
package registry
import (
"errors"
"fmt"
"reflect"
"github.com/Tnze/go-mc/chat"
@ -58,41 +56,22 @@ type Dimension struct {
MonsterSpawnBlockLightLimit int32 `nbt:"monster_spawn_block_light_limit"`
}
// InsertNBTDataIntoRegistry insert data (entry, data) into the registry.
// The codec should be a pointer of a struct. And the registry should be a field of the codec struct.
//
// This function is a temporary solution while the registry system isn't implemented well.
func InsertNBTDataIntoRegistry(codec any, registry, entry string, data nbt.RawMessage) error {
codecVal := reflect.ValueOf(codec)
if codecVal.Kind() != reflect.Pointer {
return errors.New("codec is not a pointer")
}
codecVal = codecVal.Elem()
if codecVal.Kind() != reflect.Struct {
return errors.New("codec is not a pointer of struct")
}
func (c *NetworkCodec) Registry(id string) RegistryHandler {
codecVal := reflect.ValueOf(c).Elem()
codecTyp := codecVal.Type()
numField := codecVal.NumField()
for i := 0; i < numField; i++ {
registryID, ok := codecTyp.Field(i).Tag.Lookup("registry")
if !ok {
continue
}
if registryID == registry {
fieldVal := codecVal.Field(i).Addr()
args := []reflect.Value{reflect.ValueOf(entry), reflect.ValueOf(data)}
err := fieldVal.MethodByName("InsertNBT").Call(args)[0]
if !err.IsNil() {
return err.Interface().(error)
if registryID == id {
return codecVal.Field(i).Addr().Interface().(RegistryHandler)
}
if registry == "minecraft:chat_type" {
fmt.Println(fieldVal.Interface())
}
return nil
}
}
return errors.New("registry " + registry + " not found in the codec")
}
type RegistryHandler interface {
InsertWithNBT(name string, data nbt.RawMessage) error
}

View File

@ -35,16 +35,21 @@ func (r *Registry[E]) FindByID(id int32) *E {
}
func (r *Registry[E]) Insert(name string, data E) {
r.Value = append(r.Value, Entry[E]{Name: name, Element: data})
entry := Entry[E]{
Name: name,
ID: int32(len(r.Value)),
Element: data,
}
r.Value = append(r.Value, entry)
}
func (r *Registry[E]) InsertNBT(name string, data nbt.RawMessage) error {
entry := Entry[E]{Name: name, ID: int32(len(r.Value))}
func (r *Registry[E]) InsertWithNBT(name string, data nbt.RawMessage) error {
var elem E
if data.Type != 0 {
if err := data.UnmarshalDisallowUnknownField(&entry.Element); err != nil {
if err := data.UnmarshalDisallowUnknownField(&elem); err != nil {
return err
}
}
r.Value = append(r.Value, entry)
r.Insert(name, elem)
return nil
}