-
Notifications
You must be signed in to change notification settings - Fork 42
/
cell.go
executable file
·121 lines (91 loc) · 2.64 KB
/
cell.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
package resolv
// Cell is used to contain and organize Object information.
type Cell struct {
X, Y int
Shapes []IShape // The Objects that a Cell contains.
}
// newCell creates a new cell at the specified X and Y position. Should not be used directly.
func newCell(x, y int) *Cell {
return &Cell{
X: x,
Y: y,
Shapes: []IShape{},
}
}
// register registers an object with a Cell. Should not be used directly.
func (cell *Cell) register(obj IShape) {
if !cell.Contains(obj) {
cell.Shapes = append(cell.Shapes, obj)
}
}
// unregister unregisters an object from a Cell. Should not be used directly.
func (cell *Cell) unregister(obj IShape) {
for i, o := range cell.Shapes {
if o == obj {
cell.Shapes[i] = cell.Shapes[len(cell.Shapes)-1]
cell.Shapes = cell.Shapes[:len(cell.Shapes)-1]
break
}
}
}
// Contains returns whether a Cell contains the specified Object at its position.
func (cell *Cell) Contains(obj IShape) bool {
for _, o := range cell.Shapes {
if o == obj {
return true
}
}
return false
}
// ContainsTags returns whether a Cell contains an Object that has the specified tag at its position.
func (cell *Cell) HasTags(tags Tags) bool {
for _, o := range cell.Shapes {
if o.Tags().Has(tags) {
return true
}
}
return false
}
// IsOccupied returns whether a Cell contains any Objects at all.
func (cell *Cell) IsOccupied() bool {
return len(cell.Shapes) > 0
}
// CellSelection is a selection of cells. It is primarily used to filter down Shapes.
type CellSelection struct {
StartX, StartY, EndX, EndY int // The start and end position of the Cell in cellular locations.
space *Space
excludeSelf IShape
}
// FilterShapes returns a ShapeFilter of the shapes within the cell selection.
func (c CellSelection) FilterShapes() ShapeFilter {
if c.space == nil {
return ShapeFilter{}
}
return ShapeFilter{
operatingOn: c,
}
}
// ForEach loops through each shape in the CellSelection.
func (c CellSelection) ForEach(iterationFunction func(shape IShape) bool) {
// Internally, this function allows us to pass a CellSelection as the operatingOn property in a ShapeFilter.
cellSelectionForEachIDSet = cellSelectionForEachIDSet[:0]
for y := c.StartY; y <= c.EndY; y++ {
for x := c.StartX; x <= c.EndX; x++ {
cell := c.space.Cell(x, y)
if cell != nil {
for _, s := range cell.Shapes {
if s == c.excludeSelf {
continue
}
if cellSelectionForEachIDSet.idInSet(s.ID()) {
continue
}
if !iterationFunction(s) {
break
}
cellSelectionForEachIDSet = append(cellSelectionForEachIDSet, s.ID())
}
}
}
}
}