actionMap.h
Classes:
class
Used to represent a devices.
class
class
class
Detailed Description
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#ifndef _ACTIONMAP_H_ 25#define _ACTIONMAP_H_ 26 27#ifndef _PLATFORM_H_ 28#include "platform/platform.h" 29#endif 30#ifndef _TVECTOR_H_ 31#include "core/util/tVector.h" 32#endif 33#ifndef _SIMBASE_H_ 34#include "console/simBase.h" 35#endif 36#ifndef _ITICKABLE_H_ 37#include "core/iTickable.h" 38#endif 39 40class ContextAction; 41struct InputEventInfo; 42 43struct EventDescriptor 44{ 45 U8 flags; ///< Combination of any modifier flags. 46 U8 eventType; ///< SI_KEY, etc. 47 U16 eventCode; ///< From event.h 48}; 49 50/// Map raw inputs to a variety of actions. This is used for all keymapping 51/// in the engine. 52/// @see ActionMap::Node 53class ActionMap : public SimObject 54{ 55 typedef SimObject Parent; 56 friend class ContextAction; 57 58 protected: 59 bool onAdd(); 60 61 struct Node { 62 U32 modifiers; 63 U32 action; 64 65 enum Flags { 66 Ranged = BIT(0), ///< Ranged input. 67 HasScale = BIT(1), ///< Scaled input. 68 HasDeadZone = BIT(2), ///< Dead zone is present. 69 Inverted = BIT(3), ///< Input is inverted. 70 NonLinear = BIT(4), ///< Input should be re-fit to a non-linear scale 71 BindCmd = BIT(5), ///< Bind a console command to this. 72 Held = BIT(6), 73 DoubleTap = BIT(7) 74 }; 75 76 U32 flags; ///< @see Node::Flags 77 F32 deadZoneBegin; 78 F32 deadZoneEnd; 79 F32 scaleFactor; 80 81 SimObject* object; ///< Object to call consoleFunction on. 82 StringTableEntry consoleFunction; ///< Console function to call with new values. 83 84 char *makeConsoleCommand; ///< Console command to execute when we make this command. 85 char *breakConsoleCommand; ///< Console command to execute when we break this command. 86 ContextAction* contextEvent; ///< Event that kicks off via context-keybind actions such as holding or double-tapping 87 }; 88 89 /// Used to represent a devices. 90 struct DeviceMap 91 { 92 U32 deviceType; 93 U32 deviceInst; 94 95 Vector<Node> nodeMap; 96 DeviceMap():deviceType(NULL), deviceInst(NULL){ 97 VECTOR_SET_ASSOCIATION(nodeMap); 98 } 99 ~DeviceMap(); 100 }; 101 struct BreakEntry 102 { 103 U32 deviceType; 104 U32 deviceInst; 105 U32 objInst; 106 SimObject* object; 107 StringTableEntry consoleFunction; 108 char *breakConsoleCommand; 109 110 // It's possible that the node could be deleted (unlikely, but possible, 111 // so we replicate the node flags here... 112 // 113 U32 flags; 114 F32 deadZoneBegin; 115 F32 deadZoneEnd; 116 F32 scaleFactor; 117 }; 118 119 120 Vector<DeviceMap*> mDeviceMaps; 121 static Vector<BreakEntry> smBreakTable; 122 123 // Find: return NULL if not found in current map, Get: create if not 124 // found. 125 const Node* findNode(const U32 inDeviceType, const U32 inDeviceInst, 126 const U32 inModifiers, const U32 inAction); 127 bool findBoundNode( const char* function, U32 &devMapIndex, U32 &nodeIndex ); 128 bool nextBoundNode( const char* function, U32 &devMapIndex, U32 &nodeIndex ); 129 Node* getNode(const U32 inDeviceType, const U32 inDeviceInst, 130 const U32 inModifiers, const U32 inAction, 131 SimObject* object = NULL); 132 133 void removeNode(const U32 inDeviceType, const U32 inDeviceInst, 134 const U32 inModifiers, const U32 inAction, 135 SimObject* object = NULL); 136 137 void enterBreakEvent(const InputEventInfo* pEvent, const Node* pNode); 138 139 static const char* getModifierString(const U32 modifiers); 140 141 /// Pass index to a break entry, and this function will fire it off. 142 static void fireBreakEvent(U32 idx, F32 value = 0.f); 143 144 public: 145 ActionMap(); 146 ~ActionMap(); 147 148 void dumpActionMap(const char* fileName, const bool append) const; 149 150 static bool createEventDescriptor(const char* pEventString, EventDescriptor* pDescriptor); 151 152 bool processBind(const U32 argc, const char** argv, SimObject* object = NULL); 153 bool processBindCmd(const char *device, const char *action, const char *makeCmd, const char *breakCmd); 154 bool processUnbind(const char *device, const char *action, SimObject* object = NULL); 155 bool processHoldBind(const char *device, const char *action, const char *holdFunc, const char *tapFunc, const U32 holdTime, const bool holdOnly, const bool returnHoldTime = false); 156 157 /// @name Console Interface Functions 158 /// @{ 159 const char* getBinding ( const char* command ); ///< Find what the given command is bound to. 160 const char* getCommand ( const char* device, const char* action ); ///< Find what command is bound to the given event descriptor . 161 bool isInverted ( const char* device, const char* action ); 162 F32 getScale ( const char* device, const char* action ); 163 const char* getDeadZone( const char* device, const char* action ); 164 /// @} 165 166 167 static bool getKeyString(const U32 action, char* buffer); 168 static bool getDeviceName(const U32 deviceType, const U32 deviceInstance, char* buffer); 169 static const char* buildActionString( const InputEventInfo* event ); 170 171 bool processAction(const InputEventInfo*); 172 173 /// Return true if the given event triggers is bound to an action in this map. 174 bool isAction( U32 deviceType, U32 deviceInst, U32 modifiers, U32 action ); 175 176 /// Returns the global ActionMap. 177 static ActionMap* getGlobalMap(); 178 179 static bool checkBreakTable(const InputEventInfo*); 180 static bool handleEvent(const InputEventInfo*); 181 static bool handleEventGlobal(const InputEventInfo*); 182 183 /// Called when we lose focus, to make sure we have no dangling inputs. 184 /// 185 /// This fires a break event for every currently pending item in the break 186 /// table. 187 static void clearAllBreaks(); 188 189 /// Returns true if the specified key + modifiers are bound to something 190 /// on the global action map. 191 static bool checkAsciiGlobal(U16 key, U32 modifiers); 192 193 static bool getDeviceTypeAndInstance(const char *device, U32 &deviceType, U32 &deviceInstance); 194 195 DECLARE_CONOBJECT(ActionMap); 196}; 197 198class ContextAction : public ITickable 199{ 200 ActionMap::Node* mButton; ///< our button we're holding 201 F32 mMinHoldTime; ///< minimum time to qualify as 'held'. If we hold less than this, 202 ///< it's a 'press', otherwise it's a 'held' 203public: 204 F32 mStartTime; ///< Our timestamp when we first pressed. 205 F32 mEventValue; ///< Event value from our key event. 206 StringTableEntry mConsoleFunctionHeld; ///< Console function to call with new values if we held over 207 ///< a certain time. 208 209 bool mHoldOnly; ///< does this only care if we're holding? 210 ///< true means that it only fires a function while holding 211 ///< false time-contexts it 212 bool mBreakEvent; ///< Button is no longer being pressed! 213 bool mDidHold; ///< did we, at some point in the process, hold the button? 214 bool mActive; ///< do we be tickin? 215 bool mReturnHoldTime; ///< Do we return back our time held? 216 217 ContextAction(StringTableEntry func, F32 minHoldTime, ActionMap::Node* button, bool holdOnly); 218 virtual void processTick(); 219 virtual void interpolateTick(F32 delta) {} 220 virtual void advanceTime(F32 timeDelta) {} 221}; 222#endif // _ACTIONMAP_H_ 223