-
Notifications
You must be signed in to change notification settings - Fork 10
/
entity.go
68 lines (61 loc) · 1.49 KB
/
entity.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package ecs
// Entity is simply a composition of one or more Components with an Id.
type Entity struct {
Components []Component `json:"components"`
Id string `json:"id"`
Masked uint64 `json:"masked"`
}
// Add a component.
func (e *Entity) Add(cn ...Component) {
for _, c := range cn {
if e.Masked&c.Mask() == c.Mask() {
continue
}
e.Components = append(e.Components, c)
e.Masked = maskSlice(e.Components)
}
}
// Get a component by its bitmask.
func (e *Entity) Get(mask uint64) Component {
for _, c := range e.Components {
if c.Mask() == mask {
return c
}
}
return nil
}
// Mask returns a pre-calculated maskSlice to identify the Components.
func (e *Entity) Mask() uint64 {
return e.Masked
}
// Remove a component by using its maskSlice.
func (e *Entity) Remove(mask uint64) {
modified := false
for i, c := range e.Components {
if c.Mask() == mask {
copy(e.Components[i:], e.Components[i+1:])
e.Components[len(e.Components)-1] = nil
e.Components = e.Components[:len(e.Components)-1]
modified = true
break
}
}
if modified {
e.Masked = maskSlice(e.Components)
}
}
// NewEntity creates a new entity and pre-calculates the component maskSlice.
func NewEntity(id string, components []Component) *Entity {
return &Entity{
Components: components,
Id: id,
Masked: maskSlice(components),
}
}
func maskSlice(components []Component) uint64 {
mask := uint64(0)
for _, c := range components {
mask = mask | c.Mask()
}
return mask
}