Guest User

Untitled

a guest
Jun 20th, 2018
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.42 KB | None | 0 0
  1. //
  2. // fsStateMachine.m
  3. // fuzzspaces
  4. //
  5. // Created by fuzzimac4 on 6/4/09.
  6. // Copyright 2009 __MyCompanyName__. All rights reserved.
  7. //
  8.  
  9. #import "fsStateMachine.h"
  10. #include "sio2.h"
  11.  
  12. // State register offset table
  13. unsigned short fsStateRegisterOffset[] = {FS_STATE_REGISTER_ENVIRONMENT,
  14. FS_STATE_REGISTER_MENU,
  15. FS_STATE_REGISTER_TOOL,
  16. FS_STATE_REGISTER_VIEW,
  17. FS_STATE_REGISTER_TOUCH,
  18. FS_STATE_REGISTER_MULTITOUCH,
  19. 0x00};
  20.  
  21. @implementation fsStateMachine
  22.  
  23. @synthesize touchAccumulator;
  24. @synthesize touchTimer;
  25. @synthesize touchPositions;
  26. @synthesize touch2Positions;
  27.  
  28. - (fsStateMachine *) init {
  29. self = [super init];
  30. inputState = (fsInputState *) calloc(1, sizeof(fsInputState));
  31. touchTimer = nil;
  32. touchPositions = (vec2 *) calloc(1, sizeof(vec2) * FS_TOUCH_LAST_POSITIONS);
  33. touch2Positions = (vec2 *) calloc(1, sizeof(vec2) * FS_TOUCH_LAST_POSITIONS);
  34. currentStateCallback = NULL;
  35. mainRunLoop = [NSRunLoop currentRunLoop];
  36.  
  37. [self setState:FS_STATE_START inRegister:FS_STATE_REGISTER_ENVIRONMENT];
  38. [self setState:FS_STATE_NO_SELECTION inRegister:FS_STATE_REGISTER_ENVIRONMENT];
  39. [self setState:FS_STATE_VIEW_PAN inRegister:FS_STATE_REGISTER_VIEW];
  40.  
  41. return self;
  42. }
  43.  
  44. - (void) dealloc {
  45. free(inputState);
  46. free(touchPositions);
  47. free(touch2Positions);
  48.  
  49. inputState = NULL;
  50. touchPositions = NULL;
  51. touch2Positions = NULL;
  52.  
  53. [super dealloc];
  54. }
  55.  
  56. - (unsigned short *) registerOffsetFor:(unsigned short)stateRegister {
  57. unsigned short *baseOffset = fsStateRegisterOffset;
  58. unsigned short *currentOffset = fsStateRegisterOffset;
  59.  
  60. while (*currentOffset) {
  61. if (*currentOffset == stateRegister)
  62. return (unsigned short *) (++currentOffset - baseOffset);
  63.  
  64. currentOffset++;
  65. }
  66.  
  67. return NULL;
  68. }
  69.  
  70. - (void) setState:(unsigned short)stateFlag inRegister:(unsigned short)stateRegister {
  71. unsigned short *registerPtr = [self registerOffsetFor:stateRegister];
  72. registerPtr = (unsigned short *) ((unsigned int) inputState + (unsigned int) registerPtr);
  73. *registerPtr = *registerPtr | stateFlag;
  74. }
  75.  
  76. - (void) resetState:(unsigned short)stateFlag inRegister:(unsigned short)stateRegister {
  77. unsigned short *registerPtr = [self registerOffsetFor:stateRegister];
  78. registerPtr = (unsigned short *) ((unsigned int) inputState + (unsigned int) registerPtr);
  79. *registerPtr = *registerPtr & ~stateFlag;
  80. }
  81.  
  82. - (void) resetRegister:(unsigned short)stateRegister {
  83. unsigned short *registerPtr = [self registerOffsetFor:stateRegister];
  84. registerPtr = (unsigned short *) ((unsigned int) inputState + (unsigned int) registerPtr);
  85. *registerPtr = 0x0;
  86. }
  87.  
  88. - (BOOL) isState:(unsigned short)stateFlag inRegister:(unsigned short)stateRegister {
  89. unsigned short *registerPtr = [self registerOffsetFor:stateRegister];
  90. registerPtr = (unsigned short *) ((unsigned int) inputState + (unsigned int) registerPtr);
  91. return (*registerPtr & stateFlag) != 0;
  92. }
  93.  
  94. - (void) applyStateDiff:(fsInputStateDiff *)stateDiff {
  95. // First, test the registers to make sure we can switch to the new input state
  96. if (stateDiff->testStates.registerEnvironment) {
  97. if (![self isState:stateDiff->testStates.registerEnvironment inRegister:FS_STATE_REGISTER_ENVIRONMENT])
  98. return;
  99. }
  100.  
  101. if (stateDiff->testStates.registerMenu) {
  102. if (![self isState:stateDiff->testStates.registerEnvironment inRegister:FS_STATE_REGISTER_MENU])
  103. return;
  104. }
  105.  
  106. if (stateDiff->testStates.registerTool) {
  107. if (![self isState:stateDiff->testStates.registerEnvironment inRegister:FS_STATE_REGISTER_TOOL])
  108. return;
  109. }
  110.  
  111. if (stateDiff->testStates.registerView) {
  112. if (![self isState:stateDiff->testStates.registerEnvironment inRegister:FS_STATE_REGISTER_VIEW])
  113. return;
  114. }
  115.  
  116. if (stateDiff->testStates.registerTouch) {
  117. if (![self isState:stateDiff->testStates.registerEnvironment inRegister:FS_STATE_REGISTER_TOUCH])
  118. return;
  119. }
  120.  
  121. if (stateDiff->testStates.registerMultitouch) {
  122. if (![self isState:stateDiff->testStates.registerEnvironment inRegister:FS_STATE_REGISTER_MULTITOUCH])
  123. return;
  124. }
  125.  
  126. // Second, clear any registers that were set
  127. if (FS_STATE_REGISTER_ENVIRONMENT & stateDiff->clearRegisters)
  128. [self resetRegister:FS_STATE_REGISTER_ENVIRONMENT];
  129.  
  130. if (FS_STATE_REGISTER_MENU & stateDiff->clearRegisters)
  131. [self resetRegister:FS_STATE_REGISTER_MENU];
  132.  
  133. if (FS_STATE_REGISTER_TOOL & stateDiff->clearRegisters)
  134. [self resetRegister:FS_STATE_REGISTER_TOOL];
  135.  
  136. if (FS_STATE_REGISTER_VIEW & stateDiff->clearRegisters)
  137. [self resetRegister:FS_STATE_REGISTER_VIEW];
  138.  
  139. if (FS_STATE_REGISTER_TOUCH & stateDiff->clearRegisters)
  140. [self resetRegister:FS_STATE_REGISTER_TOUCH];
  141.  
  142. if (FS_STATE_REGISTER_MULTITOUCH & stateDiff->clearRegisters)
  143. [self resetRegister:FS_STATE_REGISTER_MULTITOUCH];
  144.  
  145. // Next, unset any states
  146. [self resetState:stateDiff->unsetStates.registerEnvironment inRegister:FS_STATE_REGISTER_ENVIRONMENT];
  147. [self resetState:stateDiff->unsetStates.registerMenu inRegister:FS_STATE_REGISTER_MENU];
  148. [self resetState:stateDiff->unsetStates.registerTool inRegister:FS_STATE_REGISTER_TOOL];
  149. [self resetState:stateDiff->unsetStates.registerView inRegister:FS_STATE_REGISTER_VIEW];
  150. [self resetState:stateDiff->unsetStates.registerTouch inRegister:FS_STATE_REGISTER_TOUCH];
  151. [self resetState:stateDiff->unsetStates.registerMultitouch inRegister:FS_STATE_REGISTER_MULTITOUCH];
  152.  
  153. // Finally, set any new states
  154. [self setState:stateDiff->setStates.registerEnvironment inRegister:FS_STATE_REGISTER_ENVIRONMENT];
  155. [self setState:stateDiff->setStates.registerMenu inRegister:FS_STATE_REGISTER_MENU];
  156. [self setState:stateDiff->setStates.registerTool inRegister:FS_STATE_REGISTER_TOOL];
  157. [self setState:stateDiff->setStates.registerView inRegister:FS_STATE_REGISTER_VIEW];
  158. [self setState:stateDiff->setStates.registerTouch inRegister:FS_STATE_REGISTER_TOUCH];
  159. [self setState:stateDiff->setStates.registerMultitouch inRegister:FS_STATE_REGISTER_MULTITOUCH];
  160. }
  161.  
  162. // Convention is to reset registers, then states, and finally set states.
  163. - (void) updateTouchesForWindow:(SIO2window *)_SIO2window {
  164. [self setTouchAccumulator: _SIO2window->n_tap];
  165.  
  166. switch (_SIO2window->n_touch) {
  167. case 0:
  168. [self.touchTimer invalidate];
  169. self.touchTimer = nil;
  170. [self resetRegister:FS_STATE_REGISTER_TOUCH];
  171. [self resetRegister:FS_STATE_REGISTER_MULTITOUCH];
  172. [self resetState:
  173. FS_STATE_SCREEN_TOUCH | FS_STATE_SCREEN_MULTITOUCH
  174. inRegister:
  175. FS_STATE_REGISTER_ENVIRONMENT];
  176. [self setState:FS_STATE_START inRegister:FS_STATE_REGISTER_ENVIRONMENT];
  177. break;
  178.  
  179. case 1:
  180. [self resetRegister:FS_STATE_REGISTER_MULTITOUCH];
  181. [self resetState:
  182. FS_STATE_START | FS_STATE_SCREEN_MULTITOUCH
  183. inRegister:
  184. FS_STATE_REGISTER_ENVIRONMENT];
  185. [self setState:FS_STATE_SCREEN_TOUCH inRegister:FS_STATE_REGISTER_ENVIRONMENT];
  186. self.touchTimer = [NSTimer timerWithTimeInterval:FS_TOUCH_IS_HELD_AFTER
  187. target:self
  188. selector:@selector(touchWasHeld:)
  189. userInfo:nil
  190. repeats:false];
  191. [mainRunLoop addTimer:self.touchTimer forMode:NSDefaultRunLoopMode];
  192. break;
  193.  
  194. case 2:
  195. [self.touchTimer invalidate];
  196. self.touchTimer = nil;
  197. [self resetRegister:FS_STATE_REGISTER_TOUCH];
  198. [self resetState:
  199. FS_STATE_START | FS_STATE_SCREEN_TOUCH
  200. inRegister:
  201. FS_STATE_REGISTER_ENVIRONMENT];
  202. [self setState:FS_STATE_SCREEN_MULTITOUCH inRegister:FS_STATE_REGISTER_ENVIRONMENT];
  203. break;
  204.  
  205. default:
  206. [self resetRegister:FS_STATE_REGISTER_TOUCH];
  207. [self resetRegister:FS_STATE_REGISTER_MULTITOUCH];
  208. [self resetState:
  209. FS_STATE_SCREEN_TOUCH | FS_STATE_SCREEN_MULTITOUCH | FS_STATE_START
  210. inRegister:
  211. FS_STATE_REGISTER_ENVIRONMENT];
  212. [self setState:FS_STATE_ERROR inRegister:FS_STATE_REGISTER_ENVIRONMENT];
  213. break;
  214. }
  215. }
  216.  
  217. - (void) touchWasHeld:(NSTimer *)touchTimer {
  218. [self.touchTimer invalidate];
  219. self.touchTimer = nil;
  220. [self setState:FS_STATE_SCREEN_TOUCH_HOLD inRegister:FS_STATE_REGISTER_TOUCH];
  221. }
  222.  
  223. - (void) updateWithMoveForWindow:(SIO2window *)_SIO2window {
  224. return;
  225. }
  226.  
  227. - (void) updateWithAccelerometer:(SIO2window *)_SIO2window {
  228. return;
  229. }
  230.  
  231. - (BOOL) areToolsInMenuEnabled {
  232. return true;
  233. }
  234.  
  235. @end
Add Comment
Please, Sign In to add comment