-
Notifications
You must be signed in to change notification settings - Fork 44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Idiomatic Go - biggest breaking change yet #13
Comments
A possible fix for the downside, is doing this, when adding an entity: // Create the entity
e := &MyEntity{}
// Loop over all systems. This way we loop only once, and add it to all systems we like
for _, system := range systems {
switch sys := system.(type) {
case *RenderSystem:
sys.Add(&e.BasicEntity, &e.SpaceComponent, &e.RenderComponent)
case *MouseSystem:
sys.Add(&e.BasicEntity, &e.SpaceComponent, &e.MouseComponent)
}
} |
Just to illustrate, I re-wrote the Old / current: type AnimationSystem struct {
ecs.LinearSystem
}
func (a *AnimationSystem) New(*ecs.World) {}
func (*AnimationSystem) Type() string { return "AnimationSystem" }
func (*AnimationSystem) Pre() {}
func (*AnimationSystem) Post() {}
func (a *AnimationSystem) UpdateEntity(entity *ecs.Entity, dt float32) {
var (
ac *AnimationComponent
r *RenderComponent
ok bool
)
if ac, ok = entity.ComponentFast(ac).(*AnimationComponent); !ok {
return
}
if r, ok = entity.ComponentFast(r).(*RenderComponent); !ok {
return
}
ac.change += dt
if ac.change >= ac.Rate {
ac.NextFrame()
r.SetDrawable(ac.Cell())
}
} New: type animationEntity struct {
*ecs.BasicEntity
*AnimationComponent
*RenderComponent
}
type AnimationSystem struct {
entities []animationSystemEntity
}
func (a *AnimationSystem) Add(e *ecs.BasicEntity, anim *AnimationComponent, rend *RenderComponent) {
a.entities = append(a.entities, []animationEntity{e, anim, rend})
}
func (a *AnimationSystem) Remove(basic ecs.BasicEntity) {
delete := -1
for index, e := range a.entities {
if e.ID() == basic.ID() {
delete = index
break
}
}
if delete >= 0 {
a.entities = append(a.entities[:delete], a.entities[delete+1:]...)
}
}
func (a *AnimationSystem) Update(dt float32) {
for _, e := range a.entities {
e.AnimationComponent.change += dt
if e.AnimationComponent.change >= e.AnimationComponent.Rate {
e.AnimationComponent.NextFrame()
e.RenderComponent.SetDrawable(e.AnimationComponent.Cell())
}
}
} So this basically made the |
On the Gitter I have expressed that I would like to get this into master.
|
^ Please, thank you 💃 |
So, I was told by some people at the slack-chat, that we aren't using idiomatic Go. There may be collisions between the
Type() string
methods, and we're wasting performance by doing constant lookups.They said: why don't you use
reflect
? Well,reflect
is horrible so I don't want to use it.But the idea is simple: get rid of the global
[]Entity
, which stores everyEntity
. Instead, add the user-made entities to the appropriate systems,Usage would be something like:
Upsides;
Component
function takes 91ns per lookup, theComponentFast
about 18ns, and this approach takes 0ns. For something that might happen thousands / millions of times a second, this is nice.Downsides:
Scene
s? They would have to start using other references.This change is huge, but might also be worth it. I'd love a discussion on this, and maybe a fix for the downside? @paked, @everyone?
The text was updated successfully, but these errors were encountered: