Add item DataComponent implements (part 1)

This commit is contained in:
Tnze
2024-07-28 17:52:41 +08:00
parent 966f50eb53
commit 090493c4ac
26 changed files with 860 additions and 256 deletions

View File

@ -1,37 +1,37 @@
package basic
import (
"github.com/Tnze/go-mc/data/packetid"
pk "github.com/Tnze/go-mc/net/packet"
)
func (p *Player) handleCookieRequestPacket(packet pk.Packet) error {
var key pk.Identifier
err := packet.Scan(&key)
if err != nil {
return Error{err}
}
cookieContent := p.c.Cookies[string(key)]
err = p.c.Conn.WritePacket(pk.Marshal(
packetid.ServerboundCookieResponse,
key, pk.OptionEncoder[pk.ByteArray]{
Has: cookieContent != nil,
Val: pk.ByteArray(cookieContent),
},
))
if err != nil {
return Error{err}
}
return nil
}
func (p *Player) handleStoreCookiePacket(packet pk.Packet) error {
var key pk.Identifier
var payload pk.ByteArray
err := packet.Scan(&key, &payload)
if err != nil {
return Error{err}
}
p.c.Cookies[string(key)] = []byte(payload)
return nil
}
package basic
import (
"github.com/Tnze/go-mc/data/packetid"
pk "github.com/Tnze/go-mc/net/packet"
)
func (p *Player) handleCookieRequestPacket(packet pk.Packet) error {
var key pk.Identifier
err := packet.Scan(&key)
if err != nil {
return Error{err}
}
cookieContent := p.c.Cookies[string(key)]
err = p.c.Conn.WritePacket(pk.Marshal(
packetid.ServerboundCookieResponse,
key, pk.OptionEncoder[pk.ByteArray]{
Has: cookieContent != nil,
Val: pk.ByteArray(cookieContent),
},
))
if err != nil {
return Error{err}
}
return nil
}
func (p *Player) handleStoreCookiePacket(packet pk.Packet) error {
var key pk.Identifier
var payload pk.ByteArray
err := packet.Scan(&key, &payload)
if err != nil {
return Error{err}
}
p.c.Cookies[string(key)] = []byte(payload)
return nil
}

View File

@ -1,37 +1,37 @@
package basic
import (
"bytes"
"errors"
pk "github.com/Tnze/go-mc/net/packet"
)
func (p *Player) handleUpdateTags(packet pk.Packet) error {
r := bytes.NewReader(packet.Data)
var length pk.VarInt
_, err := length.ReadFrom(r)
if err != nil {
return Error{err}
}
var registryID pk.Identifier
for i := 0; i < int(length); i++ {
_, err = registryID.ReadFrom(r)
if err != nil {
return Error{err}
}
registry := p.c.Registries.Registry(string(registryID))
if registry == nil {
return Error{errors.New("unknown registry: " + string(registryID))}
}
_, err = registry.ReadTagsFrom(r)
if err != nil {
return Error{err}
}
}
return nil
}
package basic
import (
"bytes"
"errors"
pk "github.com/Tnze/go-mc/net/packet"
)
func (p *Player) handleUpdateTags(packet pk.Packet) error {
r := bytes.NewReader(packet.Data)
var length pk.VarInt
_, err := length.ReadFrom(r)
if err != nil {
return Error{err}
}
var registryID pk.Identifier
for i := 0; i < int(length); i++ {
_, err = registryID.ReadFrom(r)
if err != nil {
return Error{err}
}
registry := p.c.Registries.Registry(string(registryID))
if registry == nil {
return Error{errors.New("unknown registry: " + string(registryID))}
}
_, err = registry.ReadTagsFrom(r)
if err != nil {
return Error{err}
}
}
return nil
}

View File

@ -1,17 +1,17 @@
package bootstrap
import (
"github.com/Tnze/go-mc/data/registryid"
"github.com/Tnze/go-mc/level/block"
"github.com/Tnze/go-mc/registry"
)
func RegisterBlocks(reg *registry.Registry[block.Block]) {
reg.Clear()
for i, key := range registryid.Block {
id, val := reg.Put(key, block.FromID[key])
if int32(i) != id || val == nil || *val == nil {
panic("register blocks failed")
}
}
}
package bootstrap
import (
"github.com/Tnze/go-mc/data/registryid"
"github.com/Tnze/go-mc/level/block"
"github.com/Tnze/go-mc/registry"
)
func RegisterBlocks(reg *registry.Registry[block.Block]) {
reg.Clear()
for i, key := range registryid.Block {
id, val := reg.Put(key, block.FromID[key])
if int32(i) != id || val == nil || *val == nil {
panic("register blocks failed")
}
}
}

View File

@ -0,0 +1,22 @@
package component
import "io"
var _ DataComponent = (*AttributeModifiers)(nil)
type AttributeModifiers struct{}
// ID implements DataComponent.
func (AttributeModifiers) ID() string {
return "minecraft:attribute_modifiers"
}
// ReadFrom implements DataComponent.
func (a *AttributeModifiers) ReadFrom(r io.Reader) (n int64, err error) {
panic("unimplemented")
}
// WriteTo implements DataComponent.
func (a *AttributeModifiers) WriteTo(w io.Writer) (n int64, err error) {
panic("unimplemented")
}

View File

@ -0,0 +1,22 @@
package component
import "io"
var _ DataComponent = (*CanBreak)(nil)
type CanBreak struct{}
// ID implements DataComponent.
func (CanBreak) ID() string {
return "minecraft:can_break"
}
// ReadFrom implements DataComponent.
func (c *CanBreak) ReadFrom(r io.Reader) (n int64, err error) {
panic("unimplemented")
}
// WriteTo implements DataComponent.
func (c *CanBreak) WriteTo(w io.Writer) (n int64, err error) {
panic("unimplemented")
}

View File

@ -0,0 +1,22 @@
package component
import "io"
var _ DataComponent = (*CanPlaceOn)(nil)
type CanPlaceOn struct{}
// ID implements DataComponent.
func (CanPlaceOn) ID() string {
return "minecraft:can_place_on"
}
// ReadFrom implements DataComponent.
func (c *CanPlaceOn) ReadFrom(r io.Reader) (n int64, err error) {
panic("unimplemented")
}
// WriteTo implements DataComponent.
func (c *CanPlaceOn) WriteTo(w io.Writer) (n int64, err error) {
panic("unimplemented")
}

View File

@ -0,0 +1,90 @@
package component
import pk "github.com/Tnze/go-mc/net/packet"
type DataComponent interface {
pk.Field
ID() string
}
func NewComponent(id int32) DataComponent {
switch id {
case 0:
return new(CustomData)
case 1:
return new(MaxStackSize)
case 2:
return new(MaxDamage)
case 3:
return new(Damage)
case 4:
return new(Unbreakable)
case 5:
return new(CustomName)
case 6:
return new(ItemName)
case 7:
return new(Lore)
case 8:
return new(Rarity)
case 9:
return new(Enchantments)
case 10:
return new(CanPlaceOn)
case 11:
return new(CanBreak)
case 12:
return new(AttributeModifiers)
case 13:
return new(CustomModelData)
case 14:
return new(HideAdditionalTooptip)
case 15:
return new(HideTooptip)
case 16:
return new(RepairCost)
case 17:
return new(CreativeSlotLock)
case 18:
case 19:
case 20:
case 21:
case 22:
case 23:
case 24:
case 25:
case 26:
case 27:
case 28:
case 29:
case 30:
case 31:
case 32:
case 33:
case 34:
case 35:
case 36:
case 37:
case 38:
case 39:
case 40:
case 41:
case 42:
case 43:
return new(Recipes)
case 44:
case 45:
case 46:
case 47:
case 48:
case 49:
case 50:
case 51:
case 52:
case 53:
case 54:
case 55:
case 56:
}
return nil
}

View File

@ -0,0 +1,10 @@
package component_test
// func TestNewComponent(t *testing.T) {
// for i, want := range registryid.DataComponentType {
// comp := component.NewComponent(int32(i))
// if got := comp.ID(); got != want {
// t.Errorf("DataComponent type mismatched: %s != %s", got, want)
// }
// }
// }

View File

@ -0,0 +1,24 @@
package component
import (
"io"
)
var _ DataComponent = (*CreativeSlotLock)(nil)
type CreativeSlotLock struct{}
// ID implements DataComponent.
func (c *CreativeSlotLock) ID() string {
return "minecraft:creative_slot_lock"
}
// ReadFrom implements DataComponent.
func (c *CreativeSlotLock) ReadFrom(r io.Reader) (n int64, err error) {
return 0, nil
}
// WriteTo implements DataComponent.
func (c *CreativeSlotLock) WriteTo(w io.Writer) (n int64, err error) {
return 0, nil
}

View File

@ -0,0 +1,29 @@
package component
import (
"io"
"github.com/Tnze/go-mc/nbt/dynbt"
pk "github.com/Tnze/go-mc/net/packet"
)
var _ DataComponent = (*CustomData)(nil)
type CustomData struct {
dynbt.Value
}
// ID implements DataComponent.
func (CustomData) ID() string {
return "minecraft:custom_data"
}
// ReadFrom implements DataComponent.
func (c *CustomData) ReadFrom(r io.Reader) (n int64, err error) {
return pk.NBT(c).ReadFrom(r)
}
// WriteTo implements DataComponent.
func (c *CustomData) WriteTo(w io.Writer) (n int64, err error) {
return pk.NBT(c).WriteTo(w)
}

View File

@ -0,0 +1,28 @@
package component
import (
"io"
pk "github.com/Tnze/go-mc/net/packet"
)
var _ DataComponent = (*CustomModelData)(nil)
type CustomModelData struct {
Value pk.VarInt
}
// ID implements DataComponent.
func (CustomModelData) ID() string {
return "minecraft:custom_model_data"
}
// ReadFrom implements DataComponent.
func (c *CustomModelData) ReadFrom(r io.Reader) (n int64, err error) {
return c.Value.ReadFrom(r)
}
// WriteTo implements DataComponent.
func (c *CustomModelData) WriteTo(w io.Writer) (n int64, err error) {
return c.Value.WriteTo(w)
}

View File

@ -0,0 +1,28 @@
package component
import (
"io"
"github.com/Tnze/go-mc/chat"
)
var _ DataComponent = (*CustomName)(nil)
type CustomName struct {
Name chat.Message
}
// ID implements DataComponent.
func (CustomName) ID() string {
return "minecraft:custom_name"
}
// ReadFrom implements DataComponent.
func (c *CustomName) ReadFrom(r io.Reader) (n int64, err error) {
return c.Name.ReadFrom(r)
}
// WriteTo implements DataComponent.
func (c *CustomName) WriteTo(w io.Writer) (n int64, err error) {
return c.Name.WriteTo(w)
}

28
level/component/damage.go Normal file
View File

@ -0,0 +1,28 @@
package component
import (
"io"
pk "github.com/Tnze/go-mc/net/packet"
)
var _ DataComponent = (*Damage)(nil)
type Damage struct {
Damage pk.VarInt
}
// ID implements DataComponent.
func (Damage) ID() string {
return "minecraft:damage"
}
// ReadFrom implements DataComponent.
func (d *Damage) ReadFrom(r io.Reader) (n int64, err error) {
return d.Damage.ReadFrom(r)
}
// WriteTo implements DataComponent.
func (d *Damage) WriteTo(w io.Writer) (n int64, err error) {
return d.Damage.WriteTo(w)
}

View File

@ -0,0 +1,22 @@
package component
import "io"
var _ DataComponent = (*Enchantments)(nil)
type Enchantments struct{}
// ID implements DataComponent.
func (Enchantments) ID() string {
return "minecraft:enchantments"
}
// ReadFrom implements DataComponent.
func (r *Enchantments) ReadFrom(reader io.Reader) (n int64, err error) {
panic("unimplemented")
}
// WriteTo implements DataComponent.
func (r *Enchantments) WriteTo(writer io.Writer) (n int64, err error) {
panic("unimplemented")
}

View File

@ -0,0 +1,24 @@
package component
import (
"io"
)
var _ DataComponent = (*HideAdditionalTooptip)(nil)
type HideAdditionalTooptip struct{}
// ID implements DataComponent.
func (HideAdditionalTooptip) ID() string {
return "minecraft:hide_additional_tooltip"
}
// ReadFrom implements DataComponent.
func (h *HideAdditionalTooptip) ReadFrom(r io.Reader) (n int64, err error) {
return 0, nil
}
// WriteTo implements DataComponent.
func (h *HideAdditionalTooptip) WriteTo(w io.Writer) (n int64, err error) {
return 0, nil
}

View File

@ -0,0 +1,24 @@
package component
import (
"io"
)
var _ DataComponent = (*HideTooptip)(nil)
type HideTooptip struct{}
// ID implements DataComponent.
func (HideTooptip) ID() string {
return "minecraft:hide_tooltip"
}
// ReadFrom implements DataComponent.
func (h *HideTooptip) ReadFrom(r io.Reader) (n int64, err error) {
return 0, nil
}
// WriteTo implements DataComponent.
func (h *HideTooptip) WriteTo(w io.Writer) (n int64, err error) {
return 0, nil
}

View File

@ -0,0 +1,28 @@
package component
import (
"io"
"github.com/Tnze/go-mc/chat"
)
var _ DataComponent = (*ItemName)(nil)
type ItemName struct {
Name chat.Message
}
// ID implements DataComponent.
func (ItemName) ID() string {
return "minecraft:item_name"
}
// ReadFrom implements DataComponent.
func (i *ItemName) ReadFrom(r io.Reader) (n int64, err error) {
return i.Name.ReadFrom(r)
}
// WriteTo implements DataComponent.
func (i *ItemName) WriteTo(w io.Writer) (n int64, err error) {
return i.Name.WriteTo(w)
}

29
level/component/lore.go Normal file
View File

@ -0,0 +1,29 @@
package component
import (
"io"
"github.com/Tnze/go-mc/chat"
pk "github.com/Tnze/go-mc/net/packet"
)
var _ DataComponent = (*Lore)(nil)
type Lore struct {
Lines []chat.Message
}
// ID implements DataComponent.
func (Lore) ID() string {
return "minecraft:lore"
}
// ReadFrom implements DataComponent.
func (l *Lore) ReadFrom(r io.Reader) (n int64, err error) {
return pk.Array(&l.Lines).ReadFrom(r)
}
// WriteTo implements DataComponent.
func (l *Lore) WriteTo(w io.Writer) (n int64, err error) {
return pk.Array(&l.Lines).WriteTo(w)
}

View File

@ -0,0 +1,28 @@
package component
import (
"io"
pk "github.com/Tnze/go-mc/net/packet"
)
var _ DataComponent = (*MaxDamage)(nil)
type MaxDamage struct {
MaxDamage pk.VarInt
}
// ID implements DataComponent.
func (MaxDamage) ID() string {
return "minecraft:max_damage"
}
// ReadFrom implements DataComponent.
func (m *MaxDamage) ReadFrom(r io.Reader) (n int64, err error) {
return m.MaxDamage.ReadFrom(r)
}
// WriteTo implements DataComponent.
func (m *MaxDamage) WriteTo(w io.Writer) (n int64, err error) {
return m.MaxDamage.WriteTo(w)
}

View File

@ -0,0 +1,28 @@
package component
import (
"io"
pk "github.com/Tnze/go-mc/net/packet"
)
var _ DataComponent = (*MaxStackSize)(nil)
type MaxStackSize struct {
MaxStackSize pk.VarInt
}
// ID implements DataComponent.
func (MaxStackSize) ID() string {
return "minecraft:max_stack_size"
}
// ReadFrom implements DataComponent.
func (m *MaxStackSize) ReadFrom(r io.Reader) (n int64, err error) {
return m.MaxStackSize.ReadFrom(r)
}
// WriteTo implements DataComponent.
func (m *MaxStackSize) WriteTo(w io.Writer) (n int64, err error) {
return m.MaxStackSize.WriteTo(w)
}

33
level/component/rarity.go Normal file
View File

@ -0,0 +1,33 @@
package component
import (
"io"
pk "github.com/Tnze/go-mc/net/packet"
)
var _ DataComponent = (*Rarity)(nil)
type Rarity int32
const (
Common Rarity = iota
Uncommon
Rare
Epic
)
// ID implements DataComponent.
func (Rarity) ID() string {
return "minecraft:rarity"
}
// ReadFrom implements DataComponent.
func (r *Rarity) ReadFrom(reader io.Reader) (n int64, err error) {
return (*pk.VarInt)(r).ReadFrom(reader)
}
// WriteTo implements DataComponent.
func (r *Rarity) WriteTo(writer io.Writer) (n int64, err error) {
return (*pk.VarInt)(r).WriteTo(writer)
}

View File

@ -0,0 +1,29 @@
package component
import (
"io"
"github.com/Tnze/go-mc/nbt/dynbt"
pk "github.com/Tnze/go-mc/net/packet"
)
var _ DataComponent = (*Recipes)(nil)
type Recipes struct {
Data dynbt.Value
}
// ID implements DataComponent.
func (Recipes) ID() string {
return "minecraft:recipes"
}
// ReadFrom implements DataComponent.
func (r *Recipes) ReadFrom(reader io.Reader) (n int64, err error) {
return pk.NBT(&r.Data).ReadFrom(reader)
}
// WriteTo implements DataComponent.
func (r *Recipes) WriteTo(writer io.Writer) (n int64, err error) {
return pk.NBT(&r.Data).WriteTo(writer)
}

View File

@ -0,0 +1,28 @@
package component
import (
"io"
pk "github.com/Tnze/go-mc/net/packet"
)
var _ DataComponent = (*RepairCost)(nil)
type RepairCost struct {
Cost pk.VarInt
}
// ID implements DataComponent.
func (RepairCost) ID() string {
return "minecraft:repair_cost"
}
// ReadFrom implements DataComponent.
func (r *RepairCost) ReadFrom(reader io.Reader) (n int64, err error) {
return r.Cost.ReadFrom(reader)
}
// WriteTo implements DataComponent.
func (r *RepairCost) WriteTo(writer io.Writer) (n int64, err error) {
return r.Cost.WriteTo(writer)
}

View File

@ -0,0 +1,28 @@
package component
import (
"io"
pk "github.com/Tnze/go-mc/net/packet"
)
var _ DataComponent = (*Unbreakable)(nil)
type Unbreakable struct {
ShowInTooltip pk.Boolean
}
// ID implements DataComponent.
func (Unbreakable) ID() string {
return "minecraft:unbreakable"
}
// ReadFrom implements DataComponent.
func (u *Unbreakable) ReadFrom(r io.Reader) (n int64, err error) {
return u.ShowInTooltip.ReadFrom(r)
}
// WriteTo implements DataComponent.
func (u *Unbreakable) WriteTo(w io.Writer) (n int64, err error) {
return u.ShowInTooltip.WriteTo(w)
}

View File

@ -1,93 +1,93 @@
package registry
import (
"errors"
"io"
"strconv"
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
}
func (reg *Registry[E]) ReadTagsFrom(r io.Reader) (int64, error) {
var count pk.VarInt
n, err := count.ReadFrom(r)
if err != nil {
return n, err
}
var tag pk.Identifier
var length pk.VarInt
for i := 0; i < int(count); i++ {
var n1, n2, n3 int64
n1, err = tag.ReadFrom(r)
if err != nil {
return n + n1, err
}
n2, err = length.ReadFrom(r)
if err != nil {
return n + n1 + n2, err
}
n += n1 + n2
values := make([]*E, length)
var id pk.VarInt
for i := 0; i < int(length); i++ {
n3, err = id.ReadFrom(r)
if err != nil {
return n + n3, err
}
if id < 0 || int(id) >= len(reg.values) {
err = errors.New("invalid id: " + strconv.Itoa(int(id)))
return n + n3, err
}
values[i] = &reg.values[id]
n += n3
}
reg.tags[string(tag)] = values
}
return n, nil
}
package registry
import (
"errors"
"io"
"strconv"
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
}
func (reg *Registry[E]) ReadTagsFrom(r io.Reader) (int64, error) {
var count pk.VarInt
n, err := count.ReadFrom(r)
if err != nil {
return n, err
}
var tag pk.Identifier
var length pk.VarInt
for i := 0; i < int(count); i++ {
var n1, n2, n3 int64
n1, err = tag.ReadFrom(r)
if err != nil {
return n + n1, err
}
n2, err = length.ReadFrom(r)
if err != nil {
return n + n1 + n2, err
}
n += n1 + n2
values := make([]*E, length)
var id pk.VarInt
for i := 0; i < int(length); i++ {
n3, err = id.ReadFrom(r)
if err != nil {
return n + n3, err
}
if id < 0 || int(id) >= len(reg.values) {
err = errors.New("invalid id: " + strconv.Itoa(int(id)))
return n + n3, err
}
values[i] = &reg.values[id]
n += n3
}
reg.tags[string(tag)] = values
}
return n, nil
}

View File

@ -1,72 +1,72 @@
package registry
import "slices"
type Registry[E any] struct {
keys map[string]int32
values []E
indices map[*E]int32
tags map[string][]*E
}
func NewRegistry[E any]() Registry[E] {
return Registry[E]{
keys: make(map[string]int32),
values: make([]E, 0, 256),
indices: make(map[*E]int32),
tags: make(map[string][]*E),
}
}
func (r *Registry[E]) Clear() {
r.keys = make(map[string]int32)
r.values = r.values[:0]
r.indices = make(map[*E]int32)
r.tags = make(map[string][]*E)
}
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(key string, data E) (id int32, val *E) {
id = int32(len(r.values))
r.keys[key] = id
r.values = append(r.values, data)
val = &r.values[id]
r.indices[val] = id
return
}
// Tags
func (r *Registry[E]) Tag(tag string) []*E {
return slices.Clone(r.tags[tag])
}
func (r *Registry[E]) ClearTags() {
r.tags = make(map[string][]*E)
}
// func (r *Registry[E]) BindTags(tag string, ids []int32) error {
// values := make([]*E, len(ids))
// for i, id := range ids {
// if id < 0 || id >= int32(len(r.values)) {
// return errors.New("invalid id: " + strconv.Itoa(int(id)))
// }
// values[i] = &r.values[id]
// }
// r.tags[tag] = values
// return nil
// }
package registry
import "slices"
type Registry[E any] struct {
keys map[string]int32
values []E
indices map[*E]int32
tags map[string][]*E
}
func NewRegistry[E any]() Registry[E] {
return Registry[E]{
keys: make(map[string]int32),
values: make([]E, 0, 256),
indices: make(map[*E]int32),
tags: make(map[string][]*E),
}
}
func (r *Registry[E]) Clear() {
r.keys = make(map[string]int32)
r.values = r.values[:0]
r.indices = make(map[*E]int32)
r.tags = make(map[string][]*E)
}
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(key string, data E) (id int32, val *E) {
id = int32(len(r.values))
r.keys[key] = id
r.values = append(r.values, data)
val = &r.values[id]
r.indices[val] = id
return
}
// Tags
func (r *Registry[E]) Tag(tag string) []*E {
return slices.Clone(r.tags[tag])
}
func (r *Registry[E]) ClearTags() {
r.tags = make(map[string][]*E)
}
// func (r *Registry[E]) BindTags(tag string, ids []int32) error {
// values := make([]*E, len(ids))
// for i, id := range ids {
// if id < 0 || id >= int32(len(r.values)) {
// return errors.New("invalid id: " + strconv.Itoa(int(id)))
// }
// values[i] = &r.values[id]
// }
// r.tags[tag] = values
// return nil
// }