Add registry implement

This commit is contained in:
Tnze
2024-07-27 22:48:40 +08:00
parent 300304eed3
commit d88ee401fd
7 changed files with 118 additions and 99 deletions

View File

@ -21,6 +21,22 @@ type NetworkCodec struct {
JukeboxSong Registry[nbt.RawMessage] `registry:"minecraft:jukebox_song"`
}
func NewNetworkCodec() NetworkCodec {
return NetworkCodec{
ChatType: NewRegistry[ChatType](),
DamageType: NewRegistry[DamageType](),
DimensionType: NewRegistry[Dimension](),
TrimMaterial: NewRegistry[nbt.RawMessage](),
TrimPattern: NewRegistry[nbt.RawMessage](),
WorldGenBiome: NewRegistry[nbt.RawMessage](),
Wolfvariant: NewRegistry[nbt.RawMessage](),
PaintingVariant: NewRegistry[nbt.RawMessage](),
BannerPattern: NewRegistry[nbt.RawMessage](),
Enchantment: NewRegistry[nbt.RawMessage](),
JukeboxSong: NewRegistry[nbt.RawMessage](),
}
}
type ChatType struct {
Chat chat.Decoration `nbt:"chat"`
Narration chat.Decoration `nbt:"narration"`
@ -56,7 +72,7 @@ type Dimension struct {
MonsterSpawnBlockLightLimit int32 `nbt:"monster_spawn_block_light_limit"`
}
func (c *NetworkCodec) Registry(id string) RegistryHandler {
func (c *NetworkCodec) Registry(id string) any {
codecVal := reflect.ValueOf(c).Elem()
codecTyp := codecVal.Type()
numField := codecVal.NumField()
@ -66,12 +82,8 @@ func (c *NetworkCodec) Registry(id string) RegistryHandler {
continue
}
if registryID == id {
return codecVal.Field(i).Addr().Interface().(RegistryHandler)
return codecVal.Field(i).Addr().Interface()
}
}
return nil
}
type RegistryHandler interface {
InsertWithNBT(name string, data nbt.RawMessage) error
}

46
registry/network.go Normal file
View File

@ -0,0 +1,46 @@
package registry
import (
"io"
pk "github.com/Tnze/go-mc/net/packet"
)
func (reg *Registry[E]) ReadFrom(r io.Reader) (int64, error) {
var length pk.VarInt
n, err := length.ReadFrom(r)
if err != nil {
return n, err
}
reg.Clear()
var key pk.Identifier
var hasData pk.Boolean
for i := 0; i < int(length); i++ {
var data E
var n1, n2, n3 int64
n1, err = key.ReadFrom(r)
if err != nil {
return n + n1, err
}
n2, err = hasData.ReadFrom(r)
if err != nil {
return n + n1 + n2, err
}
if hasData {
n3, err = pk.NBTField{V:&data, AllowUnknownFields: true}.ReadFrom(r)
if err != nil {
return n + n1 + n2 + n3, err
}
reg.Put(string(key), data)
}
n += n1 + n2 + n3
}
return n, nil
}

View File

@ -1,55 +1,45 @@
package registry
import "github.com/Tnze/go-mc/nbt"
type Registry[E any] struct {
Type string `nbt:"type"`
Value []Entry[E] `nbt:"value"`
}
type Entry[E any] struct {
Name string `nbt:"name"`
ID int32 `nbt:"id"`
Element E `nbt:"element"`
}
func (r *Registry[E]) Find(name string) (int32, *E) {
for i := range r.Value {
if r.Value[i].Name == name {
return int32(i), &r.Value[i].Element
}
}
return -1, nil
}
func (r *Registry[E]) FindByID(id int32) *E {
if id >= 0 && id < int32(len(r.Value)) && r.Value[id].ID == id {
return &r.Value[id].Element
}
for i := range r.Value {
if r.Value[i].ID == id {
return &r.Value[i].Element
}
}
return nil
}
func (r *Registry[E]) Insert(name string, data E) {
entry := Entry[E]{
Name: name,
ID: int32(len(r.Value)),
Element: data,
}
r.Value = append(r.Value, entry)
}
func (r *Registry[E]) InsertWithNBT(name string, data nbt.RawMessage) error {
var elem E
if data.Type != 0 {
if err := data.UnmarshalDisallowUnknownField(&elem); err != nil {
return err
}
}
r.Insert(name, elem)
return nil
}
package registry
type Registry[E any] struct {
keys map[string]int32
values []E
indices map[*E]int32
}
func NewRegistry[E any]() Registry[E] {
return Registry[E]{
keys: make(map[string]int32),
values: make([]E, 0, 256),
indices: make(map[*E]int32),
}
}
func (r *Registry[E]) Get(key string) (int32, *E) {
id, ok := r.keys[key]
if !ok {
return -1, nil
}
return id, &r.values[id]
}
func (r *Registry[E]) GetByID(id int32) *E {
if id >= 0 && id < int32(len(r.values)) {
return &r.values[id]
}
return nil
}
func (r *Registry[E]) Put(name string, data E) (id int32, val *E) {
id = int32(len(r.values))
r.keys[name] = id
r.values = append(r.values, data)
val = &r.values[id]
r.indices[val] = id
return
}
func (r *Registry[E]) Clear() {
r.keys = make(map[string]int32)
r.values = r.values[:0]
r.indices = make(map[*E]int32)
}