1 /**
2  * Copyright:       Copyright (C) 2018 Gabriel Gheorghe, All Rights Reserved
3  * Authors:         $(Gabriel Gheorghe)
4  * License:         $(LINK2 https://www.gnu.org/licenses/gpl-3.0.txt, GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007)
5  * Source:          $(LINK2 https://github.com/GabyForceQ/LibertyEngine/blob/master/source/liberty/input/profiler/impl.d)
6  * Documentation:
7  * Coverage:
8  * TODO:
9  *  - axis
10  *  - add shift, ctrl, alt, cmd to action mapping
11 **/
12 module liberty.input.profiler.impl;
13 
14 import liberty.logger.impl;
15 import liberty.input.constants;
16 import liberty.input.profiler.binding;
17 import liberty.input.profiler.data;
18 import liberty.input.joystick.impl;
19 import liberty.input.keyboard.impl;
20 import liberty.input.mouse.impl;
21 
22 /**
23  *
24 **/
25 final class InputProfiler {
26   private {
27     string id;
28     bool warnings = true;
29     InputActionBinding[string] actionBindings;
30     InputAxisBinding[string] axisBindings;
31 
32     InputAction!Joystick iacj_test;
33     InputAction!Keyboard iack_test;
34     InputAction!Mouse iacm_test;
35 
36     InputAxis!Joystick iaxj_test;
37     InputAxis!Keyboard iaxk_test;
38     InputAxis!Mouse iaxm_test;
39   }
40 
41   package {
42     InputDeviceType lastDeviceUsed = InputDeviceType.None;
43   }
44 
45   /**
46    *
47   **/
48   this(string id)   {
49     this.id = id;
50   }
51 
52   /**
53    *
54   **/
55   string getId()   const {
56     return id;
57   }
58 
59   /**
60    *
61   **/
62   InputProfiler createActionBinding(string id) {
63     actionBindings[id] = new InputActionBinding(id, this);
64     return this;
65   }
66 
67   /**
68    *
69   **/
70   InputProfiler createAxisBinding(string id) {
71     return this;
72   }
73 
74   /**
75    *
76   **/
77   InputProfiler bindAction(T...)(string id, T actions)
78   in (actions.length > 0)
79   do {
80     // If action with this id doesn't exist, then create it.
81     if (id !in actionBindings)
82       createActionBinding(id);
83 
84     bool exists;
85     static foreach (a; actions) {
86       static if (typeof(a).stringof == typeof(iack_test).stringof) {
87         foreach (e; actionBindings[id].keyboard)
88           if (e.button == a.button && e.action == a.action)
89             exists = true;
90 
91         if (!exists)
92           actionBindings[id].keyboard ~= a;
93       } else static if (typeof(a).stringof == typeof(iacm_test).stringof) {
94         foreach (e; actionBindings[id].mouse)
95           if (e.button == a.button && e.action == a.action)
96             exists = true;
97 
98         if (!exists)
99           actionBindings[id].mouse ~= a;
100       } else static if (typeof(a).stringof == typeof(iacj_test).stringof) {
101         foreach (e; actionBindings[id].joystick)
102           if (e.button == a.button && e.action == a.action)
103             exists = true;
104 
105         if (!exists)
106           actionBindings[id].joystick ~= a;
107       }
108       exists = false;
109     }
110 
111     return this;
112   }
113 
114   /**
115    *
116   **/
117   InputProfiler bindAxis(T...)(string id, T axises)
118   in (axises.length > 0)
119   do {
120     // If axis with this id doesn't exist, then create it.
121     if (id !in axisBindings)
122       createAxisBinding(id);
123 
124 
125     return this;
126   }
127 
128   /**
129    *
130   **/
131   InputProfiler unbindAction(string id) {
132     actionBindings.remove(id);
133     return this;
134   }
135 
136   /**
137    *
138   **/
139   InputProfiler unbindAllActions() {
140     actionBindings.destroy();
141     return this;
142   }
143 
144   /**
145    *
146   **/
147   InputProfiler unbindAxis(string id) {
148     axisBindings.remove(id);
149     return this;
150   }
151 
152   /**
153    *
154   **/
155   InputProfiler unbindAllAxises() {
156     axisBindings.destroy();
157     return this;
158   }
159 
160   /**
161    *
162   **/
163   bool isActionUnfolding(string id) {
164     if (id !in actionBindings) {
165       if (warnings)
166         Logger.warning("Action binding with id: '" ~ id ~ "' of profile with id: '"
167           ~ this.id ~ "' doesn't exist. False will be returned.", typeof(this).stringof);
168       return false;
169     }
170 
171     return actionBindings[id].isUnfolding();
172   }
173 
174   /**
175    *
176   **/
177   InputDeviceType getLastDeviceUsed()   {
178     return lastDeviceUsed;
179   }
180 
181   /**
182    *
183   **/
184   InputProfiler setWarningsEnabled(bool enabled = true)   {
185     warnings = enabled;
186     return this;
187   }
188 
189   /**
190    *
191   **/
192   bool areWarningsEnabled()   const {
193     return warnings;
194   }
195 }