Skip to content

Commit

Permalink
TouchEvent: Optimization and docs
Browse files Browse the repository at this point in the history
Sprinkle some inline, optimize some functions for the analyzer.
  • Loading branch information
Dimensionscape committed Jul 10, 2024
1 parent 3062eca commit f0a76b1
Show file tree
Hide file tree
Showing 2 changed files with 143 additions and 87 deletions.
36 changes: 24 additions & 12 deletions src/starling/events/Touch.hx
Original file line number Diff line number Diff line change
Expand Up @@ -63,22 +63,34 @@ class Touch {
"previousGlobalY": {get: untyped __js__("function () { return this.get_previousGlobalY (); }")},
"startGlobalX": {get: untyped __js__("function () { return this.get_startGlobalX (); }")},
"startGlobalY": {get: untyped __js__("function () { return this.get_startGlobalY (); }")},
"globalX": {get: untyped __js__("function () { return this.get_globalX (); }"),
set: untyped __js__("function (v) { return this.set_globalX (v); }")},
"globalY": {get: untyped __js__("function () { return this.get_globalY (); }"),
set: untyped __js__("function (v) { return this.set_globalY (v); }")},
"tapCount": {get: untyped __js__("function () { return this.get_tapCount (); }"),
set: untyped __js__("function (v) { return this.set_tapCount (v); }")},
"globalX": {
get: untyped __js__("function () { return this.get_globalX (); }"),
set: untyped __js__("function (v) { return this.set_globalX (v); }")
},
"globalY": {
get: untyped __js__("function () { return this.get_globalY (); }"),
set: untyped __js__("function (v) { return this.set_globalY (v); }")
},
"tapCount": {
get: untyped __js__("function () { return this.get_tapCount (); }"),
set: untyped __js__("function (v) { return this.set_tapCount (v); }")
},
"phase": {get: untyped __js__("function () { return this.get_phase (); }"), set: untyped __js__("function (v) { return this.set_phase (v); }")},
"target": {get: untyped __js__("function () { return this.get_target (); }"), set: untyped __js__("function (v) { return this.set_target (v); }")},
"timestamp": {get: untyped __js__("function () { return this.get_timestamp (); }"),
set: untyped __js__("function (v) { return this.set_timestamp (v); }")},
"pressure": {get: untyped __js__("function () { return this.get_pressure (); }"),
set: untyped __js__("function (v) { return this.set_pressure (v); }")},
"timestamp": {
get: untyped __js__("function () { return this.get_timestamp (); }"),
set: untyped __js__("function (v) { return this.set_timestamp (v); }")
},
"pressure": {
get: untyped __js__("function () { return this.get_pressure (); }"),
set: untyped __js__("function (v) { return this.set_pressure (v); }")
},
"width": {get: untyped __js__("function () { return this.get_width (); }"), set: untyped __js__("function (v) { return this.set_width (v); }")},
"height": {get: untyped __js__("function () { return this.get_height (); }"), set: untyped __js__("function (v) { return this.set_height (v); }")},
"cancelled": {get: untyped __js__("function () { return this.get_cancelled (); }"),
set: untyped __js__("function (v) { return this.set_cancelled (v); }")},
"cancelled": {
get: untyped __js__("function () { return this.get_cancelled (); }"),
set: untyped __js__("function (v) { return this.set_cancelled (v); }")
},
"duration": {get: untyped __js__("function () { return this.get_duration (); }")},
"bubbleChain": {get: untyped __js__("function () { return this.get_bubbleChain (); }")},
});
Expand Down
194 changes: 119 additions & 75 deletions src/starling/events/TouchEvent.hx
Original file line number Diff line number Diff line change
Expand Up @@ -11,46 +11,51 @@ package starling.events;

import starling.display.DisplayObject;

/** A TouchEvent is triggered either by touch or mouse input.
*
* <p>In Starling, both touch events and mouse events are handled through the same class:
* TouchEvent. To process user input from a touch screen or the mouse, you have to register
* an event listener for events of the type <code>TouchEvent.TOUCH</code>. This is the only
* event type you need to handle; the long list of mouse event types as they are used in
* conventional Flash are mapped to so-called "TouchPhases" instead.</p>
/**
* A TouchEvent is triggered either by touch or mouse input.
*
* <p>The difference between mouse input and touch input is that</p>
*
* <ul>
* <li>only one mouse cursor can be present at a given moment and</li>
* <li>only the mouse can "hover" over an object without a pressed button.</li>
* </ul>
*
* <strong>Which objects receive touch events?</strong>
* <p>In Starling, both touch events and mouse events are handled through the same class:
* TouchEvent. To process user input from a touch screen or the mouse, you have to register
* an event listener for events of the type <code>TouchEvent.TOUCH</code>. This is the only
* event type you need to handle; the long list of mouse event types as they are used in
* conventional Flash are mapped to so-called "TouchPhases" instead.</p>
*
* <p>In Starling, any display object receives touch events, as long as the
* <code>touchable</code> property of the object and its parents is enabled. There
* is no "InteractiveObject" class in Starling.</p>
*
* <strong>How to work with individual touches</strong>
*
* <p>The event contains a list of all touches that are currently present. Each individual
* touch is stored in an object of type "Touch". Since you are normally only interested in
* the touches that occurred on top of certain objects, you can query the event for touches
* with a specific target:</p>
* <p>The difference between mouse input and touch input is that</p>
*
* <code>var touches:Array.&lt;Touch&gt; = touchEvent.getTouches(this);</code>
*
* <p>This will return all touches of "this" or one of its children. When you are not using
* multitouch, you can also access the touch object directly, like this:</p>
* <ul>
* <li>only one mouse cursor can be present at a given moment and</li>
* <li>only the mouse can "hover" over an object without a pressed button.</li>
* </ul>
*
* <code>var touch:Touch = touchEvent.getTouch(this);</code>
*
* @see Touch
* @see TouchPhase
* <strong>Which objects receive touch events?</strong>
*
* <p>In Starling, any display object receives touch events, as long as the
* <code>touchable</code> property of the object and its parents is enabled. There
* is no "InteractiveObject" class in Starling.</p>
*
* <strong>How to work with individual touches</strong>
*
* <p>The event contains a list of all touches that are currently present. Each individual
* touch is stored in an object of type "Touch". Since you are normally only interested in
* the touches that occurred on top of certain objects, you can query the event for touches
* with a specific target:</p>
*
* <code>var touches:Array.<Touch> = touchEvent.getTouches(this);</code>
*
* <p>This will return all touches of "this" or one of its children. When you are not using
* multitouch, you can also access the touch object directly, like this:</p>
*
* <code>var touch:Touch = touchEvent.getTouch(this);</code>
*
* @see Touch
* @see TouchPhase
*/
class TouchEvent extends Event {
/** Event type for touch or mouse input. */
/**
* Event type for touch or mouse input.
*
* @return The string "touch".
*/
public static inline var TOUCH:String = "touch";

@:noCompletion private var __shiftKey:Bool;
Expand All @@ -72,7 +77,15 @@ class TouchEvent extends Event {
}
#end

/** Creates a new TouchEvent instance. */
/**
* Creates a new TouchEvent instance.
*
* @param type The type of the event.
* @param touches An array of touches related to this event, or null if there are none.
* @param shiftKey Indicates if the shift key was pressed when the event occurred.
* @param ctrlKey Indicates if the ctrl key was pressed when the event occurred. (Mac OS: Cmd or Ctrl)
* @param bubbles Indicates if the event bubbles.
*/
public function new(type:String, touches:Array<Touch> = null, shiftKey:Bool = false, ctrlKey:Bool = false, bubbles:Bool = true) {
super(type, bubbles, touches);

Expand Down Expand Up @@ -110,32 +123,38 @@ class TouchEvent extends Event {
}
}

/** Returns a list of touches that originated over a certain target. If you pass an
/**
* Returns a list of touches that originated over a certain target. If you pass an
* <code>out</code>-Array, the touches will be added to this Array instead of creating
* a new object. */
* a new object.
*
* @param target The display object that was touched.
* @param phase The phase the touch must be in, or null if you don't care.
* @param out An array to which the touches will be added. If null, a new array will be created.
* @return An array of touches that originated over the specified target.
*/
public function getTouches(target:DisplayObject, phase:String = null, out:Array<Touch> = null):Array<Touch> {
if (out == null)
out = new Array<Touch>();
var allTouches:Array<Touch> = cast data;
var numTouches:Int = allTouches.length;

for (i in 0...numTouches) {
var touch:Touch = allTouches[i];
var correctTarget:Bool = touch.isTouching(target);
var correctPhase:Bool = (phase == null || phase == touch.phase);
var allTouches:Array<Touch> = cast data;

if (correctTarget && correctPhase)
out[out.length] = touch; // avoiding 'push'
for (touch in allTouches) {
if (touch.isTouching(target) && (phase == null || phase == touch.phase)) {
out.push(touch);
}
}

return out;
}

/** Returns a touch that originated over a certain target.
/**
* Returns a touch that originated over a certain target.
*
* @param target The object that was touched; may also be a parent of the actual
* touch-target.
* @param phase The phase the touch must be in, or null if you don't care.
* @param id The ID of the requested touch, or -1 if you don't care.
* @param target The object that was touched; may also be a parent of the actual touch-target.
* @param phase The phase the touch must be in, or null if you don't care.
* @param id The ID of the requested touch, or -1 if you don't care.
* @return The touch that originated over the specified target, or null if no such touch exists.
*/
public function getTouch(target:DisplayObject, phase:String = null, id:Int = -1):Touch {
getTouches(target, phase, sTouches);
Expand Down Expand Up @@ -164,46 +183,55 @@ class TouchEvent extends Event {
return null;
}

/** Indicates if a target is currently being touched or hovered over. */
/**
* Indicates if a target is currently being touched or hovered over.
*
* @param target The display object to check for interactions.
* @return A boolean value indicating whether the target is currently being touched or hovered over.
*/
public function interactsWith(target:DisplayObject):Bool {
var result:Bool = false;
getTouches(target, null, sTouches);

var i:Int = sTouches.length - 1;
while (i >= 0) {
var numTouches:Int = sTouches.length;
for (i in 0...numTouches) {
if (sTouches[i].phase != TouchPhase.ENDED) {
result = true;
break;
#if (haxe_ver >= 4.0)
sTouches.resize(0);
#else
ArrayUtil.resize(sTouches, 0);
#end
return true;
}
--i;
}

#if (haxe_ver >= 4.0)
sTouches.resize(0);
#if (haxe_ver >= 4.0)
sTouches.resize(0);
#else
ArrayUtil.resize(sTouches, 0);
#end
return result;
return false;
}

// custom dispatching

/** @private
/**
* @private
* Dispatches the event along a custom bubble chain. During the lifetime of the event,
* each object is visited only once. */
* each object is visited only once.
*
* @param chain An array of EventDispatcher objects representing the bubble chain.
*/
public function dispatch(chain:Array<EventDispatcher>):Void {
if (chain != null && chain.length != 0) {
var chainLength:Int = bubbles ? chain.length : 1;
var previousTarget:EventDispatcher = target;
setTarget(chain[0]);

for (i in 0...chainLength) {
if (chain[i] == null)
continue;
var chainElement:EventDispatcher = cast(chain[i], EventDispatcher);
if (__visitedObjects.indexOf(chainElement) == -1) {
if (chainElement != null && __visitedObjects.indexOf(chainElement) == -1) {
var stopPropagation:Bool = chainElement.__invokeEvent(this);
__visitedObjects[__visitedObjects.length] = chainElement;
__visitedObjects.push(chainElement);
if (stopPropagation)
break;
}
Expand All @@ -215,32 +243,48 @@ class TouchEvent extends Event {

// properties

/** The time the event occurred (in seconds since application launch). */
/**
* The time the event occurred (in seconds since application launch).
*
* @return The time the event occurred, in seconds since application launch.
*/
public var timestamp(get, never):Float;

private function get_timestamp():Float {
private inline function get_timestamp():Float {
return __timestamp;
}

/** All touches that are currently available. */
/**
* All touches that are currently available.
*
* @return An array of all currently available touches.
*/
public var touches(get, never):Array<Touch>;

private function get_touches():Array<Touch> {
private inline function get_touches():Array<Touch> {
var touches:Array<Touch> = cast data;
return touches.concat();
return touches.copy();
}

/** Indicates if the shift key was pressed when the event occurred. */
/**
* Indicates if the shift key was pressed when the event occurred.
*
* @return A boolean value indicating whether the shift key was pressed.
*/
public var shiftKey(get, never):Bool;

private function get_shiftKey():Bool {
private inline function get_shiftKey():Bool {
return __shiftKey;
}

/** Indicates if the ctrl key was pressed when the event occurred. (Mac OS: Cmd or Ctrl) */
/**
* Indicates if the ctrl key was pressed when the event occurred. (Mac OS: Cmd or Ctrl)
*
* @return A boolean value indicating whether the ctrl key was pressed.
*/
public var ctrlKey(get, never):Bool;

private function get_ctrlKey():Bool {
private inline function get_ctrlKey():Bool {
return __ctrlKey;
}
}

0 comments on commit f0a76b1

Please sign in to comment.