/
View.hx
93 lines (80 loc) · 2.42 KB
/
View.hx
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
package echoes;
import echoes.ComponentStorage;
import echoes.Entity;
import echoes.utils.ReadOnlyData;
#if !macro
@:genericBuild(echoes.macro.ViewBuilder.build())
#end
class View<Rest> extends ViewBase { }
class ViewBase {
@:allow(echoes.Echoes) private final _entities:Array<Entity> = [];
/**
* All entities in this view.
*/
public var entities(get, never):ReadOnlyArray<Entity>;
private inline function get_entities():ReadOnlyArray<Entity> return _entities;
private var activations:Int = 0;
public var active(get, never):Bool;
private inline function get_active():Bool return activations > 0;
public function activate():Void {
activations++;
if(activations == 1) {
Echoes._activeViews.push(this);
for(e in Echoes.activeEntities) {
add(e);
}
}
}
@:allow(echoes.Entity) @:allow(echoes.ComponentStorage)
private inline function add(entity:Entity):Void {
if(isMatched(entity)) {
if(!entities.contains(entity)) {
_entities.push(entity);
}
dispatchAddedCallback(entity);
}
}
public inline function deactivate():Void {
activations--;
if(activations <= 0) {
reset();
}
}
private function dispatchAddedCallback(entity:Entity):Void {
//Overridden by `ViewBuilder`.
}
private function dispatchRemovedCallback(entity:Entity, ?removedComponentStorage:DynamicComponentStorage, ?removedComponent:Any):Void {
//Overridden by `ViewBuilder`.
}
/**
* Returns whether the entity has all of the view's required components.
*/
private function isMatched(entity:Entity):Bool {
//Overridden by `ViewBuilder`.
return false;
}
@:allow(echoes.Entity) @:allow(echoes.ComponentStorage)
private inline function remove(entity:Entity, ?removedComponentStorage:DynamicComponentStorage, ?removedComponent:Any):Void {
//Many applications will have a mix of short-lived and long-lived
//entities. An entity being removed is more likely to be short-lived,
//meaning it's near the end of the array.
final index:Int = entities.lastIndexOf(entity);
if(index >= 0) {
#if echoes_stable_order
_entities.splice(index, 1);
#else
_entities[index] = entities[entities.length - 1];
_entities.pop();
#end
dispatchRemovedCallback(entity, removedComponentStorage, removedComponent);
}
}
@:allow(echoes.Echoes) private function reset():Void {
activations = 0;
Echoes._activeViews.remove(this);
_entities.resize(0);
}
public function toString():String {
return "ViewBase";
}
}