Change GestureState to "real" enum

This commit is contained in:
Pavel fljot 2012-07-03 23:12:38 +03:00
parent 039a7d79f4
commit 193332b9d0
12 changed files with 154 additions and 42 deletions

View file

@ -1,17 +1,99 @@
package org.gestouch.core
{
import flash.errors.IllegalOperationError;
/**
* @author Pavel fljot
*/
public class GestureState
{
public static const IDLE:uint = 1 << 0;//1
public static const POSSIBLE:uint = 1 << 1;//2
public static const RECOGNIZED:uint = 1 << 2;//4
public static const BEGAN:uint = 1 << 3;//8
public static const CHANGED:uint = 1 << 4;//16
public static const ENDED:uint = 1 << 5;//32
public static const CANCELLED:uint = 1 << 6;//64
public static const FAILED:uint = 1 << 7;//128
public static const IDLE:GestureState = new GestureState(1 << 0, "IDLE");
public static const POSSIBLE:GestureState = new GestureState(1 << 1, "POSSIBLE");
public static const RECOGNIZED:GestureState = new GestureState(1 << 2, "RECOGNIZED");
public static const BEGAN:GestureState = new GestureState(1 << 3, "BEGAN");
public static const CHANGED:GestureState = new GestureState(1 << 4, "CHANGED");
public static const ENDED:GestureState = new GestureState(1 << 5, "ENDED");
public static const CANCELLED:GestureState = new GestureState(1 << 6, "CANCELLED");
public static const FAILED:GestureState = new GestureState(1 << 7, "FAILED");
private static const endStatesBitMask:uint =
GestureState.CANCELLED.toUint() |
GestureState.RECOGNIZED.toUint() |
GestureState.ENDED.toUint() |
GestureState.FAILED.toUint();
private static var allStatesInitialized:Boolean;
private var value:uint;
private var name:String;
private var validTransitionsBitMask:uint;
{
_initClass();
}
public function GestureState(value:uint, name:String)
{
if (allStatesInitialized)
{
throw new IllegalOperationError("You cannot create gesture states." +
"Use predefined constats like GestureState.RECOGNIZED");
}
this.value = value;
this.name = name;
}
private static function _initClass():void
{
IDLE.setValidNextStates(POSSIBLE);
POSSIBLE.setValidNextStates(RECOGNIZED, BEGAN, FAILED);
RECOGNIZED.setValidNextStates(IDLE);
BEGAN.setValidNextStates(CHANGED, ENDED, CANCELLED);
CHANGED.setValidNextStates(CHANGED, ENDED, CANCELLED);
ENDED.setValidNextStates(IDLE);
FAILED.setValidNextStates(IDLE);
allStatesInitialized = true;
}
public function toString():String
{
return "GestureState." + name;
}
public function toUint():uint
{
return value;
}
private function setValidNextStates(...states):void
{
var mask:uint;
for each (var state:GestureState in states)
{
mask = mask | state.value;
}
validTransitionsBitMask = mask;
}
gestouch_internal function canTransitionTo(state:GestureState):Boolean
{
return (validTransitionsBitMask & state.value) > 0;
}
gestouch_internal function get isEndState():Boolean
{
return (endStatesBitMask & value) > 0;
}
}
}
}

View file

@ -1,5 +1,7 @@
package org.gestouch.events
{
import org.gestouch.core.GestureState;
import flash.events.Event;
@ -8,7 +10,7 @@ package org.gestouch.events
*/
public class GestureEvent extends Event
{
public var gestureState:uint;
public var gestureState:GestureState;
public var stageX:Number;
public var stageY:Number;
public var localX:Number;
@ -16,7 +18,7 @@ package org.gestouch.events
public function GestureEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false,
gestureState:uint = 0,
gestureState:GestureState = null,
stageX:Number = 0, stageY:Number = 0,
localX:Number = 0, localY:Number = 0)
{

View file

@ -1,5 +1,7 @@
package org.gestouch.events
{
import org.gestouch.core.GestureState;
import flash.events.Event;
@ -10,11 +12,11 @@ package org.gestouch.events
{
public static const STATE_CHANGE:String = "stateChange";
public var newState:uint;
public var oldState:uint;
public var newState:GestureState;
public var oldState:GestureState;
public function GestureStateEvent(type:String, newState:uint, oldState:uint)
public function GestureStateEvent(type:String, newState:GestureState, oldState:GestureState)
{
super(type, false, false);

View file

@ -1,5 +1,7 @@
package org.gestouch.events
{
import org.gestouch.core.GestureState;
import flash.events.Event;
@ -12,7 +14,7 @@ package org.gestouch.events
public function LongPressGestureEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false,
gestureState:uint = 0,
gestureState:GestureState = null,
stageX:Number = 0, stageY:Number = 0,
localX:Number = 0, localY:Number = 0)
{

View file

@ -1,5 +1,7 @@
package org.gestouch.events
{
import org.gestouch.core.GestureState;
import flash.events.Event;
@ -12,7 +14,7 @@ package org.gestouch.events
public function PanGestureEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false,
gestureState:uint = 0,
gestureState:GestureState = null,
stageX:Number = 0, stageY:Number = 0,
localX:Number = 0, localY:Number = 0,
offsetX:Number = 0, offsetY:Number = 0)

View file

@ -1,5 +1,7 @@
package org.gestouch.events
{
import org.gestouch.core.GestureState;
import flash.events.Event;
@ -12,7 +14,7 @@ package org.gestouch.events
public function RotateGestureEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false,
gestureState:uint = 0,
gestureState:GestureState = null,
stageX:Number = 0, stageY:Number = 0,
localX:Number = 0, localY:Number = 0,
rotation:Number = 0)

View file

@ -1,5 +1,7 @@
package org.gestouch.events
{
import org.gestouch.core.GestureState;
import flash.events.Event;
@ -12,7 +14,7 @@ package org.gestouch.events
public function SwipeGestureEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false,
gestureState:uint = 0,
gestureState:GestureState = null,
stageX:Number = 0, stageY:Number = 0,
localX:Number = 0, localY:Number = 0,
offsetX:Number = 0, offsetY:Number = 0)

View file

@ -1,5 +1,7 @@
package org.gestouch.events
{
import org.gestouch.core.GestureState;
import flash.events.Event;
@ -12,7 +14,8 @@ package org.gestouch.events
public function TapGestureEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false,
gestureState:uint = 0, stageX:Number = 0, stageY:Number = 0,
gestureState:GestureState = null,
stageX:Number = 0, stageY:Number = 0,
localX:Number = 0, localY:Number = 0)
{
super(type, bubbles, cancelable, gestureState, stageX, stageY, localX, localY);

View file

@ -1,5 +1,7 @@
package org.gestouch.events
{
import org.gestouch.core.GestureState;
import flash.events.Event;
@ -18,7 +20,7 @@ package org.gestouch.events
public function TransformGestureEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false,
gestureState:uint = 0,
gestureState:GestureState = null,
stageX:Number = 0, stageY:Number = 0,
localX:Number = 0, localY:Number = 0,
scaleX:Number = 1.0, scaleY:Number = 1.0,

View file

@ -1,5 +1,7 @@
package org.gestouch.events
{
import org.gestouch.core.GestureState;
import flash.events.Event;
@ -12,7 +14,7 @@ package org.gestouch.events
public function ZoomGestureEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false,
gestureState:uint = 0,
gestureState:GestureState = null,
stageX:Number = 0, stageY:Number = 0,
localX:Number = 0, localY:Number = 0,
scaleX:Number = 1.0, scaleY:Number = 1.0)

View file

@ -9,6 +9,7 @@ package org.gestouch.gestures
import org.gestouch.core.gestouch_internal;
import org.gestouch.events.GestureStateEvent;
import flash.errors.IllegalOperationError;
import flash.events.EventDispatcher;
import flash.geom.Point;
import flash.system.Capabilities;
@ -50,7 +51,9 @@ package org.gestouch.gestures
* @see requireGestureToFail()
*/
protected var _gesturesToFail:Dictionary = new Dictionary(true);
protected var _pendingRecognizedState:uint;
protected var _pendingRecognizedState:GestureState;
use namespace gestouch_internal;
public function Gesture(target:Object = null)
@ -122,11 +125,18 @@ package org.gestouch.gestures
return;
_enabled = value;
//TODO
if (!_enabled && state != GestureState.IDLE)
if (!_enabled)
{
setState(GestureState.CANCELLED);
reset();
if (state == GestureState.POSSIBLE)
{
setState(GestureState.FAILED);
}
else
if (state == GestureState.BEGAN || state == GestureState.CHANGED)
{
setState(GestureState.CANCELLED);
}
}
}
@ -153,8 +163,8 @@ package org.gestouch.gestures
}
protected var _state:uint = GestureState.IDLE;
public function get state():uint
protected var _state:GestureState = GestureState.IDLE;
public function get state():GestureState
{
return _state;
}
@ -217,7 +227,7 @@ package org.gestouch.gestures
*/
public function reset():void
{
var state:uint = this.state;//caching getter
var state:GestureState = this.state;//caching getter
if (state == GestureState.IDLE)
return;// Do nothing as we're in IDLE and nothing to reset
@ -232,14 +242,14 @@ package org.gestouch.gestures
var gestureToFail:Gesture = key as Gesture;
gestureToFail.removeEventListener(GestureStateEvent.STATE_CHANGE, gestureToFail_stateChangeHandler);
}
_pendingRecognizedState = 0;
_pendingRecognizedState = null;
if (state == GestureState.POSSIBLE)
{
// manual reset() call. Set to FAILED to keep our State Machine clean and stable
setState(GestureState.FAILED);
}
else if (state == GestureState.BEGAN || state == GestureState.RECOGNIZED)
else if (state == GestureState.BEGAN || state == GestureState.CHANGED)
{
// manual reset() call. Set to CANCELLED to keep our State Machine clean and stable
setState(GestureState.CANCELLED);
@ -379,18 +389,19 @@ package org.gestouch.gestures
}
protected function setState(newState:uint):Boolean
protected function setState(newState:GestureState):Boolean
{
if (_state == newState && _state == GestureState.CHANGED)
{
return true;
}
//TODO: is state sequence validation needed? e.g.:
//POSSIBLE should be followed by BEGAN or RECOGNIZED or FAILED
//BEGAN should be follwed by CHANGED or ENDED or CANCELLED
//CHANGED should be followed by CHANGED or ENDED or CANCELLED
//...
if (!_state.canTransitionTo(newState))
{
throw new IllegalOperationError("You cannot change from state " +
_state + " to state " + newState + ".");
}
if (newState == GestureState.BEGAN || newState == GestureState.RECOGNIZED)
{
@ -434,10 +445,10 @@ package org.gestouch.gestures
}
}
var oldState:uint = _state;
var oldState:GestureState = _state;
_state = newState;
if (((GestureState.CANCELLED | GestureState.RECOGNIZED | GestureState.ENDED | GestureState.FAILED) & _state) > 0)
if (_state.isEndState)
{
_gesturesManager.gestouch_internal::scheduleGestureStateReset(this);
}
@ -458,7 +469,7 @@ package org.gestouch.gestures
}
gestouch_internal function setState_internal(state:uint):void
gestouch_internal function setState_internal(state:GestureState):void
{
setState(state);
}
@ -575,4 +586,4 @@ package org.gestouch.gestures
}
}
}
}
}

View file

@ -128,7 +128,7 @@ package org.gestouch.gestures
//TODO: check proper condition (behavior) on iOS native
if (_numTouchesRequiredReached)
{
if (((GestureState.BEGAN | GestureState.CHANGED) & state) > 0)
if (state == GestureState.BEGAN || state == GestureState.CHANGED)
{
updateLocation();
if (setState(GestureState.ENDED) && hasEventListener(LongPressGestureEvent.GESTURE_LONG_PRESS))