1 module unecht.core.events; 2 3 import unecht.core.component; 4 import unecht.core.types:UESize; 5 public import unecht.glfw.types:UEKey; 6 7 /// 8 enum UEEventType 9 { 10 updateEditMode, 11 key, 12 text, 13 windowSize, 14 framebufferSize, 15 windowFocus, 16 mouseScroll, 17 mouseButton, 18 mousePos, 19 joystickStatus, 20 joystickAxes, 21 joystickButton 22 } 23 24 /// 25 struct EventModKeys 26 { 27 private bool shiftDown; 28 private bool ctrlDown; 29 private bool altDown; 30 private bool superDown; 31 32 void set(bool modShift,bool modCtrl,bool modAlt,bool modSuper) nothrow 33 { 34 shiftDown = modShift; 35 ctrlDown = modCtrl; 36 superDown = modSuper; 37 altDown = modAlt; 38 } 39 40 /// 41 void setFromBitMaskGLFW(int mask) nothrow 42 { 43 import unecht.core.stdex:testBitMask; 44 import derelict.glfw3.glfw3; 45 46 shiftDown = testBitMask(mask,GLFW_MOD_SHIFT); 47 ctrlDown = testBitMask(mask,GLFW_MOD_CONTROL); 48 altDown = testBitMask(mask,GLFW_MOD_ALT); 49 superDown = testBitMask(mask,GLFW_MOD_SUPER); 50 } 51 52 /// is shift mod set 53 @property bool isModShift() const { return shiftDown; } 54 /// 55 @property bool isModCtrl() const { return ctrlDown; } 56 /// 57 @property bool isModAlt() const { return altDown; } 58 /// 59 @property bool isModSuper() const { return superDown; } 60 } 61 62 /// 63 struct UEEvent 64 { 65 UEEventType eventType; 66 struct KeyEvent 67 { 68 enum Action 69 { 70 Down, 71 Up, 72 Repeat, 73 } 74 75 UEKey key; 76 Action action; 77 EventModKeys mods; 78 } 79 KeyEvent keyEvent; 80 81 struct TextEvent 82 { 83 dchar character; 84 EventModKeys mods; 85 } 86 TextEvent textEvent; 87 88 struct SizeEvent 89 { 90 UESize size; 91 } 92 SizeEvent windowSizeEvent; 93 SizeEvent framebufferSizeEvent; 94 95 struct FocusEvent 96 { 97 bool gainedFocus; 98 } 99 FocusEvent focusEvent; 100 101 struct MouseScrollEvent 102 { 103 double xoffset; 104 double yoffset; 105 EventModKeys mods; 106 } 107 MouseScrollEvent mouseScrollEvent; 108 109 struct MouseButtonEvent 110 { 111 enum Action 112 { 113 down, 114 up, 115 click 116 } 117 118 int button; 119 Action action; 120 MousePosEvent pos; 121 122 /// 123 @property bool isDown() const {return action==Action.down;} 124 /// 125 @property bool isClick() const {return action==Action.click;} 126 } 127 MouseButtonEvent mouseButtonEvent; 128 129 struct MousePosEvent 130 { 131 double x; 132 double y; 133 134 EventModKeys mods; 135 } 136 MousePosEvent mousePosEvent; 137 138 struct JoystickStatus 139 { 140 uint id; 141 string name; 142 uint buttonCount; 143 uint axesCount; 144 bool connected; 145 } 146 JoystickStatus joystickStatus; 147 148 struct JoystickButton 149 { 150 uint buttonId; 151 bool pressed; 152 } 153 JoystickButton joystickButton; 154 155 struct JoystickAxes 156 { 157 uint id; 158 float[] axes; 159 } 160 JoystickAxes joystickAxes; 161 } 162 163 /// 164 alias UEEventCallback = void delegate (UEEvent); 165 166 /// 167 struct UEEventReceiver 168 { 169 UEComponent component; 170 UEEventType eventType; 171 UEEventCallback eventFunc; 172 173 private bool removed=false; 174 } 175 176 /// 177 interface UEEvents 178 { 179 /// 180 void register(UEEventReceiver); 181 /// 182 void unRegister(UEEventReceiver); 183 /// 184 void removeComponent(UEComponent); 185 /// 186 //TODO: makes this one only schedule and trigger all events in the main loop (#145) 187 void trigger(UEEvent) nothrow; 188 } 189 190 /// 191 final class UEEventsSystem : UEEvents 192 { 193 /// 194 override void register(UEEventReceiver _receiver) 195 { 196 receiver ~= _receiver; 197 } 198 199 /// 200 override void unRegister(UEEventReceiver _receiver) 201 { 202 foreach(ref r; receiver) 203 { 204 if(r.component == _receiver.component && r.eventType == _receiver.eventType) 205 { 206 r.removed = true; 207 dirty = true; 208 } 209 } 210 } 211 212 /// 213 override void removeComponent(UEComponent _comp) 214 { 215 foreach(ref r; receiver) 216 { 217 if(r.component is _comp) 218 { 219 r.removed = true; 220 dirty = true; 221 r.component = null; 222 } 223 } 224 } 225 226 UEEventReceiver[] receiver; 227 bool dirty=false; 228 229 /// 230 override void trigger(UEEvent _ev) nothrow 231 { 232 try{ 233 foreach(r; receiver) 234 { 235 //TODO: support correct recursive enabled/disabled values 236 if(r.removed || (!r.component.enabled) || (!r.component.sceneNode.enabled)) 237 continue; 238 239 if(r.eventType == _ev.eventType) 240 { 241 r.eventFunc(_ev); 242 } 243 } 244 } 245 catch(Throwable e){ 246 import unecht.core.logger:log; 247 try log.errorf("%s",e); 248 catch(Throwable){} 249 } 250 } 251 252 /// remove deleted entries 253 void cleanUp() 254 { 255 if(dirty) 256 { 257 //TODO: 258 } 259 260 dirty = false; 261 } 262 }