actionMap.h

Engine/source/sim/actionMap.h

More...

Classes:

class

Map raw inputs to a variety of actions.

class

Used to represent a devices.

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