61 lines
1.4 KiB
Go
61 lines
1.4 KiB
Go
package gohan
|
|
|
|
import (
|
|
"sync"
|
|
)
|
|
|
|
var componentMutex sync.RWMutex
|
|
|
|
// ComponentID is a component identifier. Each Component is assigned a unique ID
|
|
// via NextComponentID, and implements a ComponentID method which returns the ID.
|
|
type ComponentID int
|
|
|
|
// Component represents data for an entity, and how it interacts with the world.
|
|
type Component interface {
|
|
ComponentID() ComponentID
|
|
}
|
|
|
|
var nextComponentID ComponentID
|
|
|
|
// NextComponentID returns the next available ComponentID.
|
|
func NextComponentID() ComponentID {
|
|
componentMutex.Lock()
|
|
defer componentMutex.Unlock()
|
|
|
|
nextComponentID++
|
|
return nextComponentID
|
|
}
|
|
|
|
// AddComponent adds a Component to an Entity.
|
|
func (entity EntityID) AddComponent(component Component) {
|
|
componentMutex.Lock()
|
|
defer componentMutex.Unlock()
|
|
|
|
if wasRemoved(entity) {
|
|
return
|
|
}
|
|
|
|
componentID := component.ComponentID()
|
|
|
|
if gameComponents[entity] == nil {
|
|
gameComponents[entity] = make(map[ComponentID]interface{})
|
|
}
|
|
gameComponents[entity][componentID] = component
|
|
|
|
entityMutex.Lock()
|
|
defer entityMutex.Unlock()
|
|
modifiedEntities = append(modifiedEntities, entity)
|
|
}
|
|
|
|
// Component gets a Component of an Entity.
|
|
func (entity EntityID) Component(componentID ComponentID) interface{} {
|
|
componentMutex.RLock()
|
|
defer componentMutex.RUnlock()
|
|
|
|
components := gameComponents[entity]
|
|
if components == nil {
|
|
return nil
|
|
}
|
|
return components[componentID]
|
|
}
|