1 module re.input.virtual.base;
2 
3 import re.input;
4 import std.algorithm;
5 
6 /// method of resolving conflicting, overlapping inputs
7 enum OverlapBehavior {
8     Cancel,
9     Older,
10     Newer
11 }
12 
13 /// a virtual input composed of input node units
14 abstract class VirtualInput {
15     /// the input node units
16     public Node[] nodes;
17 
18     /// create and register a virtual input
19     this() {
20         Input.virtual_inputs ~= this;
21     }
22 
23     /// unregister from virtual input updates
24     public void unregister() {
25         Input.virtual_inputs = Input.virtual_inputs.remove!(x => x == this);
26     }
27 
28     /// updates all nodes
29     public void update() {
30         foreach (node; nodes) {
31             node.update();
32         }
33     }
34 
35     /// monitors a single unit for input
36     static abstract class Node {
37         void update() {
38         }
39     }
40 }
41 
42 @("input-base")
43 unittest {
44     import re.ecs;
45     import std.algorithm;
46 
47     class InputComponent : Component {
48         public VirtualButton bonk;
49 
50         this() {
51             bonk = new VirtualButton();
52             bonk.nodes ~= new VirtualButton.LogicButton();
53         }
54 
55         override void destroy() {
56             bonk.unregister();
57         }
58     }
59 
60     auto ecs = new EntityManager();
61     auto nt = ecs.create_entity();
62     auto controls = new InputComponent();
63     nt.add_component(controls);
64     // make sure input is registered
65     assert(Input.virtual_inputs.any!(x => x == controls.bonk));
66     assert(nt.has_component!InputComponent);
67     ecs.destroy();
68     // make sure entity was deactivated
69     assert(!nt.alive);
70     // make sure input is unregistered
71     assert(!Input.virtual_inputs.any!(x => x == controls.bonk));
72 }