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