-
Notifications
You must be signed in to change notification settings - Fork 44
/
Copy pathentity.go
141 lines (119 loc) · 3.69 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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package ecs
import (
"sync/atomic"
)
var (
idInc uint64
)
// A BasicEntity is simply a set of components with a unique ID attached to it,
// nothing more. It belongs to any amount of Systems, and has a number of
// Components
type BasicEntity struct {
// Entity ID.
id uint64
parent *BasicEntity
children []*BasicEntity
}
// Identifier is an interface for anything that implements the basic ID() uint64,
// as the BasicEntity does. It is useful as more specific interface for an
// entity registry than just the interface{} interface
type Identifier interface {
ID() uint64
}
// IdentifierSlice implements the sort.Interface, so you can use the
// store entites in slices, and use the P=n*log n lookup for them
type IdentifierSlice []Identifier
// NewBasic creates a new Entity with a new unique identifier. It is safe for
// concurrent use.
func NewBasic() BasicEntity {
return BasicEntity{id: atomic.AddUint64(&idInc, 1)}
}
// NewBasics creates an amount of new entities with a new unique identifiers. It
// is safe for concurrent use, and performs better than NewBasic for large
// numbers of entities.
func NewBasics(amount int) []BasicEntity {
entities := make([]BasicEntity, amount)
lastID := atomic.AddUint64(&idInc, uint64(amount))
for i := 0; i < amount; i++ {
entities[i].id = lastID - uint64(amount) + uint64(i) + 1
}
return entities
}
// ID returns the unique identifier of the entity.
func (e BasicEntity) ID() uint64 {
return e.id
}
// GetBasicEntity returns a Pointer to the BasicEntity itself
// By having this method, All Entities containing a BasicEntity now automatically have a GetBasicEntity Method
// This allows system.Add functions to recieve a single interface
// EG:
// s.AddByInterface(a interface{GetBasicEntity()*BasicEntity, GetSpaceComponent()*SpaceComponent){
// s.Add(a.GetBasicEntity(),a.GetSpaceComponent())
//}
func (e *BasicEntity) GetBasicEntity() *BasicEntity {
return e
}
// AppendChild appends a child to the BasicEntity
func (e *BasicEntity) AppendChild(child *BasicEntity) {
child.parent = e
e.children = append(e.children, child)
}
func (e *BasicEntity) RemoveChild(child *BasicEntity) {
delete := -1
for i, v := range e.children {
if v.ID() == child.ID() {
delete = i
break
}
}
if delete >= 0 {
e.children = append(e.children[:delete], e.children[delete+1:]...)
}
}
// Children returns the children of the BasicEntity
func (e *BasicEntity) Children() []BasicEntity {
ret := []BasicEntity{}
for _, child := range e.children {
ret = append(ret, *child)
}
return ret
}
// var visited map[uint64]struct{}
// var descs []*BasicEntity
// Descendents returns the children and their children all the way down the tree.
func (e *BasicEntity) Descendents() []BasicEntity {
return descendents([]BasicEntity{}, e, e)
}
func descendents(in []BasicEntity, this, top *BasicEntity) []BasicEntity {
for _, child := range this.children {
in = descendents(in, child, top)
}
if this.ID() == top.ID() {
return in
}
return append(in, *this)
}
// Parent returns the parent of the BasicEntity
func (e *BasicEntity) Parent() *BasicEntity {
return e.parent
}
// Len returns the length of the underlying slice
// part of the sort.Interface
func (is IdentifierSlice) Len() int {
return len(is)
}
// Less will return true if the ID of element at i is less than j;
// part of the sort.Interface
func (is IdentifierSlice) Less(i, j int) bool {
return is[i].ID() < is[j].ID()
}
// Swap the elements at positions i and j
// part of the sort.Interface
func (is IdentifierSlice) Swap(i, j int) {
is[i], is[j] = is[j], is[i]
}
// BasicFase is an interface that BasicEntity and entities containing
// a BasicEntity implement.
type BasicFace interface {
GetBasicEntity() *BasicEntity
}