entity

package
v1.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 14, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Example (GeneratedEntityFactory)
package main

import (
	"fmt"
	"github.com/tjbdwanghaibo/cube-core/checkpoint"
	"github.com/tjbdwanghaibo/cube-core/entity"
	"sync"
)

// ============================================================
// Below simulates what CODE GENERATION would produce.
// The generator scans entity/component/DAO definitions and
// outputs a factory file per entity category.
// ============================================================

// --- DAO definition (手写) ---

type PlayerDao struct {
	id    int64
	coll  string
	dirty checkpoint.DirtyTracker
	Name  string
	Level int
}

func (d *PlayerDao) Id() int64            { return d.id }
func (d *PlayerDao) SetId(id int64)       { d.id = id }
func (d *PlayerDao) DbName() string       { return "game" }
func (d *PlayerDao) CollName() string     { return d.coll }
func (d *PlayerDao) Dirty() entity.IDirty { return &d.dirty }
func (d *PlayerDao) CleanDirty()          { d.dirty.SelfClean() }

// --- Component definition (手写) ---

type BagComponent struct {
	player *Player // 直接引用具体类型,不是 interface
	items  map[int64]int
}

func (b *BagComponent) Name() string                                           { return "bag" }
func (b *BagComponent) OnInitFinish(_ *entity.EntityCreateParam, _ bool) error { return nil }
func (b *BagComponent) OnDestroy(_ entity.EntityDestroyReason)                 {}

func (b *BagComponent) AddItem(id int64, count int) {
	b.items[id] += count
	b.player.dao.dirty.MarkScope(checkpoint.DirtyPersist|checkpoint.DirtySync, checkpoint.DirtyAll)
}

// --- Entity definition (手写,只定义结构) ---

type Player struct {
	*entity.EntityBase
	entity.ComponentManager
	entity.DaoManager

	// 具体类型字段(由生成代码赋值)
	bag *BagComponent
	dao *PlayerDao
}

func (p *Player) Base() *entity.EntityBase { return p.EntityBase }

// ============================================================
// gen_player.go — 以下全部由代码生成器产生
// ============================================================

func NewPlayer(param *entity.EntityCreateParam) (*Player, error) {
	p := &Player{}
	if err := param.NormalizeID(param.Kind); err != nil {
		return nil, err
	}

	// 1. 初始化 EntityBase(指针嵌入,无 interface 引用)
	p.EntityBase = entity.NewEntityBase(param.Id, param.Category, false, param.Kind)
	p.EntityBase.SetHooks(
		func() { // onClear
			p.ComponentManager.Clear()
			p.DaoManager.Clear()
			p.bag = nil
			p.dao = nil
		},
		func(reason entity.EntityDestroyReason) { // onDestroy
			p.ComponentManager.DestroyAll(reason)
		},
	)

	// 2. 初始化 managers
	p.ComponentManager = entity.NewComponentManager()
	p.DaoManager = entity.NewDaoManager()

	// 3. 绑定 DAO(具体类型,从 param 中 type assert)
	if daoRaw, ok := param.Dao["players"]; ok {
		p.dao = daoRaw.(*PlayerDao)
	} else {
		p.dao = &PlayerDao{id: param.StorageID(), coll: "players"}
	}
	p.DaoManager.Set("players", p.dao)

	// 4. 创建 Component(直接传具体类型指针)
	p.bag = &BagComponent{
		player: p,
		items:  make(map[int64]int),
	}
	p.ComponentManager.Set(1, p.bag) // ComponentType = 1 for bag

	// 5. 初始化所有 component(按拓扑排序)
	if err := p.ComponentManager.InitAll(param, param.IsCreate); err != nil {
		return nil, err
	}

	return p, nil
}

// ============================================================
// Snapshot 方法(生成代码产出,配合 checkpoint)
// ============================================================

func (p *Player) Snapshot() []checkpoint.SaveItem {
	mask := p.dao.dirty.TakePersistDirty()
	if mask == 0 {
		return nil
	}
	ver := p.dao.dirty.IncVersion()
	// 序列化 DAO(实际用 BSON/MessagePack)
	data := []byte(fmt.Sprintf(`{"name":"%s","level":%d}`, p.dao.Name, p.dao.Level))
	return []checkpoint.SaveItem{
		{
			Collection: p.dao.CollName(),
			ID:         p.dao.Id(),
			Version:    ver,
			Mask:       mask,
			Data:       data,
			Tracker:    &p.dao.dirty,
		},
	}
}

// ============================================================
// Example: 展示完整流程
// ============================================================

func main() {
	entity.MustRegisterEntityKindCategory(entity.EntityKind(1), entity.EntityCategory(1))
	param := &entity.EntityCreateParam{
		IsCreate: true,
		UniqueID: 10001,
		Kind:     entity.EntityKind(1),
		Dao:      make(map[string]entity.DaoInterface),
	}

	// 生成代码创建 entity
	player, err := NewPlayer(param)
	if err != nil {
		panic(err)
	}

	// 业务逻辑:直接操作具体类型
	player.bag.AddItem(1001, 5)

	// checkpoint: guard release 时调用 Snapshot
	items := player.Snapshot()
	fmt.Printf("entity_id=%d, storage_id=%d, snapshot_items=%d, version=%d\n",
		player.ID(), player.StorageID(), len(items), items[0].Version)

	// Touch/UnTouch 生命周期
	player.Touch()
	fmt.Printf("touched, removed=%v\n", player.IsRemoved())
	player.UnTouch()

	// Guard 使用
	guard := entity.GetEntityGuard()
	ok := guard.RequireEntity(player)
	fmt.Printf("guard_acquired=%v\n", ok)
	guard.ReleaseAll()
	entity.EntityGuardRelease(guard)

	// Verify no IThreadSafeEntity stored in EntityBase
	_ = player.Base().GetMutex()
	fmt.Println("no interface reference in EntityBase")

	_ = sync.Mutex{}

}
Output:
entity_id=10241029, storage_id=10241029, snapshot_items=1, version=1
touched, removed=false
guard_acquired=true
no interface reference in EntityBase

Index

Examples

Constants

View Source
const (
	EntityGroupPlayer = iota
	EntityGroupAlliance
	EntityGroupRemote
	EntityGroupOther
	EntityGroupCnt
)

Entity group constants for lock ordering (deadlock prevention).

View Source
const (
	IDGenOffsetBits = 20
	IDGenBlockSize  = uint64(1) << IDGenOffsetBits

	UniqueIDBits        = 52
	UniqueIDMask        = (uint64(1) << UniqueIDBits) - 1
	StaticUniqueIDBase  = uint64(1) << (UniqueIDBits - 1)
	DynamicUniqueIDMask = StaticUniqueIDBase - 1
	MaxBlockNo          = DynamicUniqueIDMask >> IDGenOffsetBits
)

IDGen generates the dynamic portion of EntityID.

Layout:

unique 52 bits = [blockNo][offset]

The default offset width is 20 bits, so each acquired block provides 1,048,576 local IDs. The block number should be allocated globally and monotonically, for example by Redis INCR minus one or an etcd transaction. This keeps early IDs compact because block 0 starts at unique 1; unique 0 is reserved as an invalid/empty value for all full EntityIDs. The upper half of the 52-bit unique range is reserved for explicit static IDs.

View Source
const (
	EntityCategoryBits = 2
	EntityKindBits     = 8
	EntityRemoteBits   = 1
	EntityIDTagBits    = EntityCategoryBits + EntityKindBits

	EntityCategoryMask = (uint64(1) << EntityCategoryBits) - 1
	EntityKindMask     = (uint64(1) << EntityKindBits) - 1
	EntityRemoteMask   = (uint64(1) << EntityRemoteBits) - 1

	EntityKindShift    = EntityCategoryBits
	UniqueIDShift      = EntityIDTagBits
	EntityRemoteShift  = UniqueIDShift + UniqueIDBits
	EntityIDValueBits  = UniqueIDBits + EntityIDTagBits + EntityRemoteBits // 63 bits, positive int64
	EntityIDValueMask  = (uint64(1) << EntityIDValueBits) - 1
	MaxEntityKindValue = EntityKindMask
)

EntityID layout in positive int64:

[sign(1)=0][remote(1)][unique(52)][kind(8)][category(2)]
View Source
const (
	SyncFullReasonNone uint32 = iota
	SyncFullReasonDirty
	SyncFullReasonResync
	SyncFullReasonObserver
	SyncFullReasonSchema
)
View Source
const SyncMaskFull uint64 = ^uint64(0)

Variables

View Source
var (
	ErrEntityNil        = errors.New("entity manager: nil entity")
	ErrEntityRemoved    = errors.New("entity manager: entity removed")
	ErrEntityExists     = errors.New("entity manager: entity already exists")
	ErrEntityNotManaged = errors.New("entity manager: entity not managed")
)
View Source
var (
	ErrInvalidBlockNo    = errors.New("idgen: block number exceeds 52-bit unique range")
	ErrBlockExhausted    = errors.New("idgen: current block exhausted and no block allocator configured")
	ErrNoBlockSource     = errors.New("idgen: no initial block or block allocator configured")
	ErrInvalidCategory   = errors.New("entity id: category exceeds 2-bit limit")
	ErrInvalidEntityKind = errors.New("entity id: kind exceeds 8-bit limit")
	ErrInvalidEntityID   = errors.New("entity id: invalid")
)
View Source
var ErrRemoteSnapshotStale = errors.New("remote snapshot stale")
View Source
var GenerateID func() (uint64, error)

GenerateID is the global ID generator function. Must be set by the application layer before creating entities.

View Source
var GetEntityGroupFunc func(category EntityCategory) int

GetEntityGroupFunc is the application-level hook that maps an EntityCategory to an entity group. If nil, all non-remote entities fall into EntityGroupOther.

View Source
var SendMsg func(msg any)

SendMsg is a hook set by the nest package to dispatch messages from entity context.

Functions

func BindRemoteEntityManager added in v1.0.1

func BindRemoteEntityManager(mgr IRemoteEntityManager)

BindRemoteEntityManager wires IRemoteEntityManager into framework hooks. Called by RemoteEntityMod during Start().

func BuildEntityID added in v1.0.1

func BuildEntityID(uniqueID int64, kind EntityKind) (int64, error)

func DestroyEntity

func DestroyEntity(e IThreadSafeEntity, reason EntityDestroyReason, deleteFromDB bool)

DestroyEntity removes an entity from the manager and cleans up. If deleteFromDB is true, a delete operation is pushed to the checkpoint journal.

func EncodeRemoteSyncPayload added in v1.0.1

func EncodeRemoteSyncPayload(collection string, data []byte) ([]byte, error)

func EntityGuardRelease

func EntityGuardRelease(guard *EntityGuard)

EntityGuardRelease releases the guard. If the guard is owned by the current scope, it's a no-op (scope release handles it). Otherwise, releases immediately.

func GetEntityGroup

func GetEntityGroup(guid int64) int

GetEntityGroup extracts entity group from GUId for lock ordering.

func GetEntityRemoteFromID added in v1.0.1

func GetEntityRemoteFromID(id int64) bool

func GetUniqueIDFromEntityID added in v1.0.1

func GetUniqueIDFromEntityID(id int64) int64

func IsEntityKindRemoteCapable

func IsEntityKindRemoteCapable(kind EntityKind) bool

func IsEntityKindRemoteManaged

func IsEntityKindRemoteManaged(kind EntityKind) bool

func IsRemoteCapableEntityID added in v1.0.1

func IsRemoteCapableEntityID(id int64) bool

IsRemoteCapableEntityID returns whether the EntityID carries the remote-capable identity. EntityKind registration is authoritative when it is available; the remote bit is the wire/storage hint for processes that only have the ID.

func IsRemoteManagedMarkedEntityID added in v1.0.1

func IsRemoteManagedMarkedEntityID(id int64) bool

func IsRemoteMarkedEntityID added in v1.0.1

func IsRemoteMarkedEntityID(id int64) bool

func LoadDaoOnDemand added in v1.0.1

func LoadDaoOnDemand(ctx context.Context, collection string, storageID int64, dao DaoInterface) (bool, error)

func MatchEntityID added in v1.0.1

func MatchEntityID(id int64, kind EntityKind) bool

func MustRegisterEntityKindCategories

func MustRegisterEntityKindCategories(defs ...EntityKindCategory)

func MustRegisterEntityKindCategory

func MustRegisterEntityKindCategory(kind EntityKind, category EntityCategory)

func MustRegisterEntityKindDefs

func MustRegisterEntityKindDefs(defs ...EntityKindDef)

func NormalizeFullID added in v1.0.1

func NormalizeFullID(id int64, kind EntityKind) (int64, error)

func ParseUniqueID added in v1.0.1

func ParseUniqueID(id uint64) (blockNo uint64, offset uint64)

func PrepareRemoteEntities added in v1.0.1

func PrepareRemoteEntities(ids []int64) (func(), bool, error)

func RegisterComponentDependency

func RegisterComponentDependency(compType ComponentType, dependencies ...ComponentType)

RegisterComponentDependency declares that a component type depends on others. This determines initialization order. Call from the service bootstrap path.

func RegisterComponentFactory

func RegisterComponentFactory(compType ComponentType, factory ComponentFactory)

RegisterComponentFactory registers a global factory for a component type. Call from the service bootstrap path. Panics on duplicate registration.

func RegisterEntityBuilder

func RegisterEntityBuilder(param *EntityBuilderParam)

RegisterEntityBuilder registers a builder for a concrete entity kind. Call from the service bootstrap path. Panics on duplicate.

func RegisterEntityKindCategories

func RegisterEntityKindCategories(defs ...EntityKindCategory) error

func RegisterEntityKindCategory

func RegisterEntityKindCategory(kind EntityKind, category EntityCategory) error

func RegisterEntityKindDefs

func RegisterEntityKindDefs(defs ...EntityKindDef) error

func RegisterOnEntityRelease

func RegisterOnEntityRelease(hook func(IThreadSafeEntity)) func()

func RegisterOnEntityRemoveFromDB

func RegisterOnEntityRemoveFromDB(hook func(IThreadSafeEntity)) func()

func RemoteSnapshotExpiresAt added in v1.0.1

func RemoteSnapshotExpiresAt(readAt int64, option RemoteReadOption) int64

func RemoteSnapshotReadAt added in v1.0.1

func RemoteSnapshotReadAt(option RemoteReadOption) int64

func ResetComponentRegistryForTest

func ResetComponentRegistryForTest()

func ResetEntityRegistryForTest

func ResetEntityRegistryForTest()

func SetEntitySyncScheduler

func SetEntitySyncScheduler(scheduler EntitySyncScheduler)

func SetEntitySyncSink

func SetEntitySyncSink(sink EntitySyncSink)

func SetOnDemandDaoLoader added in v1.0.1

func SetOnDemandDaoLoader(fn OnDemandDaoLoadFunc) func()

func SetOnDemandEntityLoader added in v1.0.1

func SetOnDemandEntityLoader(fn OnDemandEntityLoadFunc) func()

func UnbindRemoteEntityManager added in v1.0.1

func UnbindRemoteEntityManager(mgr IRemoteEntityManager)

func ValidateEntityPolicy added in v1.0.1

func ValidateEntityPolicy(kind EntityKind, noPersist bool, remotePolicy RemotePolicy, lifetime EntityLifetime) error

func WithGuardScope

func WithGuardScope(name string, fn func(*GuardScope) error) error

Types

type ComponentBase added in v1.0.1

type ComponentBase struct{}

ComponentBase is the default base implementation of ComponentInterfaceBase. Embed this in concrete component structs to get no-op defaults.

func (*ComponentBase) Name added in v1.0.1

func (b *ComponentBase) Name() string

func (*ComponentBase) OnDestroy added in v1.0.1

func (b *ComponentBase) OnDestroy(rea EntityDestroyReason)

func (*ComponentBase) OnInitFinish added in v1.0.1

func (b *ComponentBase) OnInitFinish(param *EntityCreateParam, isCreate bool) error

type ComponentFactory

type ComponentFactory func(owner any, param *EntityCreateParam) (ComponentInterfaceBase, error)

ComponentFactory creates a component instance. The owner is passed as `any` (concrete entity pointer); the factory does type assertion internally.

type ComponentInterfaceBase

type ComponentInterfaceBase interface {
	Name() string
	OnInitFinish(param *EntityCreateParam, isCreate bool) error
	OnDestroy(rea EntityDestroyReason)
}

ComponentInterfaceBase is the minimal component interface.

func CreateComponent

func CreateComponent(compType ComponentType, owner any, param *EntityCreateParam) (ComponentInterfaceBase, error)

CreateComponent invokes the registered factory for the given component type.

type ComponentManager

type ComponentManager struct {
	Comps map[ComponentType]ComponentInterfaceBase
	// contains filtered or unexported fields
}

ComponentManager is a simple container for components. No owner reference — wiring is done by generated code.

func NewComponentManager

func NewComponentManager() ComponentManager

func (*ComponentManager) Clear

func (c *ComponentManager) Clear()

Clear releases all component references.

func (*ComponentManager) DestroyAll

func (c *ComponentManager) DestroyAll(reason EntityDestroyReason)

DestroyAll calls OnDestroy on all components.

func (*ComponentManager) Get

Get retrieves a component by type.

func (*ComponentManager) InitAll

func (c *ComponentManager) InitAll(param *EntityCreateParam, isCreate bool) error

InitAll initializes all components in topological order.

func (*ComponentManager) Set

func (c *ComponentManager) Set(compType ComponentType, comp ComponentInterfaceBase)

Set registers a component. Called by generated code.

type ComponentType added in v1.0.1

type ComponentType uint16

ComponentType identifies component type within an entity.

func GetTopologicalSortedComponents added in v1.0.1

func GetTopologicalSortedComponents() ([]ComponentType, error)

GetTopologicalSortedComponents returns components in dependency order.

type DaoBuilderFunc

type DaoBuilderFunc func() DaoInterface

DaoBuilderFunc creates a new DAO instance.

type DaoInterface

type DaoInterface interface {
	Id() int64
	SetId(int64)
	DbName() string
	CollName() string
	Dirty() IDirty
	CleanDirty()
}

DaoInterface is the DAO contract for entity persistence.

type DaoManager

type DaoManager struct {
	Daos map[string]DaoInterface
}

DaoManager holds DAO instances by collection name. No owner reference — wiring is done by generated code.

func NewDaoManager

func NewDaoManager() DaoManager

func (*DaoManager) Clear

func (d *DaoManager) Clear()

Clear releases all DAO references.

func (*DaoManager) Get

func (d *DaoManager) Get(collName string) DaoInterface

Get retrieves a DAO by collection name.

func (*DaoManager) RangeDao

func (d *DaoManager) RangeDao(f func(DaoInterface))

RangeDao iterates all DAOs.

func (*DaoManager) Set

func (d *DaoManager) Set(collName string, dao DaoInterface)

Set registers a DAO. Called by generated code.

type EntityBase

type EntityBase struct {
	// contains filtered or unexported fields
}

EntityBase is the core entity infrastructure. It holds identity, lifecycle state, and reference counting. No interface references — all wiring is done via generated code.

func NewEntityBase

func NewEntityBase(id int64, category EntityCategory, notAutoPersist bool, kinds ...EntityKind) *EntityBase

NewEntityBase creates an EntityBase. The id must be a full EntityID; use EntityCreateParam.NormalizeID at construction boundaries that still receive a generated unique ID. Hooks are set separately via SetHooks. The mutex is obtained from lock.Mgr if set, otherwise a default reentrant mutex is created.

func (*EntityBase) AutoPersist

func (e *EntityBase) AutoPersist() bool

func (*EntityBase) BeginGroupTransition added in v1.0.1

func (e *EntityBase) BeginGroupTransition(state EntityGroupTransitionState, targetGroupID int64) bool

func (*EntityBase) ClearBase

func (e *EntityBase) ClearBase()

ClearBase tries to clear internal state via CAS on clearedBit. Called explicitly when an entity is destroyed without going through UnTouch.

func (*EntityBase) ClearGroupTransition added in v1.0.1

func (e *EntityBase) ClearGroupTransition()

func (*EntityBase) DestroyAll

func (e *EntityBase) DestroyAll(reason EntityDestroyReason)

DestroyAll invokes the destroy hook (for components cleanup).

func (*EntityBase) EnableSync

func (e *EntityBase) EnableSync(param EntitySyncCreateParam)

EnableSync wires entity-level sync state. It is intentionally not a component: sync visibility and dirty flushing belong to the entity's base lifecycle.

func (*EntityBase) EventBus

func (e *EntityBase) EventBus() *event.EventBus

EventBus returns the entity's event bus.

func (*EntityBase) FlushSync

func (e *EntityBase) FlushSync() []SyncPacket

func (*EntityBase) FlushSyncTo

func (e *EntityBase) FlushSyncTo(sink EntitySyncSink) []SyncPacket

func (*EntityBase) GUId

func (e *EntityBase) GUId() int64

func (*EntityBase) GetEntityCategory

func (e *EntityBase) GetEntityCategory() EntityCategory

func (*EntityBase) GetEntityKind

func (e *EntityBase) GetEntityKind() EntityKind

func (*EntityBase) GetMutex

func (e *EntityBase) GetMutex() lock.Mutex

func (*EntityBase) GroupEpoch added in v1.0.1

func (e *EntityBase) GroupEpoch() uint64

GroupEpoch changes whenever the entity lock-group membership changes.

func (*EntityBase) GroupLockID added in v1.0.1

func (e *EntityBase) GroupLockID() int64

GroupLockID returns the entity lock group ID. Zero means the entity is serialized by its own entity mutex.

func (*EntityBase) GroupTransitionPending added in v1.0.1

func (e *EntityBase) GroupTransitionPending() bool

func (*EntityBase) GroupTransitionState added in v1.0.1

func (e *EntityBase) GroupTransitionState() EntityGroupTransitionState

func (*EntityBase) GroupTransitionTargetID added in v1.0.1

func (e *EntityBase) GroupTransitionTargetID() int64

func (*EntityBase) ID

func (e *EntityBase) ID() int64

func (*EntityBase) IsClear

func (e *EntityBase) IsClear() bool

func (*EntityBase) IsRemoved

func (e *EntityBase) IsRemoved() bool

func (*EntityBase) Lifetime

func (e *EntityBase) Lifetime() EntityLifetime

func (*EntityBase) MarkSyncDirty

func (e *EntityBase) MarkSyncDirty(mask uint64)

func (*EntityBase) MarkSyncFullDirty

func (e *EntityBase) MarkSyncFullDirty(reason uint32)

func (*EntityBase) OnDestroy

func (e *EntityBase) OnDestroy(reason EntityDestroyReason)

OnDestroy is the default no-op implementation. Override in concrete entity for cleanup logic on removal.

func (*EntityBase) OnInitFinish

func (e *EntityBase) OnInitFinish(param *EntityCreateParam) error

OnInitFinish is the default no-op implementation. Override in concrete entity for post-initialization logic.

func (*EntityBase) PubEvent

func (e *EntityBase) PubEvent(d event.EventData)

PubEvent publishes an event via the entity's event bus.

func (*EntityBase) SetEventBus

func (e *EntityBase) SetEventBus(bus *event.EventBus)

SetEventBus wires the event bus. Called by generated factory code or application layer.

func (*EntityBase) SetGroupLockIDForTest added in v1.0.1

func (e *EntityBase) SetGroupLockIDForTest(groupID int64)

SetGroupLockIDForTest sets the lock group directly. Production code should use EntityManager.UpdateEntityGroup so the group index stays in sync.

func (*EntityBase) SetHooks

func (e *EntityBase) SetHooks(onClear func(), onDestroy func(EntityDestroyReason))

SetHooks configures lifecycle callbacks. Called by generated factory code.

func (*EntityBase) SetID

func (e *EntityBase) SetID(id int64)

func (*EntityBase) SetLifetime

func (e *EntityBase) SetLifetime(lifetime EntityLifetime)

func (*EntityBase) SetRemoved

func (e *EntityBase) SetRemoved()

func (*EntityBase) SetSyncState

func (e *EntityBase) SetSyncState(syncState *EntitySyncState)

func (*EntityBase) StorageID

func (e *EntityBase) StorageID() int64

func (*EntityBase) SubEvent

func (e *EntityBase) SubEvent(eventType event.EventType)

SubEvent subscribes to an event type via the entity's event bus.

func (*EntityBase) Sync

func (e *EntityBase) Sync() *EntitySyncState

func (*EntityBase) SyncEnabled

func (e *EntityBase) SyncEnabled() bool

func (*EntityBase) Touch

func (e *EntityBase) Touch() bool

Touch atomically increments reference count. Returns false if removed or cleared.

func (*EntityBase) UnTouch

func (e *EntityBase) UnTouch()

UnTouch atomically decrements reference count. Triggers clear if removed and count reaches zero.

func (*EntityBase) UniqueID

func (e *EntityBase) UniqueID() int64

type EntityBuilderFunc

type EntityBuilderFunc func(param *EntityCreateParam) (IThreadSafeEntity, error)

EntityBuilderFunc creates an entity from params. The returned entity must satisfy IThreadSafeEntity.

type EntityBuilderParam

type EntityBuilderParam struct {
	Category     EntityCategory    // ownership/access category
	Kind         EntityKind        // concrete entity definition
	Builder      EntityBuilderFunc // entity constructor (generated NewXxx)
	DaoBuilders  []DaoBuilderFunc  // DAO factories (one per DAO in entity)
	LoadPriority int               // lower = load first
	NoPersist    bool              // skip auto-persist
	RemotePolicy RemotePolicy      // explicit cross-server policy
	Lifetime     EntityLifetime    // memory/persistence lifecycle policy
	Sync         EntitySyncBuilderParam
}

EntityBuilderParam holds the builder configuration for a concrete entity kind.

func GetAllEntityBuilders

func GetAllEntityBuilders() []*EntityBuilderParam

GetAllEntityBuilders returns all registered builders.

func GetEntityBuilderParam

func GetEntityBuilderParam(kind EntityKind) *EntityBuilderParam

GetEntityBuilderParam retrieves the registered builder for an entity kind.

func (*EntityBuilderParam) IsRemoteCapable

func (param *EntityBuilderParam) IsRemoteCapable() bool

type EntityCategory added in v1.0.1

type EntityCategory uint8

EntityCategory identifies ownership/access category. It is encoded in the low 2 bits of EntityID.

const (
	EntityCategoryNone EntityCategory = 0
)

func EntityCategoryOfKind added in v1.0.1

func EntityCategoryOfKind(kind EntityKind) (EntityCategory, bool)

func GetEntityCategoryFromID added in v1.0.1

func GetEntityCategoryFromID(id int64) EntityCategory

func MustEntityCategoryOfKind added in v1.0.1

func MustEntityCategoryOfKind(kind EntityKind) EntityCategory

func ResolveEntityKindCategory added in v1.0.1

func ResolveEntityKindCategory(kind EntityKind) (EntityCategory, error)

type EntityCreateParam

type EntityCreateParam struct {
	IsCreate bool
	Category EntityCategory
	Kind     EntityKind
	// Id is normalized to the full EntityID before the entity is built.
	// Explicit Id values must already be full EntityIDs. Use UniqueID only at
	// entity creation/loading boundaries that own raw unique-number generation.
	Id             int64
	UniqueID       int64
	OwnerId        int64
	OwnerCategory  EntityCategory
	BelongId       int64
	BelongCategory EntityCategory
	ExclusiveId    int64
	Lifetime       EntityLifetime
	Dao            map[string]DaoInterface
	Sync           *EntitySyncCreateParam
	Param          any
}

EntityCreateParam holds parameters for entity creation.

func (*EntityCreateParam) FullID

func (param *EntityCreateParam) FullID() int64

func (*EntityCreateParam) NormalizeID

func (param *EntityCreateParam) NormalizeID(kind EntityKind) error

func (*EntityCreateParam) StorageID

func (param *EntityCreateParam) StorageID() int64

type EntityDestroyReason added in v1.0.1

type EntityDestroyReason uint8

EntityDestroyReason describes why an entity is being destroyed.

const (
	// DestroyReasonCommon is the neutral default reason for infrastructure-level
	// entity removal. Business packages may alias it with domain-specific names.
	DestroyReasonCommon EntityDestroyReason = 0
)

type EntityGroupTransitionState added in v1.0.1

type EntityGroupTransitionState int32

EntityGroupTransitionState describes a pending framework-level lock-group transition. It is a dispatch gate, not a lock.

const (
	EntityGroupTransitionNone EntityGroupTransitionState = iota
	EntityGroupTransitionJoin
	EntityGroupTransitionLeave
	EntityGroupTransitionMove
)

type EntityGuard

type EntityGuard struct {
	// contains filtered or unexported fields
}

EntityGuard manages per-goroutine entity locks with priority-based deadlock avoidance.

func GetEntityGuard

func GetEntityGuard() *EntityGuard

GetEntityGuard returns the EntityGuard for the current entity guard scope. Without a scope, callers receive a standalone guard and must release it.

func (*EntityGuard) AppendPostRelease

func (e *EntityGuard) AppendPostRelease(f func())

func (*EntityGuard) CheckContainAllLock

func (e *EntityGuard) CheckContainAllLock(es []IThreadSafeEntity) bool

CheckContainAllLock checks if all entities in es are already locked or safe to lock. Lock order follows the application group order from lower value to higher value. In cube this means Player -> Alliance -> Other. Once a later group is held, callers must not acquire an earlier or same-level group through cast.

func (*EntityGuard) Entities

func (e *EntityGuard) Entities() map[int64]IThreadSafeEntity

Entities returns all currently guarded entities.

func (*EntityGuard) GuardEntity

func (e *EntityGuard) GuardEntity(ent IThreadSafeEntity)

func (*EntityGuard) ReleaseAll

func (e *EntityGuard) ReleaseAll()

func (*EntityGuard) ReleaseEntity

func (e *EntityGuard) ReleaseEntity(id int64)

func (*EntityGuard) RequireEntity

func (e *EntityGuard) RequireEntity(ent IThreadSafeEntity) bool

RequireEntity acquires the entity lock. Returns true on success.

type EntityIDMeta added in v1.0.1

type EntityIDMeta struct {
	InputID       int64
	UniqueID      int64
	FullID        int64
	Category      EntityCategory
	Kind          EntityKind
	RemoteCapable bool
}

EntityIDMeta is the normalized identity view shared by Nest, entity lookup, remote entity locking, and persistence.

func ResolveEntityID added in v1.0.1

func ResolveEntityID(id int64) EntityIDMeta

ResolveEntityID treats full EntityID as the canonical input.

type EntityKind added in v1.0.1

type EntityKind uint8

EntityKind identifies the concrete business entity definition. It is encoded in EntityID so any server can choose the right factory/loader from the ID.

const EntityKindNone EntityKind = 0

func GetEntityKindFromID added in v1.0.1

func GetEntityKindFromID(id int64) EntityKind

type EntityKindCategory added in v1.0.1

type EntityKindCategory struct {
	Kind     EntityKind
	Category EntityCategory
}

EntityKindCategory declares the ownership category for one concrete entity kind. The relation is global because EntityID encodes both fields and every server must resolve the same kind to the same category.

type EntityKindDef added in v1.0.1

type EntityKindDef struct {
	Kind         EntityKind
	Category     EntityCategory
	RemotePolicy RemotePolicy
}

EntityKindDef declares all global ID-visible properties for one concrete entity kind. Every server should register the same definition before it builds, validates, or routes EntityIDs.

type EntityLifetime added in v1.0.1

type EntityLifetime uint8

EntityLifetime describes the memory/persistence lifecycle expected by the framework. It is declarative; persistence is still controlled by AutoPersist and registered save/load definitions.

const (
	EntityLifetimeDefault EntityLifetime = iota
	EntityLifetimeEphemeral
	EntityLifetimeRuntimeRebuild
	EntityLifetimePersistedHotCold
	EntityLifetimeResident
	EntityLifetimeRemoteManaged
	EntityLifetimeMirrorCache
)

func DefaultEntityLifetime added in v1.0.1

func DefaultEntityLifetime(noPersist bool, remotePolicy RemotePolicy) EntityLifetime

type EntityManager

type EntityManager struct {
	// contains filtered or unexported fields
}

EntityManager is the central registry for all entities. Uses sharded buckets for high-concurrency access with hundreds of thousands of entities.

var Mgr *EntityManager

Mgr is the global entity manager instance. Must be set by the application layer before creating entities.

func NewEntityManager

func NewEntityManager() *EntityManager

NewEntityManager creates an EntityManager with default bucket count.

func NewEntityManagerWithBuckets

func NewEntityManagerWithBuckets(bucketCnt int) *EntityManager

NewEntityManagerWithBuckets creates an EntityManager with specified bucket count.

func (*EntityManager) Add

func (m *EntityManager) Add(e IThreadSafeEntity)

Add registers an entity. Panics on duplicate ID.

func (*EntityManager) CountByCategory

func (m *EntityManager) CountByCategory(category EntityCategory) int

CountByCategory returns the number of entities of a specific category.

func (*EntityManager) Exists

func (m *EntityManager) Exists(id int64) bool

Exists checks if an entity with the given ID is in memory.

func (*EntityManager) Get

Get returns the entity with the given ID, or nil if not found.

func (*EntityManager) GetGroupEntities

func (m *EntityManager) GetGroupEntities(groupID int64) []IThreadSafeEntity

func (*EntityManager) GetGroupEntity

func (m *EntityManager) GetGroupEntity(groupID int64, entityID int64) IThreadSafeEntity

func (*EntityManager) GetMany

func (m *EntityManager) GetMany(ids []int64) []IThreadSafeEntity

GetMany returns entities matching the given IDs. Missing entities are skipped.

func (*EntityManager) GetWithCategory

func (m *EntityManager) GetWithCategory(id int64, category EntityCategory) IThreadSafeEntity

GetWithCategory returns the entity with the given ID and category check. Returns nil if not found or type mismatch.

func (*EntityManager) Len

func (m *EntityManager) Len() int

Len returns the total number of managed entities.

func (*EntityManager) Range

func (m *EntityManager) Range(fn func(IThreadSafeEntity) bool)

Range iterates all entities across all buckets. Return false from fn to stop early.

func (*EntityManager) RangeByCategory

func (m *EntityManager) RangeByCategory(category EntityCategory, fn func(IThreadSafeEntity) bool)

RangeByCategory iterates entities of a specific category.

func (*EntityManager) RangeGroupEntities

func (m *EntityManager) RangeGroupEntities(groupID int64, fn func(IThreadSafeEntity) bool)

func (*EntityManager) Remove

func (m *EntityManager) Remove(e IThreadSafeEntity, reason EntityDestroyReason, deleteFromDB bool)

Remove destroys, marks removed, removes from bucket, and directly cleans the entity. If deleteFromDB is true, triggers OnEntityRemoveFromDB to persist the deletion.

func (*EntityManager) RemoveAfter

func (m *EntityManager) RemoveAfter(e IThreadSafeEntity, reason EntityDestroyReason, deleteFromDB bool, beforeDestroy func(IThreadSafeEntity) error) error

RemoveAfter runs beforeDestroy while holding the entity lock, then removes the entity from memory. It is used by hot/cold eviction to synchronously persist dirty state before the entity becomes unreachable.

func (*EntityManager) TryAdd

func (m *EntityManager) TryAdd(e IThreadSafeEntity) error

TryAdd registers an entity and reports duplicate IDs as an error.

func (*EntityManager) UpdateEntityGroup

func (m *EntityManager) UpdateEntityGroup(e IThreadSafeEntity, groupID int64) error

UpdateEntityGroup updates EntityBase group state and the manager's derived group membership index. Callers are responsible for holding the correct entity/group serialization lock.

type EntitySyncBuilderParam

type EntitySyncBuilderParam struct {
	Enabled         bool
	Topic           string
	Mode            EntitySyncMode
	FlushPolicy     SyncFlushPolicy
	MinInterval     time.Duration
	SchemaVersion   uint32
	FullSyncOnDirty bool
	PackerFactory   func(IThreadSafeEntity) EntitySyncPacker
	PackCache       EntitySyncPackCacheConfig
}

type EntitySyncCreateParam

type EntitySyncCreateParam struct {
	Enabled             bool
	EntityID            int64
	Topic               string
	Mode                EntitySyncMode
	FlushPolicy         SyncFlushPolicy
	MinInterval         time.Duration
	SchemaVersion       uint32
	FullSyncOnDirty     bool
	InitialObserverRefs []SyncObserverRef
	Packer              EntitySyncPacker
	PackCache           EntitySyncPackCacheConfig
}

type EntitySyncMode

type EntitySyncMode uint8
const (
	EntitySyncModeDefault EntitySyncMode = iota
	EntitySyncModeManual
	EntitySyncModeDirty
)

type EntitySyncObserver

type EntitySyncObserver struct {
	ObserverID int64
	Ref        SyncObserverRef
	Flags      uint32
	LastMask   uint64
}

type EntitySyncPackCacheConfig

type EntitySyncPackCacheConfig struct {
	Enabled          bool
	ObserverAgnostic bool
}

type EntitySyncPackFunc

type EntitySyncPackFunc struct {
	Enter  func(observer SyncObserverRef) (SyncPacket, error)
	Update func(observer SyncObserverRef, mask uint64) (SyncPacket, error)
	Leave  func(observer SyncObserverRef) (SyncPacket, error)
}

func (EntitySyncPackFunc) PackSyncEnter

func (f EntitySyncPackFunc) PackSyncEnter(observer SyncObserverRef) (SyncPacket, error)

func (EntitySyncPackFunc) PackSyncLeave

func (f EntitySyncPackFunc) PackSyncLeave(observer SyncObserverRef) (SyncPacket, error)

func (EntitySyncPackFunc) PackSyncUpdate

func (f EntitySyncPackFunc) PackSyncUpdate(observer SyncObserverRef, mask uint64) (SyncPacket, error)

type EntitySyncPacker

type EntitySyncPacker interface {
	PackSyncEnter(observer SyncObserverRef) (SyncPacket, error)
	PackSyncUpdate(observer SyncObserverRef, mask uint64) (SyncPacket, error)
	PackSyncLeave(observer SyncObserverRef) (SyncPacket, error)
}

type EntitySyncScheduler

type EntitySyncScheduler interface {
	EntitySyncSink
	MarkDirtyState(*EntitySyncState)
	Flush() []SyncPacket
}

func GetEntitySyncScheduler

func GetEntitySyncScheduler() EntitySyncScheduler

type EntitySyncSink

type EntitySyncSink interface {
	Enqueue(SyncPacket)
	EnqueueBatch([]SyncPacket)
}

func GetEntitySyncSink

func GetEntitySyncSink() EntitySyncSink

type EntitySyncState

type EntitySyncState struct {
	// contains filtered or unexported fields
}

func NewEntitySyncState

func NewEntitySyncState(param EntitySyncCreateParam) *EntitySyncState

func (*EntitySyncState) AddObserverRef

func (s *EntitySyncState) AddObserverRef(ref SyncObserverRef) (SyncPacket, bool)

func (*EntitySyncState) DirtyMask

func (s *EntitySyncState) DirtyMask() uint64

func (*EntitySyncState) Enabled

func (s *EntitySyncState) Enabled() bool

func (*EntitySyncState) EntityID

func (s *EntitySyncState) EntityID() int64

func (*EntitySyncState) Flush

func (s *EntitySyncState) Flush() []SyncPacket

func (*EntitySyncState) FlushTo

func (s *EntitySyncState) FlushTo(sink EntitySyncSink) []SyncPacket

func (*EntitySyncState) FlushToSink

func (s *EntitySyncState) FlushToSink() []SyncPacket

func (*EntitySyncState) HasAnyObserver

func (s *EntitySyncState) HasAnyObserver() bool

func (*EntitySyncState) HasObserverRef

func (s *EntitySyncState) HasObserverRef(ref SyncObserverRef) bool

func (*EntitySyncState) MarkDirty

func (s *EntitySyncState) MarkDirty(mask uint64)

func (*EntitySyncState) MarkFullDirty

func (s *EntitySyncState) MarkFullDirty(reason uint32)

func (*EntitySyncState) ObserverRefs

func (s *EntitySyncState) ObserverRefs() []SyncObserverRef

func (*EntitySyncState) PackFullForObserver

func (s *EntitySyncState) PackFullForObserver(ref SyncObserverRef, reason uint32) (SyncPacket, bool)

func (*EntitySyncState) PendingDirty

func (s *EntitySyncState) PendingDirty() bool

func (*EntitySyncState) RemoveObserverRef

func (s *EntitySyncState) RemoveObserverRef(ref SyncObserverRef) (SyncPacket, bool)

func (*EntitySyncState) SetPackCache

func (s *EntitySyncState) SetPackCache(config EntitySyncPackCacheConfig)

func (*EntitySyncState) SetPacker

func (s *EntitySyncState) SetPacker(packer EntitySyncPacker)

func (*EntitySyncState) TakeDirty

func (s *EntitySyncState) TakeDirty() uint64

func (*EntitySyncState) Topic

func (s *EntitySyncState) Topic() string

func (*EntitySyncState) TryAddObserverRefFromCachedEnter

func (s *EntitySyncState) TryAddObserverRefFromCachedEnter(ref SyncObserverRef) (SyncPacket, bool)

TryAddObserverRefFromCachedEnter adds a new observer only when the enter payload is already cached. Callers can use it on hot visibility paths to avoid locking the whole entity just to reuse a clean, observer-agnostic pack.

func (*EntitySyncState) Version

func (s *EntitySyncState) Version() uint64

type Getter

type Getter interface {
	Get(id int64, entityCategory EntityCategory) (IThreadSafeEntity, error)
	GetMany(ids []int64, idCategories []EntityCategory) ([]IThreadSafeEntity, error)
}

Getter retrieves entities by ID.

type GuardScope

type GuardScope struct {
	// contains filtered or unexported fields
}

func CurrentGuardScope

func CurrentGuardScope() *GuardScope

func NewGuardScope

func NewGuardScope(name string) (*GuardScope, func())

func (*GuardScope) Guard

func (s *GuardScope) Guard() *EntityGuard

func (*GuardScope) Name

func (s *GuardScope) Name() string

type Guardable

type Guardable interface {
	RangeDao(func(DaoInterface))
}

Guardable is implemented by entities that expose DAO instances for persistence, remote save, and dirty-mask tracking.

type IDGen added in v1.0.1

type IDGen struct {
	// contains filtered or unexported fields
}

IDGen is a lock-free fast path unique ID generator. It only calls acquireBlock when the current block is exhausted.

func NewIDGen added in v1.0.1

func NewIDGen(initialBlock uint64, acquireBlock func() (uint64, error)) (*IDGen, error)

func (*IDGen) Generate added in v1.0.1

func (g *IDGen) Generate() (uint64, error)

type IDirty

type IDirty interface {
	Dirty() bool
	SelfClean()
}

IDirty tracks modification state.

type IRemoteEntityLoader added in v1.0.1

type IRemoteEntityLoader interface {
	// LoadRemoteEntity loads entity from DB, creates/merges into EntityManager.
	// Returns nil if entity does not exist.
	LoadRemoteEntity(id int64, kind EntityKind) IThreadSafeRemoteEntity
	// SaveRemoteEntity persists dirty entity state.
	SaveRemoteEntity(e IThreadSafeRemoteEntity) error
	// SnapshotRemoteEntitySync samples sync dirty fields and returns a payload
	// plus commit/rollback callbacks. It does not persist data.
	SnapshotRemoteEntitySync(e IThreadSafeRemoteEntity) RemoteSyncSnapshot
	// DelRemoteEntity deletes entity from DB.
	DelRemoteEntity(e IThreadSafeRemoteEntity) error
	// CheckEntityExist checks if entity exists in DB without loading.
	CheckEntityExist(id int64, kind EntityKind) bool
}

IRemoteEntityLoader loads/saves remote entities from persistent storage. Application layer implements per entity category (Player, Alliance, etc.).

type IRemoteEntityManager added in v1.0.1

type IRemoteEntityManager interface {
	IRemoteEntityWrapperManager

	// SetLoader sets application-layer entity loader.
	SetLoader(loader IRemoteEntityLoader)
	// SetMarkerStore sets the mark persistence backend.
	SetMarkerStore(store IRemoteEntityMarkerStore)
	// SetSyncer sets the cross-server sync backend (optional).
	SetSyncer(syncer IRemoteEntitySyncer)

	// Loader returns current loader (may be nil).
	Loader() IRemoteEntityLoader
	// MarkerStore returns current marker store (may be nil).
	MarkerStore() IRemoteEntityMarkerStore
	// Syncer returns current syncer (may be nil).
	Syncer() IRemoteEntitySyncer

	// ResolveRemoteSnapshot resolves a read-only/cache remote snapshot. It must
	// not expose mutable entity/component/DAO pointers to callers.
	ResolveRemoteSnapshot(req RemoteSnapshotResolveRequest) (RemoteSnapshot, error)
}

IRemoteEntityManager is the top-level orchestrator for remote entity lifecycle. Composes WrapperManager + Loader + MarkerStore + Syncer.

type IRemoteEntityMarkerStore added in v1.0.1

type IRemoteEntityMarkerStore interface {
	// IsMarked checks if entity is currently marked (reads from cache/Redis).
	IsMarked(ctx context.Context, id int64) (bool, error)
	// Mark stores mark for entity (called under dist lock protection).
	Mark(ctx context.Context, id int64) error
	// Unmark removes mark.
	Unmark(ctx context.Context, id int64) error
}

IRemoteEntityMarkerStore provides remote entity mark persistence. A "mark" indicates entity is exclusively held by a server for remote access.

type IRemoteEntitySyncer added in v1.0.1

type IRemoteEntitySyncer interface {
	// SyncEntity publishes entity data change to subscribers.
	SyncEntity(id int64, version int64, collection string, data []byte) error
	// SyncDelEntity publishes entity deletion to subscribers.
	SyncDelEntity(id int64, version int64) error
}

IRemoteEntitySyncer broadcasts entity changes to other servers holding the entity.

type IRemoteEntityWrapper added in v1.0.1

type IRemoteEntityWrapper interface {
	// TryCastEntity acquires lock (if marked) → loads/validates version → attaches entity.
	// Returns release func for: save → sync → unlock.
	// If entity is not marked, uses local fast path (no dist lock).
	TryCastEntity() (release func(), err error)

	// TryReadOnlyEntity loads or returns the authoritative entity for a single
	// read without acquiring the distributed write lock. The returned release is
	// a no-op and never persists dirty state.
	TryReadOnlyEntity(option RemoteReadOption) (IThreadSafeRemoteEntity, func(), error)

	// TryReadOnlySnapshot loads or returns an immutable snapshot for a single
	// authoritative read without acquiring the distributed write lock.
	TryReadOnlySnapshot(req RemoteSnapshotRequest) (RemoteSnapshot, error)

	// TryCachedSnapshot returns an immutable snapshot from the local cache/
	// materialization path. It never exposes a mutable entity pointer.
	TryCachedSnapshot(req RemoteSnapshotRequest) (RemoteSnapshot, error)

	// MarkRemote marks entity as remote-owned (acquires dist lock, writes mark,
	// saves) and returns the release function that must be called to unlock.
	MarkRemote(ctx context.Context) (release func(), err error)

	// UnmarkRemote clears remote mark (entity returns to local ownership).
	UnmarkRemote(ctx context.Context) error

	// IsMarked returns cached mark state (fast path, no Redis call).
	IsMarked() bool

	// SetMarked updates local cached mark state (called by sync handler).
	SetMarked(v bool)

	// EvictEntity removes local entity from memory (after unmark by remote owner).
	EvictEntity()

	// TryUpdateEntity applies sync data (version + payload) from another server.
	TryUpdateEntity(version int64, data []byte) error

	// TryDelEntity applies remote deletion notification.
	TryDelEntity() error

	// Entity returns the currently attached entity (may be nil).
	Entity() IThreadSafeRemoteEntity
}

IRemoteEntityWrapper manages a single remote entity's distributed lifecycle. Each remote entity (identified by unique ID + category + kind) has one wrapper instance.

type IRemoteEntityWrapperManager added in v1.0.1

type IRemoteEntityWrapperManager interface {
	// GetOrCreate returns existing wrapper or creates one for (id, category, kind).
	GetOrCreate(id int64, category EntityCategory, kind EntityKind) IRemoteEntityWrapper

	// Get returns wrapper if exists, nil otherwise.
	Get(id int64) (IRemoteEntityWrapper, bool)

	// Remove removes and cleans up wrapper.
	Remove(id int64)

	// PrepareRemoteEntities is the batch entry point for nest dispatch.
	// Separates marked/non-marked, acquires locks in order, loads entities.
	// Returns aggregated release func for all entities.
	PrepareRemoteEntities(ids []int64) (release func(), err error)
}

IRemoteEntityWrapperManager manages all RemoteEntityWrappers.

type IThreadSafeEntity

type IThreadSafeEntity interface {
	IThreadSafeEntityBase

	AutoPersist() bool

	IsRemoved() bool
	SetRemoved()
	Touch() bool
	UnTouch()

	ClearBase()
	IsClear() bool

	Base() *EntityBase

	// OnInitFinish is called after all components are initialized.
	// Override in concrete entity to perform post-initialization logic.
	OnInitFinish(param *EntityCreateParam) error

	// OnDestroy is called when the entity is removed.
	// Called after all components' OnDestroy. Override in concrete entity for cleanup.
	OnDestroy(reason EntityDestroyReason)
}

IThreadSafeEntity is the full entity interface for the nest framework. Business entities embed EntityBase and implement this interface. Component/DAO wiring is handled by generated code, NOT by this interface.

func BuildEntity

func BuildEntity(param *EntityCreateParam) (IThreadSafeEntity, error)

BuildEntity creates an entity using the registered builder without adding it to the global manager or acquiring its guard lock. It is intended for loaders that need to finish construction before deciding how to publish the entity into memory.

func CreateEntity

func CreateEntity(param *EntityCreateParam) (IThreadSafeEntity, error)

CreateEntity creates and publishes an entity in a short-lived guard scope. The entity lock is released before this function returns; subsequent mutation should go through nest/entity handlers.

func LoadEntityOnDemand added in v1.0.1

func LoadEntityOnDemand(ctx context.Context, id int64, category EntityCategory, kind EntityKind) (IThreadSafeEntity, bool, error)

func NewEntity

func NewEntity(param *EntityCreateParam) (IThreadSafeEntity, error)

NewEntity creates an entity using the registered builder and publishes it to the global manager. For new entities (IsCreate=true), it generates a new ID and creates DAOs. For loaded entities (IsCreate=false), DAOs should be pre-populated in param.Dao.

func NewEntityInScope

func NewEntityInScope(scope *GuardScope, param *EntityCreateParam) (IThreadSafeEntity, error)

type IThreadSafeEntityBase

type IThreadSafeEntityBase interface {
	ID() int64
	UniqueID() int64
	StorageID() int64
	GUId() int64
	GetEntityCategory() EntityCategory
	GetEntityKind() EntityKind
	GetMutex() lock.Mutex
}

IThreadSafeEntityBase is the minimal entity identity interface.

type IThreadSafeRemoteEntity added in v1.0.1

type IThreadSafeRemoteEntity interface {
	IThreadSafeEntity
	EntityVersion() int64
	SetEntityVersion(int64)
	ExcludeSId() int32 // 0=remote-marked(other server owns), >0=local(this server owns)
	SetExcludeSId(int32)

	// OnDataChange applies synced data from another server.
	// Called when a remote owner broadcasts updated entity state.
	OnDataChange(data []byte, version int64)
}

IThreadSafeRemoteEntity extends IThreadSafeEntity with remote entity capabilities. Remote entities can be shared across servers and require distributed locking.

type OnDemandDaoLoadFunc added in v1.0.1

type OnDemandDaoLoadFunc func(ctx context.Context, collection string, storageID int64, dao DaoInterface) (loaded bool, err error)

type OnDemandEntityLoadFunc added in v1.0.1

type OnDemandEntityLoadFunc func(ctx context.Context, id int64, category EntityCategory, kind EntityKind) (IThreadSafeEntity, bool, error)

type RemoteAcquireMode added in v1.0.1

type RemoteAcquireMode uint8

RemoteAcquireMode describes how callers intend to access a remote entity. Write is the existing locked mutation path. ReadOnly is a one-shot safe read from the authoritative entity. Cache is a local read-only materialization.

const (
	RemoteAcquireWrite RemoteAcquireMode = iota + 1
	RemoteAcquireReadOnly
	RemoteAcquireCache
)

type RemoteEntityBase added in v1.0.1

type RemoteEntityBase struct {
	EntityBase
	// contains filtered or unexported fields
}

RemoteEntityBase extends EntityBase with remote entity fields. Embed this instead of EntityBase for entities that support remote access.

func (*RemoteEntityBase) EntityVersion added in v1.0.1

func (r *RemoteEntityBase) EntityVersion() int64

func (*RemoteEntityBase) ExcludeSId added in v1.0.1

func (r *RemoteEntityBase) ExcludeSId() int32

func (*RemoteEntityBase) IsRemoteCapable added in v1.0.1

func (r *RemoteEntityBase) IsRemoteCapable() bool

IsRemoteCapable returns true if this entity's ID has the remote-capable bit. It does not check the runtime remote marker store.

func (*RemoteEntityBase) SetEntityVersion added in v1.0.1

func (r *RemoteEntityBase) SetEntityVersion(v int64)

func (*RemoteEntityBase) SetExcludeSId added in v1.0.1

func (r *RemoteEntityBase) SetExcludeSId(sid int32)

type RemoteEntityMarkedFunc added in v1.0.1

type RemoteEntityMarkedFunc func(id int64) bool

type RemoteEntityPrepareFunc added in v1.0.1

type RemoteEntityPrepareFunc func(ids []int64) (release func(), err error)

RemoteEntityPrepareFunc prepares remote entities before dispatch. Input: remote entity IDs that need to be loaded/locked. Output: release func (called after dispatch to release distributed locks), error. Application layer implements: acquire distributed lock → load from DB → put into EntityManager. Set by application layer during initialization.

type RemotePolicy added in v1.0.1

type RemotePolicy uint8

RemotePolicy describes how an entity kind participates in cross-server routing/ownership. Remote-capable only means the ID carries the remote bit; remote-managed means the remote_entity module may load, lock, save, and sync the entity through IThreadSafeRemoteEntity.

const (
	RemotePolicyNone RemotePolicy = iota
	RemotePolicyCapable
	RemotePolicyManaged
	RemotePolicyMirror
)

func GetEntityKindRemotePolicy added in v1.0.1

func GetEntityKindRemotePolicy(kind EntityKind) RemotePolicy

func (RemotePolicy) RemoteCapable added in v1.0.1

func (p RemotePolicy) RemoteCapable() bool

func (RemotePolicy) RemoteManaged added in v1.0.1

func (p RemotePolicy) RemoteManaged() bool

type RemoteReadOption added in v1.0.1

type RemoteReadOption struct {
	MinVersion     uint64
	AllowStale     bool
	CacheTTLMillis int64
	NowMillis      int64
}

RemoteReadOption configures a single read operation. It is intentionally not stored in business objects; long-lived consumers store only RemoteViewRef.

func NormalizeRemoteReadOption added in v1.0.1

func NormalizeRemoteReadOption(option RemoteReadOption) RemoteReadOption

func (RemoteReadOption) Accepts added in v1.0.1

func (o RemoteReadOption) Accepts(version int64) bool

type RemoteSnapshot added in v1.0.1

type RemoteSnapshot struct {
	EntityID   int64
	Kind       EntityKind
	Scope      uint64
	Version    uint64
	RouteEpoch uint64
	Source     RemoteSnapshotSource
	ReadAt     int64
	ExpiresAt  int64
	Data       any
}

RemoteSnapshot is an immutable read result for remote read-only/cache paths. It is intentionally value-oriented: callers must not receive a mutable entity, component, or DAO pointer from read-only remote access.

func ResolveRemoteSnapshot added in v1.0.1

func ResolveRemoteSnapshot(req RemoteSnapshotResolveRequest) (RemoteSnapshot, bool, error)

func (RemoteSnapshot) Accepts added in v1.0.1

func (s RemoteSnapshot) Accepts(option RemoteReadOption) bool

func (RemoteSnapshot) AsString added in v1.0.1

func (s RemoteSnapshot) AsString() string

func (RemoteSnapshot) Expired added in v1.0.1

func (s RemoteSnapshot) Expired(now int64) bool

type RemoteSnapshotProvider added in v1.0.1

type RemoteSnapshotProvider interface {
	RemoteSnapshot(scope uint64) (any, bool)
}

type RemoteSnapshotRequest added in v1.0.1

type RemoteSnapshotRequest struct {
	Scope      uint64
	RouteEpoch uint64
	Option     RemoteReadOption
}

type RemoteSnapshotResolveFunc added in v1.0.1

type RemoteSnapshotResolveFunc func(req RemoteSnapshotResolveRequest) (RemoteSnapshot, error)

type RemoteSnapshotResolveRequest added in v1.0.1

type RemoteSnapshotResolveRequest struct {
	Ref        RemoteViewRef
	Mode       RemoteAcquireMode
	Scope      uint64
	RouteEpoch uint64
	Option     RemoteReadOption
}

type RemoteSnapshotSource added in v1.0.1

type RemoteSnapshotSource uint8
const (
	RemoteSnapshotSourceUnknown RemoteSnapshotSource = iota
	RemoteSnapshotSourceLocal
	RemoteSnapshotSourceLoaded
	RemoteSnapshotSourceCache
)

func (RemoteSnapshotSource) String added in v1.0.1

func (s RemoteSnapshotSource) String() string

type RemoteSyncApplier added in v1.0.1

type RemoteSyncApplier interface {
	ApplyRemoteSync(collection string, data []byte, version int64) error
}

type RemoteSyncItem added in v1.0.1

type RemoteSyncItem struct {
	Collection string
	Data       []byte
	Commit     func()
	Rollback   func()
}

RemoteSyncItem is one sampled sync payload with the dirty-mask callbacks needed to finish or retry that sampled payload.

type RemoteSyncPayload added in v1.0.1

type RemoteSyncPayload struct {
	Collection string `json:"collection"`
	Data       []byte `json:"data"`
}

func DecodeRemoteSyncPayload added in v1.0.1

func DecodeRemoteSyncPayload(raw []byte) (RemoteSyncPayload, error)

type RemoteSyncSnapshot added in v1.0.1

type RemoteSyncSnapshot struct {
	Items []RemoteSyncItem
}

RemoteSyncSnapshot is a batch of sampled sync payloads. A single entity can own multiple DAOs, and each DAO may produce an independent sync payload.

type RemoteViewRef added in v1.0.1

type RemoteViewRef struct {
	EntityID int64
	Kind     EntityKind
	Version  uint64
}

RemoteViewRef is the generic persisted reference to a server-side read model. It says which remote entity is being consumed and which version was observed.

func NewRemoteViewRef added in v1.0.1

func NewRemoteViewRef(entityID int64, kind EntityKind, version uint64) (RemoteViewRef, error)

func (RemoteViewRef) UniqueID added in v1.0.1

func (r RemoteViewRef) UniqueID() int64

func (RemoteViewRef) Valid added in v1.0.1

func (r RemoteViewRef) Valid() bool

type SyncFlushPolicy

type SyncFlushPolicy uint8
const (
	SyncFlushManual SyncFlushPolicy = iota
	SyncFlushOnEntityRelease
	SyncFlushInterval
	SyncFlushImmediate
)

type SyncObserverKind

type SyncObserverKind uint8
const (
	SyncObserverNone SyncObserverKind = iota
	SyncObserverPlayer
	SyncObserverServer
	SyncObserverEntity
	SyncObserverGroup
	SyncObserverCache
)

type SyncObserverRef

type SyncObserverRef struct {
	Kind SyncObserverKind
	ID   int64
	Sid  int32
	Key  string
}

SyncObserverRef identifies who observes an entity. Scene AOI, cross-server replication, cache subscribers, and entity-to-entity observation all use this one reference shape.

func NewCacheSyncObserver

func NewCacheSyncObserver(key string) SyncObserverRef

func NewEntitySyncObserver

func NewEntitySyncObserver(entityID int64) SyncObserverRef

func NewGroupSyncObserver

func NewGroupSyncObserver(key string) SyncObserverRef

func NewPlayerSyncObserver

func NewPlayerSyncObserver(playerID int64) SyncObserverRef

func NewServerSyncObserver

func NewServerSyncObserver(sid int32) SyncObserverRef

func (SyncObserverRef) Empty

func (r SyncObserverRef) Empty() bool

func (SyncObserverRef) Normalize

func (r SyncObserverRef) Normalize() SyncObserverRef

func (SyncObserverRef) PlayerID

func (r SyncObserverRef) PlayerID() int64

type SyncPacket

type SyncPacket struct {
	Topic         string
	EntityID      int64
	EntityKind    int32
	ObserverID    int64
	Observer      SyncObserverRef
	Type          SyncPacketType
	Version       uint64
	BaseVersion   uint64
	Mask          uint64
	Full          bool
	SchemaVersion uint32
	Reason        uint32
	Body          any
}

type SyncPacketType

type SyncPacketType uint8
const (
	SyncPacketTypeNone SyncPacketType = iota
	SyncPacketEnter
	SyncPacketUpdate
	SyncPacketLeave
	SyncPacketCustom
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL