Package AccessEngine :: Package AEDevice :: Package AEInput :: Module Gesture
[hide private]
[frames] | no frames]

Source Code for Module AccessEngine.AEDevice.AEInput.Gesture

  1  ''' 
  2  Defines a class representing an input L{Gesture}, one or more device specific 
  3  input actions (e.g. keyboard key press, Braille button press, speech input 
  4  command, camera tracked gesture, etc.) performed simultaneously. 
  5   
  6  @author: Peter Parente 
  7  @organization: IBM Corporation 
  8  @copyright: Copyright (c) 2005, 2007 IBM Corporation 
  9  @license: The BSD License 
 10   
 11  All rights reserved. This program and the accompanying materials are made  
 12  available under the terms of the BSD license which accompanies 
 13  this distribution, and is available at 
 14  U{http://www.opensource.org/licenses/bsd-license.php} 
 15  ''' 
 16   
17 -class Gesture(object):
18 ''' 19 Represents one or more device specific input actions. Maintains a list of 20 action codes specific to a L{AEInput} device as well as a reference to the 21 device itself. Maintains a separate list of the action codes sorted according 22 to the order specified by the L{AEInput} device owning this L{Gesture} in 23 order to speed comparisons of two L{Gesture}s. Maintains a hash value computed 24 by XORing the sorted action codes in order to support the deterministic 25 hashing of L{Gesture}s with the same action codes to the same bin in a 26 dictionary. Both the cached sorted list and the hash code are reset on each 27 successful call to L{Gesture.addActionCode}. 28 29 @ivar device: Input device on which the L{Gesture} is performed 30 @type device: L{AEInput.AEInput} 31 @ivar sorted_codes: Cached action codes sorted by the device owning this 32 L{Gesture} 33 @type sorted_codes: list of integer 34 @ivar hash: Cached copy of the hash value of the L{Gesture} 35 @type hash: integer 36 @ivar action_codes: Codes for the actions performed on the device forming this 37 L{Gesture} 38 @type action_codes: list of integer 39 '''
40 - def __init__(self, device, action_codes=None, gesture=None):
41 ''' 42 Stores a reference to the input device. Stores a copy of the the provided 43 action codes or gets a copy of the action codes from the provided 44 L{Gesture}. If neither is specified, creates an empty action code list. 45 46 @param device: Input device on which this L{Gesture} is pressed 47 @type device: L{AEInput.AEInput} 48 @param action_codes: Action codes used to initialize the action code list 49 @type action_codes: list of integer 50 @param gesture: L{Gesture} object that this L{Gesture} should copy 51 @type gesture: L{Gesture} 52 ''' 53 self.device = device 54 self.sorted_codes = None 55 self.hash = None 56 57 if action_codes is not None: 58 # add action codes one by one using addActionCode method 59 self.action_codes = [] 60 for code in action_codes: 61 self.addActionCode(code) 62 elif gesture is not None: 63 # make a copy of the action codes in the gesture 64 self.action_codes = gesture.getActionCodes() 65 else: 66 # start an empty action codes list 67 self.action_codes = []
68
69 - def __str__(self):
70 ''' 71 Gets a human readable representation of the L{Gesture} as a string from 72 L{asString}. 73 74 @return: Text describing the gesture 75 @rtype: string 76 ''' 77 return self.asString()
78
79 - def __eq__(self, other):
80 ''' 81 Compares this L{Gesture} to the one provided. The comparison is performed 82 independent of the order of the actions forming the gesture by using 83 L{Gesture.getSortedActionCodes}. 84 85 @param other: L{Gesture} to compare to this one 86 @type other: L{Gesture} 87 @return: Is this L{Gesture} equal to the one provided? 88 @rtype: boolean 89 ''' 90 # equality comparison on a list is deep so that two lists with contents that 91 # equate are considered equal, even if they are not the same instance 92 # (the 'is' operate is used to check equality of instances) 93 return self.getSortedActionCodes() == other.getSortedActionCodes()
94
95 - def __iter__(self):
96 ''' 97 Gets an iterator over the action codes in this L{Gesture}. 98 99 @return: Iterator over all action codes in this L{Gesture} 100 @rtype: iterator 101 ''' 102 return iter(self.action_codes)
103
104 - def __contains__(self, action_code):
105 ''' 106 Gets if this L{Gesture} contains the given action code. 107 108 @return: Is the action code in this L{Gesture}? 109 @rtype: boolean 110 ''' 111 return action_code in self.action_codes
112
113 - def __hash__(self):
114 ''' 115 Builds a hash code for this L{Gesture} based on its action code contents by 116 XORing them together. The hash code is used by a L{GestureList} in building 117 its hash code. The action codes are sorted in device dependent order using 118 L{Gesture.getSortedActionCodes} before XORing to ensure two L{Gesture}s with 119 the same actions hash to the same value. 120 121 @return: Hash code for this L{Gesture} 122 @rtype: integer 123 ''' 124 if self.hash is None: 125 self.hash = 0 126 for code in self.getSortedActionCodes(): 127 self.hash = self.hash^code 128 return self.hash
129
130 - def __len__(self):
131 ''' 132 Gets the number of codes in the current gesture. 133 134 @return: Number of codes 135 @rtype: integer 136 ''' 137 return len(self.action_codes)
138
139 - def getDevice(self):
140 ''' 141 Gets the device on which this L{Gesture} is performed. 142 143 @return: Device on which this L{Gesture} is performed 144 @rtype: L{AEInput.AEInput} 145 ''' 146 return self.device
147
148 - def addActionCode(self, code):
149 ''' 150 Adds the given action code to this L{Gesture}. If the L{Gesture} is full 151 (i.e. it has the maximum number of action as determined by its device), a 152 ValueError is raised. If the L{Gesture} is not full, the new action code is 153 added to the end of L{action_codes}. If the action code was already in the 154 L{Gesture}, the action code is moved to the end of L{action_codes}. 155 156 @param code: Action code to add to this L{Gesture} 157 @type code: integer 158 @raise ValueError: When the L{Gesture} is full according to 159 L{AEInput.Base.AEInput.getMaxActions} 160 ''' 161 # check if full 162 if len(self.action_codes) == self.device.getMaxActions(): 163 raise ValueError('Maximum action codes reached for this device') 164 try: 165 # remove the action if it's already there 166 self.action_codes.remove(code) 167 except ValueError: 168 # the action wasn't already there 169 pass 170 # add the new action to the end 171 self.action_codes.append(code) 172 # reset cached sorted action codes and hash value 173 self.sorted_codes = None 174 self.hash = None
175
176 - def removeActionCode(self, code):
177 ''' 178 Deletes an action code from this L{Gesture}. 179 180 @param code: Action code to remove from this L{Gesture} 181 @type code: integer 182 @raise ValueError: When the action code does not exist in the L{Gesture} 183 ''' 184 self.action_codes.remove(code) 185 self.sorted_codes = None 186 self.hash = None
187
188 - def clearActionCodes(self):
189 ''' 190 Deletes all action codes from this L{Gesture}. 191 ''' 192 self.action_codes = [] 193 self.sorted_codes = None 194 self.hash = None
195
196 - def getActionCodes(self):
197 ''' 198 Gets a copy of all the action codes in this L{Gesture}. Makes a fast copy by taking 199 a slice using the start and end slice defaults. 200 201 @return: Copy of all the action codes in this L{Gesture} 202 @rtype: list of integer 203 ''' 204 return self.action_codes[:]
205
206 - def peekActionCodes(self):
207 ''' 208 Gets a reference to the list of action codes in this L{Gesture}. The reference to 209 the list should be used for read-only access even though protections against 210 modification are not used. This method exists solely to offset the time 211 cost incurred by making a copy of actions using L{getActionCodes}. 212 ''' 213 return self.action_codes
214
215 - def getSortedActionCodes(self):
216 ''' 217 Gets a copy of all the action codes in this L{Gesture} in a sort order 218 determined by the L{AEInput} device on which the actions are performed. 219 220 @return: Copy of all the action codes in device dependent sort order 221 @rtype: list of integer 222 ''' 223 if self.sorted_codes is None: 224 self.sorted_codes = self.device.sortGesture(self) 225 return self.sorted_codes
226
227 - def getNumActions(self):
228 ''' 229 Gets the number of action codes stored in this L{Gesture}. 230 231 @return: Number of action codes bounded by 232 L{AEInput.Base.AEInput.getMaxActions} 233 @rtype: integer 234 ''' 235 return len(self.action_codes)
236
237 - def asString(self):
238 ''' 239 Gets a human readable representation of the action codes in this L{Gesture} 240 determined by the L{AEInput} device on which the actions were performed. 241 242 @return: Text representation of the actions in this L{Gesture} 243 @rtype: string 244 ''' 245 return self.device.asString(self)
246