diff --git a/component.go b/component.go index 683ce2e..a22c4d9 100644 --- a/component.go +++ b/component.go @@ -43,7 +43,7 @@ func componentIDByName(name string) componentID { if !w.haveSystemComponentName[name] { w.systemComponentNames = append(w.systemComponentNames, name) w.haveSystemComponentName[name] = true - id := newComponentID() // ComponentNames index now aligns with componentID + id := newComponentID() return id } @@ -88,7 +88,13 @@ func (e Entity) With(f interface{}) { args := make([]reflect.Value, numIn) for i := 0; i < numIn; i++ { id := componentIDByName(t.In(i).String()) - args[i] = reflect.ValueOf(components[id]) + + arg := reflect.ValueOf(components[id]) + if components[id] == nil { + arg = reflect.New(t.In(i)).Elem() + } + + args[i] = arg } v.Call(args) diff --git a/entity.go b/entity.go index 2bd60c3..f8a4265 100644 --- a/entity.go +++ b/entity.go @@ -24,9 +24,6 @@ func NewEntity() Entity { w.allEntities = append(w.allEntities, w.maxEntityID) w.components = append(w.components, make([]interface{}, w.maxComponentID+1)) - for i := range w.systems { - w.systemComponents[i] = append(w.systemComponents[i], make([]interface{}, w.maxComponentID+1)) - } return w.maxEntityID } diff --git a/world.go b/world.go index e957249..b60fcce 100644 --- a/world.go +++ b/world.go @@ -57,7 +57,6 @@ type world struct { systemNeeds [][]componentID // Slice of ComponentIDs needed by each system. systemUses [][]componentID // Slice of ComponentIDs used by each system. systemComponentIDs [][]componentID // Slice of ComponentIDs needed or used by each system. - systemComponents [][][]interface{} // Slice of components for matching entities. systemComponentFields [][]reflect.Value // Slice of component struct fields used by each system. systemReceivesUpdate []bool @@ -76,8 +75,6 @@ type world struct { cacheTime time.Duration - ctx *context - entityMutex sync.Mutex componentMutex sync.Mutex @@ -93,8 +90,6 @@ func newWorld() *world { haveSystemComponentName: make(map[string]bool), } - w.ctx = &context{} - // Pad slices to match IDs starting with 1. w.components = append(w.components, nil) w.systemComponentNames = append(w.systemComponentNames, "") @@ -113,7 +108,6 @@ func AddSystem(system System) { w.systemReceivesUpdate = append(w.systemReceivesUpdate, true) w.systemReceivesDraw = append(w.systemReceivesDraw, true) w.systemEntities = append(w.systemEntities, nil) - w.systemComponents = append(w.systemComponents, nil) w.systemComponentFields = append(w.systemComponentFields, nil) w.entityMutex.Lock() @@ -175,28 +169,25 @@ func AddSystemAfter(system System, after ...System) { } */ -func (w *world) setSystemComponentFields(i int) { +func (w *world) setSystemComponentFields(e Entity, i int) { //log.Println(len(w.systemComponentFields[i])) //log.Println(w.systemComponentFields[i]) for j, field := range w.systemComponentFields[i] { //log.Println(j, field, field.String()) id := w.systemComponentIDs[i][j] //log.Println("SYSTEM", i, "FIELD", j, "ID", id) - if w.ctx.components[id] == nil { + if w.components[e][id] == nil { field.Set(reflect.Zero(field.Type())) } else { - field.Set(reflect.ValueOf(w.ctx.components[id])) + field.Set(reflect.ValueOf(w.components[e][id])) } } } func (w *world) updateSystem(i int) (int, error) { - w.ctx.systemIndex = i - w.ctx.allowed = w.systemComponentIDs[i] updated := 0 for _, entity := range w.systemEntities[i] { - w.ctx.components = w.systemComponents[i][entity] - w.setSystemComponentFields(i) + w.setSystemComponentFields(entity, i) err := w.systems[i].Update(entity) if err != nil { @@ -220,7 +211,6 @@ func (w *world) _handleRemovedEntities() { for j, e := range w.systemEntities[i] { if e == entity { w.systemEntities[i] = _removeAt(w.systemEntities[i], j) - w.systemComponents[i][entity] = w.systemComponents[i][entity][:0] // TODO Could this lead to memory issues? continue REMOVED } } @@ -247,15 +237,6 @@ func (w *world) _handleModifiedEntities() { w.handledModifiedEntities[entity] = true for i := range w.systems { - l := len(w.systemComponents[i]) - if l != int(w.maxEntityID+1) { - w.systemComponents[i] = append(w.systemComponents[i], make([][]interface{}, int(w.maxEntityID+1)-l)...) - } - - if len(w.systemComponents[i][entity]) != int(w.maxComponentID+1) { - w.systemComponents[i][entity] = make([]interface{}, w.maxComponentID+1) - } - systemEntityIndex := -1 for j, systemEntity := range w.systemEntities[i] { if systemEntity == entity { @@ -271,15 +252,8 @@ func (w *world) _handleModifiedEntities() { skip = true break } - - w.systemComponents[i][entity][componentID] = c } if !skip { - for _, componentID := range w.systemUses[i] { - c := entity.getComponent(componentID) - w.systemComponents[i][entity][componentID] = c - } - if systemEntityIndex != -1 { // Already attached. continue @@ -293,8 +267,6 @@ func (w *world) _handleModifiedEntities() { } else if systemEntityIndex != -1 { // Detach from system. w.systemEntities[i] = _removeAt(w.systemEntities[i], systemEntityIndex) - - w.systemComponents[i][entity] = w.systemComponents[i][entity][:0] // TODO Could this lead to memory issues? } } } @@ -362,12 +334,9 @@ func CurrentUpdates() int { } func (w *world) drawSystem(i int, screen *ebiten.Image) (int, error) { - w.ctx.systemIndex = i - w.ctx.allowed = w.systemComponentIDs[i] var drawn int for _, entity := range w.systemEntities[i] { - w.ctx.components = w.systemComponents[i][entity] - w.setSystemComponentFields(i) + w.setSystemComponentFields(entity, i) err := w.systems[i].Draw(entity, screen) if err != nil {