1 module re.input.virtual.axis; 2 3 import re.input; 4 import std.algorithm; 5 6 /// a virtual axis 7 class VirtualAxis : VirtualInput { 8 /// monitors a pair of inputs to make an axis 9 static abstract class Node : VirtualInput.Node { 10 @property public float value(); 11 } 12 13 /// logic-controllable axis 14 static class LogicAxis : Node { 15 public float logic_value = 0; 16 17 @property public override float value() { 18 return logic_value; 19 } 20 } 21 22 /// monitors a pair of keyboard keys 23 static class KeyboardKeys : Node { 24 public OverlapBehavior overlap_behavior; 25 public Keys positive; 26 public Keys negative; 27 private float _value; 28 private bool _turned; 29 30 /// creates a keyboard keys node 31 this(Keys positive, Keys negative, OverlapBehavior overlap_behavior = OverlapBehavior.init) { 32 this.positive = positive; 33 this.negative = negative; 34 this.overlap_behavior = overlap_behavior; 35 } 36 37 @property public override float value() { 38 return _value; 39 } 40 41 public override void update() { 42 if (Input.is_key_down(positive)) { 43 if (Input.is_key_down(negative)) { 44 switch (overlap_behavior) { 45 case OverlapBehavior.Cancel: 46 _value = 0; 47 break; 48 case OverlapBehavior.Newer: 49 if (!_turned) { 50 _value *= -1; 51 _turned = true; 52 } 53 break; 54 case OverlapBehavior.Older: 55 break; // we don't touch the value 56 default: 57 assert(0); 58 } 59 } else { 60 _turned = false; 61 _value = 1; 62 } 63 } else if (Input.is_key_down(negative)) { 64 _turned = false; 65 _value = -1; 66 } else { 67 _turned = false; 68 _value = 0; 69 } 70 } 71 } 72 73 @property public float value() { 74 foreach (node; nodes) { 75 auto val = (cast(Node) node).value; 76 if (val != 0) { 77 return val; 78 } 79 } 80 return 0; 81 } 82 } 83 84 @("input-axis") 85 unittest { 86 auto the_axis = new VirtualAxis(); 87 the_axis.nodes ~= new VirtualAxis.KeyboardKeys(Keys.KEY_LEFT, Keys.KEY_RIGHT); 88 89 assert(the_axis.nodes.length > 0); 90 }