feat: westworldwithmessaging. add entitymanager, telegram, messagehandlers, delayedmessages, expand baseentity

This commit is contained in:
jonas committed 2026-09-03 21:57:52 +02:00
1 parent 0e7482e04c
commit 129dd5d8b8
18 files changed
+505 -19

No files matched your search

@@ -0,0 +1,70 @@
package westworldwithmessaging
import "sync"
// entityManager is the Go version of the singleton class
// EntityManager. Same singleton pattern used throughout this
// package: an unexported type, one shared instance, reached only
// through the EntityManager() function below.
//
// The C++ version stores "BaseGameEntity*" pointers in its map. In
// C++, a BaseGameEntity* pointing at an actual Miner still calls
// Miner's real Update() (that's what "virtual" functions do - even
// through a base-class pointer, the real subclass's version runs).
// Go doesn't have virtual functions or base-class pointers, but our
// Entity interface (from entity.go: Update() and ID()) gives us the
// exact same behavior - a variable of type Entity holding a *Miner
// still calls *Miner's own Update(). So Entity is what we store here
// instead of *BaseGameEntity, to get the same real-subclass-runs
// behavior C++ gets from virtual dispatch.
type entityManager struct {
// entityMap cross-references entities by their ID number, same
// as the book's std::map<int, BaseGameEntity*> m_EntityMap. (The
// book's own comment above that field actually describes a
// std::vector instead - a leftover mismatch in the book's text
// itself. We're matching the real field, the map.)
entityMap map[int]Entity
}
var (
entityManagerInstance *entityManager
entityManagerOnce sync.Once
)
// EntityManager is the Go stand-in for "EntityManager::Instance()".
func EntityManager() *entityManager {
entityManagerOnce.Do(func() {
entityManagerInstance = &entityManager{
entityMap: make(map[int]Entity),
}
})
return entityManagerInstance
}
// EntityMgr is a shorthand for EntityManager(), matching the book's
// "#define EntityMgr EntityManager::Instance()" macro. Go has no
// preprocessor and no macros, so instead this is just a plain
// package-level variable, set up once when the package is loaded -
// EntityMgr.RegisterEntity(...) reads the same as the book's
// EntityMgr->RegisterEntity(...), just with a dot instead of an
// arrow (Go doesn't distinguish "." for values from "->" for
// pointers the way C++ does - it's always ".").
var EntityMgr = EntityManager()
// RegisterEntity stores an entity so it can be looked up later by
// its ID.
func (m *entityManager) RegisterEntity(newEntity Entity) {
m.entityMap[newEntity.ID()] = newEntity
}
// GetEntityFromID returns the entity with the given ID, or nil if
// none is registered under that ID (same as the C++ version
// implicitly returning nullptr for a lookup miss).
func (m *entityManager) GetEntityFromID(id int) Entity {
return m.entityMap[id]
}
// RemoveEntity removes an entity from the registry.
func (m *entityManager) RemoveEntity(entity Entity) {
delete(m.entityMap, entity.ID())
}