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