1 /*
   2  * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javafx.scene.input;
  27 
  28 import com.sun.javafx.pgstub.StubScene;
  29 import java.util.ArrayList;
  30 import java.util.Arrays;
  31 import java.util.Random;
  32 import javafx.event.Event;
  33 import javafx.scene.Group;
  34 import javafx.scene.Scene;
  35 import javafx.scene.shape.Rectangle;
  36 import javafx.stage.Stage;
  37 import javafx.event.EventHandler;
  38 import javafx.geometry.Point3D;
  39 import org.junit.Assert;
  40 import org.junit.Ignore;
  41 import org.junit.Test;
  42 import static org.junit.Assert.*;
  43 
  44 public class TouchEventTest {
  45     private static final int SANE_BENCHMARK_CYCLES = 1000000;
  46     private static final int CRAZY_BENCHMARK_CYCLES = 500000;
  47 
  48     private int touched;
  49 
  50     @Test public void testTouchPointConstructor() {
  51         Rectangle node = new Rectangle();
  52         node.setTranslateX(3);
  53         node.setTranslateY(2);
  54         node.setTranslateZ(50);
  55         PickResult pickRes = new PickResult(node, new Point3D(15, 25, 100), 33);
  56         TouchPoint tp = new TouchPoint(2, TouchPoint.State.STATIONARY,
  57                 10, 20, 30, 40, node, pickRes);
  58 
  59         assertEquals(2, tp.getId());
  60         assertSame(TouchPoint.State.STATIONARY, tp.getState());
  61         assertEquals(18, tp.getX(), 10e-20);
  62         assertEquals(27, tp.getY(), 10e-20);
  63         assertEquals(150, tp.getZ(), 10e-20);
  64         assertEquals(10, tp.getSceneX(), 10e-20);
  65         assertEquals(20, tp.getSceneY(), 10e-20);
  66         assertEquals(30, tp.getScreenX(), 10e-20);
  67         assertEquals(40, tp.getScreenY(), 10e-20);
  68         assertSame(node, tp.getTarget());
  69         assertSame(pickRes, tp.getPickResult());
  70     }
  71 
  72     @Test public void testTouchPointConstructorWithoutPickResult() {
  73         Rectangle node = new Rectangle();
  74         TouchPoint tp = new TouchPoint(2, TouchPoint.State.STATIONARY,
  75                 10, 20, 30, 40, node, null);
  76 
  77         assertEquals(10, tp.getX(), 10e-20);
  78         assertEquals(20, tp.getY(), 10e-20);
  79         assertEquals(0, tp.getZ(), 10e-20);
  80         assertEquals(10, tp.getSceneX(), 10e-20);
  81         assertEquals(20, tp.getSceneY(), 10e-20);
  82         assertEquals(30, tp.getScreenX(), 10e-20);
  83         assertEquals(40, tp.getScreenY(), 10e-20);
  84         assertNotNull(tp.getPickResult());
  85         assertNotNull(tp.getPickResult().getIntersectedPoint());
  86         assertEquals(10, tp.getPickResult().getIntersectedPoint().getX(), 10e-20);
  87         assertEquals(20, tp.getPickResult().getIntersectedPoint().getY(), 10e-20);
  88         assertEquals(0, tp.getPickResult().getIntersectedPoint().getZ(), 10e-20);
  89     }
  90 
  91     @Test public void testShortConstructor() {
  92         Rectangle node = new Rectangle();
  93         node.setTranslateX(3);
  94         node.setTranslateY(2);
  95         node.setTranslateZ(50);
  96 
  97         PickResult pickRes1 = new PickResult(node, new Point3D(15, 25, 100), 33);
  98         PickResult pickRes2 = new PickResult(node, new Point3D(16, 26, 101), 33);
  99         TouchPoint tp1 = new TouchPoint(2, TouchPoint.State.STATIONARY, 10, 20, 30, 40, node, pickRes1);
 100         TouchPoint tp2 = new TouchPoint(3, TouchPoint.State.PRESSED, 11, 21, 31, 41, node, pickRes2);
 101 
 102         TouchEvent e = new TouchEvent(
 103                 TouchEvent.TOUCH_PRESSED, tp2,
 104                 new ArrayList<>(Arrays.asList(tp1, tp2)), 158,
 105                 false, true, false, true);
 106 
 107         assertSame(TouchEvent.TOUCH_PRESSED, e.getEventType());
 108         assertSame(tp2, e.getTouchPoint());
 109         assertEquals(2, e.getTouchPoints().size());
 110         assertSame(tp1, e.getTouchPoints().get(0));
 111         assertSame(tp2, e.getTouchPoints().get(1));
 112         assertEquals(158, e.getEventSetId());
 113         assertFalse(e.isShiftDown());
 114         assertTrue(e.isControlDown());
 115         assertFalse(e.isAltDown());
 116         assertTrue(e.isMetaDown());
 117         assertSame(Event.NULL_SOURCE_TARGET, e.getSource());
 118         assertSame(Event.NULL_SOURCE_TARGET, e.getTarget());
 119         assertFalse(e.isConsumed());
 120 
 121         e = new TouchEvent(
 122                 TouchEvent.TOUCH_PRESSED, tp2,
 123                 new ArrayList<>(Arrays.asList(tp1, tp2)), 158,
 124                 true, false, true, false);
 125         assertTrue(e.isShiftDown());
 126         assertFalse(e.isControlDown());
 127         assertTrue(e.isAltDown());
 128         assertFalse(e.isMetaDown());
 129     }
 130 
 131     @Test public void testLongConstructor() {
 132         Rectangle node = new Rectangle(10, 10);
 133         node.setTranslateX(3);
 134         node.setTranslateY(2);
 135         node.setTranslateZ(50);
 136         Rectangle n1 = new Rectangle(10, 10);
 137         Rectangle n2 = new Rectangle(10, 10);
 138 
 139         PickResult pickRes1 = new PickResult(node, new Point3D(15, 25, 100), 33);
 140         PickResult pickRes2 = new PickResult(node, new Point3D(16, 26, 101), 33);
 141         TouchPoint tp1 = new TouchPoint(2, TouchPoint.State.STATIONARY, 10, 20, 30, 40, node, pickRes1);
 142         TouchPoint tp2 = new TouchPoint(3, TouchPoint.State.PRESSED, 11, 21, 31, 41, node, pickRes2);
 143 
 144         TouchEvent e = new TouchEvent(n1, n2,
 145                 TouchEvent.TOUCH_PRESSED, tp2,
 146                 new ArrayList<>(Arrays.asList(tp1, tp2)), 158,
 147                 false, true, false, true);
 148 
 149         assertSame(n1, e.getSource());
 150         assertSame(n2, e.getTarget());
 151         assertSame(TouchEvent.TOUCH_PRESSED, e.getEventType());
 152         assertSame(tp2, e.getTouchPoint());
 153         assertEquals(2, e.getTouchPoints().size());
 154         assertSame(tp1, e.getTouchPoints().get(0));
 155         assertSame(tp2, e.getTouchPoints().get(1));
 156         assertEquals(158, e.getEventSetId());
 157         assertFalse(e.isShiftDown());
 158         assertTrue(e.isControlDown());
 159         assertFalse(e.isAltDown());
 160         assertTrue(e.isMetaDown());
 161         assertFalse(e.isConsumed());
 162 
 163         e = new TouchEvent(n1, n2,
 164                 TouchEvent.TOUCH_PRESSED, tp2,
 165                 new ArrayList<>(Arrays.asList(tp1, tp2)), 158,
 166                 true, false, true, false);
 167         assertTrue(e.isShiftDown());
 168         assertFalse(e.isControlDown());
 169         assertTrue(e.isAltDown());
 170         assertFalse(e.isMetaDown());
 171     }
 172 
 173     @Test
 174     public void shouldPassModifiers() {
 175         Scene scene = createScene();
 176         Rectangle rect =
 177                 (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(0);
 178 
 179         touched = 0;
 180         rect.addEventHandler(TouchEvent.ANY, event -> {
 181             touched++;
 182             switch(touched) {
 183                 case 1:
 184                     Assert.assertEquals(true, event.isShiftDown());
 185                     Assert.assertEquals(false, event.isControlDown());
 186                     Assert.assertEquals(true, event.isAltDown());
 187                     Assert.assertEquals(false, event.isMetaDown());
 188                     break;
 189                 case 2:
 190                     Assert.assertEquals(false, event.isShiftDown());
 191                     Assert.assertEquals(true, event.isControlDown());
 192                     Assert.assertEquals(false, event.isAltDown());
 193                     Assert.assertEquals(true, event.isMetaDown());
 194                     break;
 195                 case 3:
 196                     Assert.assertEquals(false, event.isShiftDown());
 197                     Assert.assertEquals(true, event.isControlDown());
 198                     Assert.assertEquals(true, event.isAltDown());
 199                     Assert.assertEquals(false, event.isMetaDown());
 200                     break;
 201                 default:
 202                     fail("Wrong touch point id " + event.getTouchPoint().getId());
 203             }
 204         });
 205 
 206         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 207                 System.currentTimeMillis(), 1, true, true, false, true, false);
 208         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 209                 TouchPoint.State.PRESSED, 1, 110, 110, 110, 110);
 210         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 211 
 212         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 213                 System.currentTimeMillis(), 1, true, false, true, false, true);
 214         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 215                 TouchPoint.State.STATIONARY, 1, 110, 110, 110, 110);
 216         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 217 
 218         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 219                 System.currentTimeMillis(), 1, true, false, true, true, false);
 220         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 221                 TouchPoint.State.RELEASED, 1, 110, 110, 110, 110);
 222         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 223 
 224         assertEquals(3, touched);
 225     }
 226 
 227     @Test
 228     public void shouldCountTouchesCorrectly() {
 229         Scene scene = createScene();
 230         Rectangle rect =
 231                 (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(0);
 232 
 233         touched = 0;
 234         rect.addEventHandler(TouchEvent.ANY, event -> {
 235             touched++;
 236             switch(touched) {
 237                 case 1:
 238                     Assert.assertEquals(1, event.getTouchCount());
 239                     Assert.assertEquals(1, event.getTouchPoints().size());
 240                     break;
 241                 case 2:
 242                 case 3:
 243                     Assert.assertEquals(2, event.getTouchCount());
 244                     Assert.assertEquals(2, event.getTouchPoints().size());
 245                     break;
 246                 case 4:
 247                 case 5:
 248                     Assert.assertEquals(2, event.getTouchCount());
 249                     Assert.assertEquals(2, event.getTouchPoints().size());
 250                     break;
 251                 case 6:
 252                     Assert.assertEquals(1, event.getTouchCount());
 253                     Assert.assertEquals(1, event.getTouchPoints().size());
 254                     break;
 255                 default:
 256                     fail("Wrong touch point id " + event.getTouchPoint().getId());
 257             }
 258         });
 259 
 260         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 261                 System.currentTimeMillis(), 1, true, true, false, true, false);
 262         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 263                 TouchPoint.State.PRESSED, 1, 110, 110, 110, 110);
 264         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 265 
 266         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 267                 System.currentTimeMillis(), 2, true, false, true, false, true);
 268         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 269                 TouchPoint.State.STATIONARY, 1, 110, 110, 110, 110);
 270         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 271                 TouchPoint.State.PRESSED, 2, 120, 120, 110, 110);
 272         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 273 
 274         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 275                 System.currentTimeMillis(), 2, true, false, true, true, false);
 276         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 277                 TouchPoint.State.STATIONARY, 1, 110, 110, 110, 110);
 278         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 279                 TouchPoint.State.RELEASED, 2, 120, 120, 110, 110);
 280         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 281 
 282         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 283                 System.currentTimeMillis(), 1, true, false, true, true, false);
 284         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 285                 TouchPoint.State.RELEASED, 1, 110, 110, 110, 110);
 286         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 287 
 288         assertEquals(6, touched);
 289     }
 290 
 291     @Test
 292     public void shouldGenerateCorrectEventSetIDs() {
 293         Scene scene = createScene();
 294         Rectangle rect =
 295                 (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(0);
 296 
 297         touched = 0;
 298         rect.addEventHandler(TouchEvent.ANY, event -> {
 299             touched++;
 300             switch(touched) {
 301                 case 1:
 302                     Assert.assertEquals(1, event.getEventSetId());
 303                     break;
 304                 case 2:
 305                 case 3:
 306                     Assert.assertEquals(2, event.getEventSetId());
 307                     break;
 308                 case 4:
 309                 case 5:
 310                     Assert.assertEquals(3, event.getEventSetId());
 311                     break;
 312                 case 6:
 313                     Assert.assertEquals(4, event.getEventSetId());
 314                     break;
 315                 default:
 316                     fail("Wrong touch point id " + event.getTouchPoint().getId());
 317             }
 318         });
 319 
 320         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 321                 System.currentTimeMillis(), 1, true, true, false, true, false);
 322         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 323                 TouchPoint.State.PRESSED, 1, 110, 110, 110, 110);
 324         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 325 
 326         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 327                 System.currentTimeMillis(), 2, true, false, true, false, true);
 328         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 329                 TouchPoint.State.STATIONARY, 1, 110, 110, 110, 110);
 330         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 331                 TouchPoint.State.PRESSED, 2, 120, 120, 110, 110);
 332         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 333 
 334         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 335                 System.currentTimeMillis(), 2, true, false, true, true, false);
 336         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 337                 TouchPoint.State.STATIONARY, 1, 110, 110, 110, 110);
 338         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 339                 TouchPoint.State.RELEASED, 2, 120, 120, 110, 110);
 340         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 341 
 342         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 343                 System.currentTimeMillis(), 1, true, false, true, true, false);
 344         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 345                 TouchPoint.State.RELEASED, 1, 110, 110, 110, 110);
 346         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 347 
 348         assertEquals(6, touched);
 349     }
 350 
 351     @Test
 352     public void shouldReIDTouchPoints() {
 353         Scene scene = createScene();
 354         Rectangle rect =
 355                 (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(0);
 356 
 357         touched = 0;
 358         rect.setOnTouchPressed(event -> {
 359             touched++;
 360             switch(event.getTouchPoint().getId()) {
 361                 case 1:
 362                     Assert.assertEquals(110.0, event.getTouchPoint().getX(), 0.0001);
 363                     Assert.assertEquals(110.0, event.getTouchPoint().getY(), 0.0001);
 364                     assertEquals(1, touched);
 365                     break;
 366                 case 2:
 367                     Assert.assertEquals(120.0, event.getTouchPoint().getX(), 0.0001);
 368                     Assert.assertEquals(120.0, event.getTouchPoint().getY(), 0.0001);
 369                     assertEquals(2, touched);
 370                     break;
 371                 case 3:
 372                     Assert.assertEquals(130.0, event.getTouchPoint().getX(), 0.0001);
 373                     Assert.assertEquals(130.0, event.getTouchPoint().getY(), 0.0001);
 374                     assertEquals(3, touched);
 375                     break;
 376                 default:
 377                     fail("Wrong touch point id " + event.getTouchPoint().getId());
 378             }
 379         });
 380 
 381         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 382                 System.currentTimeMillis(), 3, true, false, false, false, false);
 383         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 384                 TouchPoint.State.PRESSED, 1368, 110, 110, 110, 110);
 385         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 386                 TouchPoint.State.PRESSED, 1, 120, 120, 120, 120);
 387         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 388                 TouchPoint.State.PRESSED, 152, 130, 130, 130, 130);
 389         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 390 
 391         assertEquals(3, touched);
 392     }
 393 
 394     @Test
 395     public void shouldNotReuseTouchPointID() {
 396         Scene scene = createScene();
 397         Rectangle rect =
 398                 (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(0);
 399 
 400         touched = 0;
 401         rect.setOnTouchPressed(event -> {
 402             touched++;
 403             switch(event.getTouchPoint().getId()) {
 404                 case 1:
 405                     Assert.assertEquals(110.0, event.getTouchPoint().getX(), 0.0001);
 406                     Assert.assertEquals(110.0, event.getTouchPoint().getY(), 0.0001);
 407                     assertEquals(1, touched);
 408                     break;
 409                 case 2:
 410                     Assert.assertEquals(120.0, event.getTouchPoint().getX(), 0.0001);
 411                     Assert.assertEquals(120.0, event.getTouchPoint().getY(), 0.0001);
 412                     assertEquals(2, touched);
 413                     break;
 414                 case 3:
 415                     Assert.assertEquals(130.0, event.getTouchPoint().getX(), 0.0001);
 416                     Assert.assertEquals(130.0, event.getTouchPoint().getY(), 0.0001);
 417                     assertEquals(3, touched);
 418                     break;
 419                 default:
 420                     fail("Wrong touch point id " + event.getTouchPoint().getId());
 421             }
 422         });
 423 
 424         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 425                 System.currentTimeMillis(), 2, true, false, false, false, false);
 426         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 427                 TouchPoint.State.PRESSED, 1368, 110, 110, 110, 110);
 428         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 429                 TouchPoint.State.PRESSED, 1, 120, 120, 120, 120);
 430         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 431 
 432         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 433                 System.currentTimeMillis(), 2, true, false, false, false, false);
 434         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 435                 TouchPoint.State.STATIONARY, 1368, 110, 110, 110, 110);
 436         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 437                 TouchPoint.State.RELEASED, 1, 120, 120, 120, 120);
 438         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 439 
 440         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 441                 System.currentTimeMillis(), 2, true, false, false, false, false);
 442         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 443                 TouchPoint.State.STATIONARY, 1368, 110, 110, 110, 110);
 444         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 445                 TouchPoint.State.PRESSED, 1, 130, 130, 130, 130);
 446         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 447 
 448         assertEquals(3, touched);
 449     }
 450 
 451     @Test
 452     public void shouldMaintainPressOrder() {
 453         Scene scene = createScene();
 454         Rectangle rect =
 455                 (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(0);
 456 
 457         touched = 0;
 458         rect.setOnTouchPressed(event -> {
 459             touched++;
 460             switch(event.getTouchPoint().getId()) {
 461                 case 1:
 462                     Assert.assertEquals(110.0, event.getTouchPoint().getX(), 0.0001);
 463                     Assert.assertEquals(110.0, event.getTouchPoint().getY(), 0.0001);
 464                     Assert.assertEquals(1, event.getTouchPoints().get(0).getId());
 465                     Assert.assertEquals(2, event.getTouchPoints().get(1).getId());
 466                     assertEquals(1, touched);
 467                     break;
 468                 case 2:
 469                     Assert.assertEquals(120.0, event.getTouchPoint().getX(), 0.0001);
 470                     Assert.assertEquals(120.0, event.getTouchPoint().getY(), 0.0001);
 471                     Assert.assertEquals(1, event.getTouchPoints().get(0).getId());
 472                     Assert.assertEquals(2, event.getTouchPoints().get(1).getId());
 473                     assertEquals(2, touched);
 474                     break;
 475                 case 3:
 476                     Assert.assertEquals(130.0, event.getTouchPoint().getX(), 0.0001);
 477                     Assert.assertEquals(130.0, event.getTouchPoint().getY(), 0.0001);
 478                     Assert.assertEquals(1, event.getTouchPoints().get(0).getId());
 479                     Assert.assertEquals(3, event.getTouchPoints().get(1).getId());
 480                     assertEquals(3, touched);
 481                     break;
 482                 default:
 483                     fail("Wrong touch point id " + event.getTouchPoint().getId());
 484             }
 485         });
 486 
 487         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 488                 System.currentTimeMillis(), 2, true, false, false, false, false);
 489         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 490                 TouchPoint.State.PRESSED, 1368, 110, 110, 110, 110);
 491         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 492                 TouchPoint.State.PRESSED, 1, 120, 120, 120, 120);
 493         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 494 
 495         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 496                 System.currentTimeMillis(), 2, true, false, false, false, false);
 497         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 498                 TouchPoint.State.RELEASED, 1, 120, 120, 120, 120);
 499         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 500                 TouchPoint.State.STATIONARY, 1368, 110, 110, 110, 110);
 501         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 502 
 503         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 504                 System.currentTimeMillis(), 2, true, false, false, false, false);
 505         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 506                 TouchPoint.State.PRESSED, 1, 130, 130, 130, 130);
 507         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 508                 TouchPoint.State.STATIONARY, 1368, 110, 110, 110, 110);
 509         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 510 
 511         assertEquals(3, touched);
 512     }
 513 
 514     @Test
 515     public void shouldMaintainIDMapping() {
 516         Scene scene = createScene();
 517         Rectangle rect =
 518                 (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(0);
 519 
 520         touched = 0;
 521         rect.setOnTouchPressed(event -> {
 522             touched++;
 523             switch(event.getTouchPoint().getId()) {
 524                 case 1:
 525                     Assert.assertEquals(110.0, event.getTouchPoint().getX(), 0.0001);
 526                     Assert.assertEquals(110.0, event.getTouchPoint().getY(), 0.0001);
 527                     Assert.assertEquals(1, event.getTouchPoints().get(0).getId());
 528                     Assert.assertEquals(2, event.getTouchPoints().get(1).getId());
 529                     assertEquals(1, touched);
 530                     break;
 531                 case 2:
 532                     Assert.assertEquals(120.0, event.getTouchPoint().getX(), 0.0001);
 533                     Assert.assertEquals(120.0, event.getTouchPoint().getY(), 0.0001);
 534                     Assert.assertEquals(1, event.getTouchPoints().get(0).getId());
 535                     Assert.assertEquals(2, event.getTouchPoints().get(1).getId());
 536                     assertEquals(2, touched);
 537                     break;
 538                 default:
 539                     fail("Wrong touch point id " + event.getTouchPoint().getId());
 540             }
 541         });
 542 
 543         rect.setOnTouchMoved(event -> {
 544             touched++;
 545             switch(event.getTouchPoint().getId()) {
 546                 case 1:
 547                     Assert.assertEquals(120.0, event.getTouchPoint().getX(), 0.0001);
 548                     Assert.assertEquals(120.0, event.getTouchPoint().getY(), 0.0001);
 549                     Assert.assertEquals(1, event.getTouchPoints().get(0).getId());
 550                     Assert.assertEquals(2, event.getTouchPoints().get(1).getId());
 551                     assertEquals(3, touched);
 552                     break;
 553                 case 2:
 554                     Assert.assertEquals(110.0, event.getTouchPoint().getX(), 0.0001);
 555                     Assert.assertEquals(110.0, event.getTouchPoint().getY(), 0.0001);
 556                     Assert.assertEquals(1, event.getTouchPoints().get(0).getId());
 557                     Assert.assertEquals(2, event.getTouchPoints().get(1).getId());
 558                     assertEquals(4, touched);
 559                     break;
 560                 default:
 561                     fail("Wrong touch point id " + event.getTouchPoint().getId());
 562             }
 563         });
 564 
 565         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 566                 System.currentTimeMillis(), 2, true, false, false, false, false);
 567         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 568                 TouchPoint.State.PRESSED, 1368, 110, 110, 110, 110);
 569         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 570                 TouchPoint.State.PRESSED, 127, 120, 120, 120, 120);
 571         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 572 
 573         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 574                 System.currentTimeMillis(), 2, true, false, false, false, false);
 575         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 576                 TouchPoint.State.MOVED, 127, 110, 110, 110, 110);
 577         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 578                 TouchPoint.State.MOVED, 1368, 120, 120, 120, 120);
 579         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 580 
 581         assertEquals(4, touched);
 582     }
 583 
 584     @Test
 585     public void shouldMaintainIDMappingInDynamicConditions() {
 586         Scene scene = createScene();
 587         Rectangle rect =
 588                 (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(0);
 589 
 590         touched = 0;
 591         rect.setOnTouchPressed(event -> {
 592             touched++;
 593             switch(event.getTouchPoint().getId()) {
 594                 case 1:
 595                     Assert.assertEquals(110.0, event.getTouchPoint().getX(), 0.0001);
 596                     Assert.assertEquals(110.0, event.getTouchPoint().getY(), 0.0001);
 597                     Assert.assertEquals(1, event.getTouchPoints().get(0).getId());
 598                     Assert.assertEquals(2, event.getTouchPoints().get(1).getId());
 599                     assertEquals(1, touched);
 600                     break;
 601                 case 2:
 602                     Assert.assertEquals(120.0, event.getTouchPoint().getX(), 0.0001);
 603                     Assert.assertEquals(120.0, event.getTouchPoint().getY(), 0.0001);
 604                     Assert.assertEquals(1, event.getTouchPoints().get(0).getId());
 605                     Assert.assertEquals(2, event.getTouchPoints().get(1).getId());
 606                     assertEquals(2, touched);
 607                     break;
 608                 case 3:
 609                     Assert.assertEquals(160.0, event.getTouchPoint().getX(), 0.0001);
 610                     Assert.assertEquals(160.0, event.getTouchPoint().getY(), 0.0001);
 611                     Assert.assertEquals(2, event.getTouchPoints().get(0).getId());
 612                     Assert.assertEquals(3, event.getTouchPoints().get(1).getId());
 613                     assertEquals(3, touched);
 614                     break;
 615                 default:
 616                     fail("Wrong touch point id " + event.getTouchPoint().getId());
 617             }
 618         });
 619 
 620         rect.setOnTouchMoved(event -> {
 621             touched++;
 622             switch(event.getTouchPoint().getId()) {
 623                 case 2:
 624                     Assert.assertEquals(120.0, event.getTouchPoint().getX(), 0.0001);
 625                     Assert.assertEquals(120.0, event.getTouchPoint().getY(), 0.0001);
 626                     Assert.assertEquals(2, event.getTouchPoints().get(0).getId());
 627                     Assert.assertEquals(3, event.getTouchPoints().get(1).getId());
 628                     assertEquals(4, touched);
 629                     break;
 630                 case 3:
 631                     Assert.assertEquals(160.0, event.getTouchPoint().getX(), 0.0001);
 632                     Assert.assertEquals(160.0, event.getTouchPoint().getY(), 0.0001);
 633                     Assert.assertEquals(2, event.getTouchPoints().get(0).getId());
 634                     Assert.assertEquals(3, event.getTouchPoints().get(1).getId());
 635                     assertEquals(5, touched);
 636                     break;
 637                 default:
 638                     fail("Wrong touch point id " + event.getTouchPoint().getId());
 639             }
 640         });
 641 
 642         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 643                 System.currentTimeMillis(), 2, true, false, false, false, false);
 644         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 645                 TouchPoint.State.PRESSED, 1368, 110, 110, 110, 110);
 646         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 647                 TouchPoint.State.PRESSED, 127, 120, 120, 120, 120);
 648         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 649 
 650         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 651                 System.currentTimeMillis(), 2, true, false, false, false, false);
 652         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 653                 TouchPoint.State.STATIONARY, 127, 120, 120, 120, 120);
 654         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 655                 TouchPoint.State.RELEASED, 1368, 120, 120, 120, 120);
 656         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 657 
 658         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 659                 System.currentTimeMillis(), 2, true, false, false, false, false);
 660         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 661                 TouchPoint.State.PRESSED, 11, 160, 160, 160, 160);
 662         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 663                 TouchPoint.State.STATIONARY, 127, 120, 120, 120, 120);
 664         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 665 
 666         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 667                 System.currentTimeMillis(), 2, true, false, false, false, false);
 668         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 669                 TouchPoint.State.MOVED, 11, 160, 160, 160, 160);
 670         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 671                 TouchPoint.State.MOVED, 127, 120, 120, 120, 120);
 672         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 673 
 674         assertEquals(5, touched);
 675     }
 676 
 677     @Test
 678     public void shouldResetIDsAfterGesture() {
 679         Scene scene = createScene();
 680         Rectangle rect =
 681                 (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(0);
 682 
 683         touched = 0;
 684         rect.addEventHandler(TouchEvent.ANY, event -> {
 685             touched++;
 686             switch(touched) {
 687                 case 1:
 688                 case 2:
 689                     Assert.assertEquals(1, event.getEventSetId());
 690                     Assert.assertEquals(touched, event.getTouchPoint().getId());
 691                     break;
 692                 case 3:
 693                 case 4:
 694                     Assert.assertEquals(2, event.getEventSetId());
 695                     Assert.assertEquals(touched - 2, event.getTouchPoint().getId());
 696                     break;
 697                 case 5:
 698                 case 6:
 699                     Assert.assertEquals(1, event.getEventSetId());
 700                     Assert.assertEquals(touched - 4, event.getTouchPoint().getId());
 701                     break;
 702                 case 7:
 703                 case 8:
 704                     Assert.assertEquals(2, event.getEventSetId());
 705                     Assert.assertEquals(touched - 6, event.getTouchPoint().getId());
 706                     break;
 707                 default:
 708                     fail("Wrong touch point id " + event.getTouchPoint().getId());
 709             }
 710         });
 711 
 712         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 713                 System.currentTimeMillis(), 2, true, true, false, true, false);
 714         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 715                 TouchPoint.State.PRESSED, 1, 110, 110, 110, 110);
 716         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 717                 TouchPoint.State.PRESSED, 2, 120, 120, 110, 110);
 718         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 719 
 720         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 721                 System.currentTimeMillis(), 2, true, false, true, true, false);
 722         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 723                 TouchPoint.State.RELEASED, 1, 110, 110, 110, 110);
 724         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 725                 TouchPoint.State.RELEASED, 2, 120, 120, 110, 110);
 726         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 727 
 728         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 729                 System.currentTimeMillis(), 2, true, true, false, true, false);
 730         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 731                 TouchPoint.State.PRESSED, 1, 110, 110, 110, 110);
 732         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 733                 TouchPoint.State.PRESSED, 2, 120, 120, 110, 110);
 734         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 735 
 736         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 737                 System.currentTimeMillis(), 2, true, false, true, true, false);
 738         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 739                 TouchPoint.State.RELEASED, 1, 110, 110, 110, 110);
 740         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 741                 TouchPoint.State.RELEASED, 2, 120, 120, 110, 110);
 742         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 743 
 744 
 745         assertEquals(8, touched);
 746     }
 747 
 748     @Test
 749     public void touchPointsShouldContainTouchPoint() {
 750         Scene scene = createScene();
 751         Rectangle rect =
 752                 (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(0);
 753 
 754         touched = 0;
 755         rect.addEventHandler(TouchEvent.ANY, event -> {
 756             touched++;
 757             switch(touched) {
 758                 case 1:
 759                 case 3:
 760                     assertSame(event.getTouchPoint(), event.getTouchPoints().get(0));
 761                     break;
 762                 case 2:
 763                 case 4:
 764                     assertSame(event.getTouchPoint(), event.getTouchPoints().get(1));
 765                     break;
 766                 default:
 767                     fail("Wrong touch point id " + event.getTouchPoint().getId());
 768             }
 769         });
 770 
 771         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 772                 System.currentTimeMillis(), 2, true, true, false, true, false);
 773         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 774                 TouchPoint.State.PRESSED, 1, 110, 110, 110, 110);
 775         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 776                 TouchPoint.State.PRESSED, 2, 120, 120, 110, 110);
 777         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 778 
 779         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 780                 System.currentTimeMillis(), 2, true, true, false, true, false);
 781         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 782                 TouchPoint.State.RELEASED, 1, 110, 110, 110, 110);
 783         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 784                 TouchPoint.State.RELEASED, 2, 120, 120, 110, 110);
 785         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 786 
 787         assertEquals(4, touched);
 788     }
 789 
 790     @Test
 791     public void touchPointsShouldHaveCorrectTarget() {
 792         Scene scene = createScene();
 793 
 794         final Rectangle rect1 =
 795                 (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(0);
 796 
 797         final Rectangle rect2 =
 798                 (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(1);
 799 
 800         touched = 0;
 801         rect1.addEventHandler(TouchEvent.ANY, event -> {
 802             touched++;
 803             assertSame(rect1, event.getTouchPoint().getTarget());
 804             assertSame(rect2, event.getTouchPoints().get(1).getTarget());
 805         });
 806         rect2.addEventHandler(TouchEvent.ANY, event -> {
 807             touched++;
 808             assertSame(rect2, event.getTouchPoint().getTarget());
 809             assertSame(rect1, event.getTouchPoints().get(0).getTarget());
 810         });
 811 
 812         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 813                 System.currentTimeMillis(), 2, true, true, false, true, false);
 814         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 815                 TouchPoint.State.PRESSED, 1, 110, 110, 110, 110);
 816         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 817                 TouchPoint.State.PRESSED, 2, 220, 220, 220, 220);
 818         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 819 
 820         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 821                 System.currentTimeMillis(), 2, true, true, false, true, false);
 822         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 823                 TouchPoint.State.RELEASED, 1, 110, 110, 110, 110);
 824         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 825                 TouchPoint.State.RELEASED, 2, 220, 220, 220, 220);
 826         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 827 
 828         assertEquals(4, touched);
 829     }
 830 
 831     @Test
 832     public void shouldCompute3dCoordinates() {
 833         Scene scene = createScene();
 834         Rectangle rect =
 835                 (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(0);
 836         rect.setTranslateZ(50);
 837 
 838         touched = 0;
 839         rect.addEventHandler(TouchEvent.ANY, event -> {
 840             touched++;
 841             Assert.assertEquals(110, event.getTouchPoint().getX(), 0.00001);
 842             Assert.assertEquals(110, event.getTouchPoint().getY(), 0.00001);
 843             Assert.assertEquals(0, event.getTouchPoint().getZ(), 0.00001);
 844         });
 845 
 846         scene.addEventHandler(TouchEvent.ANY, event -> {
 847             touched++;
 848             Assert.assertEquals(110, event.getTouchPoint().getX(), 0.00001);
 849             Assert.assertEquals(110, event.getTouchPoint().getY(), 0.00001);
 850             Assert.assertEquals(50, event.getTouchPoint().getZ(), 0.00001);
 851         });
 852 
 853         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 854                 System.currentTimeMillis(), 1, true, true, false, true, false);
 855         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 856                 TouchPoint.State.PRESSED, 1, 110, 110, 110, 110);
 857         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 858 
 859         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 860                 System.currentTimeMillis(), 1, true, false, true, false, true);
 861         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 862                 TouchPoint.State.STATIONARY, 1, 110, 110, 110, 110);
 863         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 864 
 865         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 866                 System.currentTimeMillis(), 1, true, false, true, true, false);
 867         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 868                 TouchPoint.State.RELEASED, 1, 110, 110, 110, 110);
 869         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 870 
 871         assertEquals(6, touched);
 872     }
 873 
 874     @Test
 875     public void touchPointsShouldHaveCorrectPickResult() {
 876         Scene scene = createScene();
 877 
 878         final Rectangle rect1 =
 879                 (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(0);
 880 
 881         final Rectangle rect2 =
 882                 (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(1);
 883 
 884         touched = 0;
 885         rect1.addEventHandler(TouchEvent.ANY, event -> {
 886             touched++;
 887             assertSame(rect1, event.getTouchPoint().getTarget());
 888             assertSame(rect2, event.getTouchPoints().get(1).getTarget());
 889             PickResult res1 = event.getTouchPoint().getPickResult();
 890             PickResult res2 = event.getTouchPoints().get(1).getPickResult();
 891             switch(touched) {
 892                 case 1:
 893                     assertNotNull(res1);
 894                     assertSame(rect1, res1.getIntersectedNode());
 895                     assertEquals(110, res1.getIntersectedPoint().getX(), 0.00001);
 896                     assertEquals(110, res1.getIntersectedPoint().getY(), 0.00001);
 897                     assertEquals(0, res1.getIntersectedPoint().getZ(), 0.00001);
 898 
 899                     assertNotNull(res2);
 900                     assertSame(rect2, res2.getIntersectedNode());
 901                     assertEquals(220, res2.getIntersectedPoint().getX(), 0.00001);
 902                     assertEquals(220, res2.getIntersectedPoint().getY(), 0.00001);
 903                     assertEquals(0, res1.getIntersectedPoint().getZ(), 0.00001);
 904                     break;
 905                 case 3:
 906                     assertNotNull(res1);
 907                     assertSame(rect2, res1.getIntersectedNode());
 908                     assertEquals(220, res1.getIntersectedPoint().getX(), 0.00001);
 909                     assertEquals(220, res1.getIntersectedPoint().getY(), 0.00001);
 910                     assertEquals(0, res1.getIntersectedPoint().getZ(), 0.00001);
 911 
 912                     assertNotNull(res2);
 913                     assertSame(rect1, res2.getIntersectedNode());
 914                     assertEquals(110, res2.getIntersectedPoint().getX(), 0.00001);
 915                     assertEquals(110, res2.getIntersectedPoint().getY(), 0.00001);
 916                     assertEquals(0, res1.getIntersectedPoint().getZ(), 0.00001);
 917                     break;
 918                 default:
 919                     fail("Wrong event delivered");
 920             }
 921         });
 922         rect2.addEventHandler(TouchEvent.ANY, event -> {
 923             touched++;
 924             assertSame(rect2, event.getTouchPoint().getTarget());
 925             assertSame(rect1, event.getTouchPoints().get(0).getTarget());
 926             PickResult res2 = event.getTouchPoint().getPickResult();
 927             PickResult res1 = event.getTouchPoints().get(0).getPickResult();
 928             switch(touched) {
 929                 case 2:
 930                     assertNotNull(res1);
 931                     assertSame(rect1, res1.getIntersectedNode());
 932                     assertEquals(110, res1.getIntersectedPoint().getX(), 0.00001);
 933                     assertEquals(110, res1.getIntersectedPoint().getY(), 0.00001);
 934                     assertEquals(0, res1.getIntersectedPoint().getZ(), 0.00001);
 935 
 936                     assertNotNull(res2);
 937                     assertSame(rect2, res2.getIntersectedNode());
 938                     assertEquals(220, res2.getIntersectedPoint().getX(), 0.00001);
 939                     assertEquals(220, res2.getIntersectedPoint().getY(), 0.00001);
 940                     assertEquals(0, res1.getIntersectedPoint().getZ(), 0.00001);
 941                     break;
 942                 case 4:
 943                     assertNotNull(res1);
 944                     assertSame(rect2, res1.getIntersectedNode());
 945                     assertEquals(220, res1.getIntersectedPoint().getX(), 0.00001);
 946                     assertEquals(220, res1.getIntersectedPoint().getY(), 0.00001);
 947                     assertEquals(0, res1.getIntersectedPoint().getZ(), 0.00001);
 948 
 949                     assertNotNull(res2);
 950                     assertSame(rect1, res2.getIntersectedNode());
 951                     assertEquals(110, res2.getIntersectedPoint().getX(), 0.00001);
 952                     assertEquals(110, res2.getIntersectedPoint().getY(), 0.00001);
 953                     assertEquals(0, res1.getIntersectedPoint().getZ(), 0.00001);
 954                     break;
 955                 default:
 956                     fail("Wrong event delivered");
 957             }
 958         });
 959 
 960         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 961                 System.currentTimeMillis(), 2, true, true, false, true, false);
 962         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 963                 TouchPoint.State.PRESSED, 1, 110, 110, 110, 110);
 964         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 965                 TouchPoint.State.PRESSED, 2, 220, 220, 220, 220);
 966         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 967 
 968         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
 969                 System.currentTimeMillis(), 2, true, true, false, true, false);
 970         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 971                 TouchPoint.State.MOVED, 1, 220, 220, 220, 220);
 972         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
 973                 TouchPoint.State.MOVED, 2, 110, 110, 110, 110);
 974         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
 975 
 976         assertEquals(4, touched);
 977     }
 978 
 979     @Test
 980     public void testTouchPointsBelongsTo() {
 981         final Scene scene = createScene();
 982 
 983         final Rectangle rect1 =
 984                 (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(0);
 985 
 986         final Rectangle rect2 =
 987                 (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(1);
 988 
 989         touched = 0;
 990         rect1.addEventHandler(TouchEvent.ANY, event -> {
 991             touched++;
 992             assertTrue(event.getTouchPoint().belongsTo(rect1));
 993             assertTrue(event.getTouchPoint().belongsTo(scene.getRoot()));
 994             assertTrue(event.getTouchPoint().belongsTo(scene));
 995             assertFalse(event.getTouchPoint().belongsTo(rect2));
 996 
 997             assertFalse(event.getTouchPoints().get(1).belongsTo(rect1));
 998             assertTrue(event.getTouchPoints().get(1).belongsTo(scene.getRoot()));
 999             assertTrue(event.getTouchPoints().get(1).belongsTo(scene));
1000             assertTrue(event.getTouchPoints().get(1).belongsTo(rect2));
1001         });
1002         rect2.addEventHandler(TouchEvent.ANY, event -> {
1003             touched++;
1004             assertTrue(event.getTouchPoint().belongsTo(rect2));
1005             assertTrue(event.getTouchPoint().belongsTo(scene.getRoot()));
1006             assertTrue(event.getTouchPoint().belongsTo(scene));
1007             assertFalse(event.getTouchPoint().belongsTo(rect1));
1008 
1009             assertFalse(event.getTouchPoints().get(0).belongsTo(rect2));
1010             assertTrue(event.getTouchPoints().get(0).belongsTo(scene.getRoot()));
1011             assertTrue(event.getTouchPoints().get(0).belongsTo(scene));
1012             assertTrue(event.getTouchPoints().get(0).belongsTo(rect1));
1013         });
1014 
1015         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
1016                 System.currentTimeMillis(), 2, true, true, false, true, false);
1017         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1018                 TouchPoint.State.PRESSED, 1, 110, 110, 110, 110);
1019         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1020                 TouchPoint.State.PRESSED, 2, 220, 220, 220, 220);
1021         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
1022 
1023         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
1024                 System.currentTimeMillis(), 2, true, true, false, true, false);
1025         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1026                 TouchPoint.State.RELEASED, 1, 110, 110, 110, 110);
1027         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1028                 TouchPoint.State.RELEASED, 2, 220, 220, 220, 220);
1029         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
1030 
1031         assertEquals(4, touched);
1032     }
1033 
1034     @Test
1035     public void shouldPickAndGrabTouchPoints() {
1036         Scene scene = createScene();
1037         final Rectangle rect1 =
1038                 (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(0);
1039 
1040         final Rectangle rect2 =
1041                 (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(1);
1042 
1043         touched = 0;
1044         rect1.addEventHandler(TouchEvent.ANY, event -> {
1045             touched++;
1046             switch(touched) {
1047                 case 1:
1048                     Assert.assertEquals(1, event.getTouchPoint().getId());
1049                     Assert.assertEquals(150.0, event.getTouchPoint().getX(), 0.0001);
1050                     Assert.assertEquals(155.0, event.getTouchPoint().getY(), 0.0001);
1051                     Assert.assertEquals(150.0, event.getTouchPoint().getSceneX(), 0.0001);
1052                     Assert.assertEquals(155.0, event.getTouchPoint().getSceneY(), 0.0001);
1053                     Assert.assertEquals(1150.0, event.getTouchPoint().getScreenX(), 0.0001);
1054                     Assert.assertEquals(1155.0, event.getTouchPoint().getScreenY(), 0.0001);
1055                     break;
1056                 case 3:
1057                     Assert.assertEquals(1, event.getTouchPoint().getId());
1058                     Assert.assertEquals(250.0, event.getTouchPoint().getX(), 0.0001);
1059                     Assert.assertEquals(255.0, event.getTouchPoint().getY(), 0.0001);
1060                     Assert.assertEquals(250.0, event.getTouchPoint().getSceneX(), 0.0001);
1061                     Assert.assertEquals(255.0, event.getTouchPoint().getSceneY(), 0.0001);
1062                     Assert.assertEquals(1250.0, event.getTouchPoint().getScreenX(), 0.0001);
1063                     Assert.assertEquals(1255.0, event.getTouchPoint().getScreenY(), 0.0001);
1064                     break;
1065                 default:
1066                     fail("Wrong touch point delivery");
1067             }
1068         });
1069 
1070         rect2.addEventHandler(TouchEvent.ANY, event -> {
1071             touched++;
1072             switch(touched) {
1073                 case 2:
1074                     Assert.assertEquals(2, event.getTouchPoint().getId());
1075                     Assert.assertEquals(260.0, event.getTouchPoint().getX(), 0.0001);
1076                     Assert.assertEquals(265.0, event.getTouchPoint().getY(), 0.0001);
1077                     Assert.assertEquals(260.0, event.getTouchPoint().getSceneX(), 0.0001);
1078                     Assert.assertEquals(265.0, event.getTouchPoint().getSceneY(), 0.0001);
1079                     Assert.assertEquals(1260.0, event.getTouchPoint().getScreenX(), 0.0001);
1080                     Assert.assertEquals(1265.0, event.getTouchPoint().getScreenY(), 0.0001);
1081                     break;
1082                 case 4:
1083                     Assert.assertEquals(2, event.getTouchPoint().getId());
1084                     Assert.assertEquals(160.0, event.getTouchPoint().getX(), 0.0001);
1085                     Assert.assertEquals(165.0, event.getTouchPoint().getY(), 0.0001);
1086                     Assert.assertEquals(160.0, event.getTouchPoint().getSceneX(), 0.0001);
1087                     Assert.assertEquals(165.0, event.getTouchPoint().getSceneY(), 0.0001);
1088                     Assert.assertEquals(1160.0, event.getTouchPoint().getScreenX(), 0.0001);
1089                     Assert.assertEquals(1165.0, event.getTouchPoint().getScreenY(), 0.0001);
1090                     break;
1091                 default:
1092                     fail("Wrong touch point delivery");
1093             }
1094         });
1095 
1096         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
1097                 System.currentTimeMillis(), 2, true, true, false, true, false);
1098         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1099                 TouchPoint.State.PRESSED, 3, 150, 155, 1150, 1155);
1100         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1101                 TouchPoint.State.PRESSED, 4, 260, 265, 1260, 1265);
1102         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
1103 
1104         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
1105                 System.currentTimeMillis(), 2, true, true, false, true, false);
1106         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1107                 TouchPoint.State.MOVED, 3, 250, 255, 1250, 1255);
1108         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1109                 TouchPoint.State.MOVED, 4, 160, 165, 1160, 1165);
1110         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
1111 
1112         assertEquals(4, touched);
1113     }
1114 
1115     @Test
1116     public void ungrabShouldEnablePickingForTouchPoints() {
1117         Scene scene = createScene();
1118         Rectangle rect1 =
1119                 (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(0);
1120 
1121         Rectangle rect2 =
1122                 (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(1);
1123 
1124         touched = 0;
1125         rect1.addEventHandler(TouchEvent.ANY, event -> {
1126             touched++;
1127             switch(touched) {
1128                 case 1:
1129                     Assert.assertEquals(1, event.getTouchPoint().getId());
1130                     Assert.assertEquals(150.0, event.getTouchPoint().getX(), 0.0001);
1131                     Assert.assertEquals(155.0, event.getTouchPoint().getY(), 0.0001);
1132                     Assert.assertEquals(150.0, event.getTouchPoint().getSceneX(), 0.0001);
1133                     Assert.assertEquals(155.0, event.getTouchPoint().getSceneY(), 0.0001);
1134                     Assert.assertEquals(1150.0, event.getTouchPoint().getScreenX(), 0.0001);
1135                     Assert.assertEquals(1155.0, event.getTouchPoint().getScreenY(), 0.0001);
1136                     event.getTouchPoint().ungrab();
1137                     break;
1138                 case 4:
1139                     Assert.assertEquals(2, event.getTouchPoint().getId());
1140                     Assert.assertEquals(160.0, event.getTouchPoint().getX(), 0.0001);
1141                     Assert.assertEquals(165.0, event.getTouchPoint().getY(), 0.0001);
1142                     Assert.assertEquals(160.0, event.getTouchPoint().getSceneX(), 0.0001);
1143                     Assert.assertEquals(165.0, event.getTouchPoint().getSceneY(), 0.0001);
1144                     Assert.assertEquals(1160.0, event.getTouchPoint().getScreenX(), 0.0001);
1145                     Assert.assertEquals(1165.0, event.getTouchPoint().getScreenY(), 0.0001);
1146                     break;
1147                 default:
1148                     fail("Wrong touch point delivery");
1149             }
1150         });
1151 
1152         rect2.addEventHandler(TouchEvent.ANY, event -> {
1153             touched++;
1154             switch(touched) {
1155                 case 2:
1156                     Assert.assertEquals(2, event.getTouchPoint().getId());
1157                     Assert.assertEquals(260.0, event.getTouchPoint().getX(), 0.0001);
1158                     Assert.assertEquals(265.0, event.getTouchPoint().getY(), 0.0001);
1159                     Assert.assertEquals(260.0, event.getTouchPoint().getSceneX(), 0.0001);
1160                     Assert.assertEquals(265.0, event.getTouchPoint().getSceneY(), 0.0001);
1161                     Assert.assertEquals(1260.0, event.getTouchPoint().getScreenX(), 0.0001);
1162                     Assert.assertEquals(1265.0, event.getTouchPoint().getScreenY(), 0.0001);
1163                     event.getTouchPoint().ungrab();
1164                     break;
1165                 case 3:
1166                     Assert.assertEquals(1, event.getTouchPoint().getId());
1167                     Assert.assertEquals(250.0, event.getTouchPoint().getX(), 0.0001);
1168                     Assert.assertEquals(255.0, event.getTouchPoint().getY(), 0.0001);
1169                     Assert.assertEquals(250.0, event.getTouchPoint().getSceneX(), 0.0001);
1170                     Assert.assertEquals(255.0, event.getTouchPoint().getSceneY(), 0.0001);
1171                     Assert.assertEquals(1250.0, event.getTouchPoint().getScreenX(), 0.0001);
1172                     Assert.assertEquals(1255.0, event.getTouchPoint().getScreenY(), 0.0001);
1173                     break;
1174                 default:
1175                     fail("Wrong touch point delivery");
1176             }
1177         });
1178 
1179         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
1180                 System.currentTimeMillis(), 2, true, true, false, true, false);
1181         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1182                 TouchPoint.State.PRESSED, 3, 150, 155, 1150, 1155);
1183         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1184                 TouchPoint.State.PRESSED, 4, 260, 265, 1260, 1265);
1185         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
1186 
1187         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
1188                 System.currentTimeMillis(), 2, true, true, false, true, false);
1189         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1190                 TouchPoint.State.MOVED, 3, 250, 255, 1250, 1255);
1191         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1192                 TouchPoint.State.MOVED, 4, 160, 165, 1160, 1165);
1193         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
1194 
1195         assertEquals(4, touched);
1196     }
1197 
1198     @Test
1199     public void grabWithArgShouldAffectDelivery() {
1200         Scene scene = createScene();
1201         final Rectangle rect1 =
1202                 (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(0);
1203 
1204         final Rectangle rect2 =
1205                 (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(1);
1206 
1207         touched = 0;
1208         rect1.addEventHandler(TouchEvent.ANY, event -> {
1209             touched++;
1210             switch(touched) {
1211                 case 1:
1212                     Assert.assertEquals(1, event.getTouchPoint().getId());
1213                     Assert.assertEquals(150.0, event.getTouchPoint().getX(), 0.0001);
1214                     Assert.assertEquals(155.0, event.getTouchPoint().getY(), 0.0001);
1215                     Assert.assertEquals(150.0, event.getTouchPoint().getSceneX(), 0.0001);
1216                     Assert.assertEquals(155.0, event.getTouchPoint().getSceneY(), 0.0001);
1217                     Assert.assertEquals(1150.0, event.getTouchPoint().getScreenX(), 0.0001);
1218                     Assert.assertEquals(1155.0, event.getTouchPoint().getScreenY(), 0.0001);
1219                     event.getTouchPoints().get(1).grab(rect1);
1220                     break;
1221                 case 3:
1222                     Assert.assertEquals(1, event.getTouchPoint().getId());
1223                     Assert.assertEquals(250.0, event.getTouchPoint().getX(), 0.0001);
1224                     Assert.assertEquals(255.0, event.getTouchPoint().getY(), 0.0001);
1225                     Assert.assertEquals(250.0, event.getTouchPoint().getSceneX(), 0.0001);
1226                     Assert.assertEquals(255.0, event.getTouchPoint().getSceneY(), 0.0001);
1227                     Assert.assertEquals(1250.0, event.getTouchPoint().getScreenX(), 0.0001);
1228                     Assert.assertEquals(1255.0, event.getTouchPoint().getScreenY(), 0.0001);
1229                     break;
1230                 case 4:
1231                     Assert.assertEquals(2, event.getTouchPoint().getId());
1232                     Assert.assertEquals(160.0, event.getTouchPoint().getX(), 0.0001);
1233                     Assert.assertEquals(165.0, event.getTouchPoint().getY(), 0.0001);
1234                     Assert.assertEquals(160.0, event.getTouchPoint().getSceneX(), 0.0001);
1235                     Assert.assertEquals(165.0, event.getTouchPoint().getSceneY(), 0.0001);
1236                     Assert.assertEquals(1160.0, event.getTouchPoint().getScreenX(), 0.0001);
1237                     Assert.assertEquals(1165.0, event.getTouchPoint().getScreenY(), 0.0001);
1238                     break;
1239                 default:
1240                     fail("Wrong touch point delivery");
1241             }
1242         });
1243 
1244         rect2.addEventHandler(TouchEvent.ANY, event -> {
1245             touched++;
1246             switch(touched) {
1247                 case 2:
1248                     Assert.assertEquals(2, event.getTouchPoint().getId());
1249                     Assert.assertEquals(260.0, event.getTouchPoint().getX(), 0.0001);
1250                     Assert.assertEquals(265.0, event.getTouchPoint().getY(), 0.0001);
1251                     Assert.assertEquals(260.0, event.getTouchPoint().getSceneX(), 0.0001);
1252                     Assert.assertEquals(265.0, event.getTouchPoint().getSceneY(), 0.0001);
1253                     Assert.assertEquals(1260.0, event.getTouchPoint().getScreenX(), 0.0001);
1254                     Assert.assertEquals(1265.0, event.getTouchPoint().getScreenY(), 0.0001);
1255                     break;
1256                 default:
1257                     fail("Wrong touch point delivery");
1258             }
1259         });
1260 
1261         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
1262                 System.currentTimeMillis(), 2, true, true, false, true, false);
1263         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1264                 TouchPoint.State.PRESSED, 3, 150, 155, 1150, 1155);
1265         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1266                 TouchPoint.State.PRESSED, 4, 260, 265, 1260, 1265);
1267         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
1268 
1269         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
1270                 System.currentTimeMillis(), 2, true, true, false, true, false);
1271         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1272                 TouchPoint.State.MOVED, 3, 250, 255, 1250, 1255);
1273         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1274                 TouchPoint.State.MOVED, 4, 160, 165, 1160, 1165);
1275         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
1276 
1277         assertEquals(4, touched);
1278     }
1279 
1280     @Test
1281     public void grabWithoutArgShouldAffectDelivery() {
1282         Scene scene = createScene();
1283         final Rectangle rect1 =
1284                 (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(0);
1285 
1286         final Rectangle rect2 =
1287                 (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(1);
1288 
1289         touched = 0;
1290         rect1.addEventHandler(TouchEvent.ANY, event -> {
1291             touched++;
1292             switch(touched) {
1293                 case 1:
1294                     Assert.assertEquals(1, event.getTouchPoint().getId());
1295                     Assert.assertEquals(150.0, event.getTouchPoint().getX(), 0.0001);
1296                     Assert.assertEquals(155.0, event.getTouchPoint().getY(), 0.0001);
1297                     Assert.assertEquals(150.0, event.getTouchPoint().getSceneX(), 0.0001);
1298                     Assert.assertEquals(155.0, event.getTouchPoint().getSceneY(), 0.0001);
1299                     Assert.assertEquals(1150.0, event.getTouchPoint().getScreenX(), 0.0001);
1300                     Assert.assertEquals(1155.0, event.getTouchPoint().getScreenY(), 0.0001);
1301                     event.getTouchPoints().get(1).grab();
1302                     break;
1303                 case 3:
1304                     Assert.assertEquals(1, event.getTouchPoint().getId());
1305                     Assert.assertEquals(250.0, event.getTouchPoint().getX(), 0.0001);
1306                     Assert.assertEquals(255.0, event.getTouchPoint().getY(), 0.0001);
1307                     Assert.assertEquals(250.0, event.getTouchPoint().getSceneX(), 0.0001);
1308                     Assert.assertEquals(255.0, event.getTouchPoint().getSceneY(), 0.0001);
1309                     Assert.assertEquals(1250.0, event.getTouchPoint().getScreenX(), 0.0001);
1310                     Assert.assertEquals(1255.0, event.getTouchPoint().getScreenY(), 0.0001);
1311                     break;
1312                 case 4:
1313                     Assert.assertEquals(2, event.getTouchPoint().getId());
1314                     Assert.assertEquals(160.0, event.getTouchPoint().getX(), 0.0001);
1315                     Assert.assertEquals(165.0, event.getTouchPoint().getY(), 0.0001);
1316                     Assert.assertEquals(160.0, event.getTouchPoint().getSceneX(), 0.0001);
1317                     Assert.assertEquals(165.0, event.getTouchPoint().getSceneY(), 0.0001);
1318                     Assert.assertEquals(1160.0, event.getTouchPoint().getScreenX(), 0.0001);
1319                     Assert.assertEquals(1165.0, event.getTouchPoint().getScreenY(), 0.0001);
1320                     break;
1321                 default:
1322                     fail("Wrong touch point delivery");
1323             }
1324         });
1325 
1326         rect2.addEventHandler(TouchEvent.ANY, event -> {
1327             touched++;
1328             switch(touched) {
1329                 case 2:
1330                     Assert.assertEquals(2, event.getTouchPoint().getId());
1331                     Assert.assertEquals(260.0, event.getTouchPoint().getX(), 0.0001);
1332                     Assert.assertEquals(265.0, event.getTouchPoint().getY(), 0.0001);
1333                     Assert.assertEquals(260.0, event.getTouchPoint().getSceneX(), 0.0001);
1334                     Assert.assertEquals(265.0, event.getTouchPoint().getSceneY(), 0.0001);
1335                     Assert.assertEquals(1260.0, event.getTouchPoint().getScreenX(), 0.0001);
1336                     Assert.assertEquals(1265.0, event.getTouchPoint().getScreenY(), 0.0001);
1337                     break;
1338                 default:
1339                     fail("Wrong touch point delivery");
1340             }
1341         });
1342 
1343         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
1344                 System.currentTimeMillis(), 2, true, true, false, true, false);
1345         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1346                 TouchPoint.State.PRESSED, 3, 150, 155, 1150, 1155);
1347         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1348                 TouchPoint.State.PRESSED, 4, 260, 265, 1260, 1265);
1349         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
1350 
1351         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
1352                 System.currentTimeMillis(), 2, true, true, false, true, false);
1353         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1354                 TouchPoint.State.MOVED, 3, 250, 255, 1250, 1255);
1355         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1356                 TouchPoint.State.MOVED, 4, 160, 165, 1160, 1165);
1357         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
1358 
1359         assertEquals(4, touched);
1360     }
1361 
1362     @Test
1363     public void pointsShouldBeTransformedCorrectly() {
1364         Scene scene = createScene();
1365         Rectangle rect =
1366                 (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(0);
1367         rect.setTranslateX(15);
1368         rect.setTranslateY(5);
1369 
1370         touched = 0;
1371         rect.addEventHandler(TouchEvent.ANY, event -> {
1372             touched++;
1373             switch(touched) {
1374                 case 1:
1375                     Assert.assertEquals(115.0, event.getTouchPoint().getX(), 0.0001);
1376                     Assert.assertEquals(125.0, event.getTouchPoint().getY(), 0.0001);
1377                     Assert.assertEquals(130.0, event.getTouchPoint().getSceneX(), 0.0001);
1378                     Assert.assertEquals(130.0, event.getTouchPoint().getSceneY(), 0.0001);
1379                     break;
1380                 case 2:
1381                 case 3:
1382                 case 4:
1383                 case 5:
1384                     Assert.assertEquals(115.0, event.getTouchPoints().get(0).getX(), 0.0001);
1385                     Assert.assertEquals(125.0, event.getTouchPoints().get(0).getY(), 0.0001);
1386                     Assert.assertEquals(130.0, event.getTouchPoints().get(0).getSceneX(), 0.0001);
1387                     Assert.assertEquals(130.0, event.getTouchPoints().get(0).getSceneY(), 0.0001);
1388                     Assert.assertEquals(125.0, event.getTouchPoints().get(1).getX(), 0.0001);
1389                     Assert.assertEquals(135.0, event.getTouchPoints().get(1).getY(), 0.0001);
1390                     Assert.assertEquals(140.0, event.getTouchPoints().get(1).getSceneX(), 0.0001);
1391                     Assert.assertEquals(140.0, event.getTouchPoints().get(1).getSceneY(), 0.0001);
1392                     break;
1393                 default:
1394                     fail("Wrong touch point id " + event.getTouchPoint().getId());
1395             }
1396         });
1397 
1398         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
1399                 System.currentTimeMillis(), 1, true, true, false, true, false);
1400         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1401                 TouchPoint.State.PRESSED, 1, 130, 130, 130, 130);
1402         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
1403 
1404         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
1405                 System.currentTimeMillis(), 2, true, true, false, true, false);
1406         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1407                 TouchPoint.State.STATIONARY, 1, 130, 130, 130, 130);
1408         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1409                 TouchPoint.State.PRESSED, 2, 140, 140, 140, 140);
1410         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
1411 
1412         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
1413                 System.currentTimeMillis(), 2, true, true, false, true, false);
1414         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1415                 TouchPoint.State.RELEASED, 1, 130, 130, 130, 130);
1416         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1417                 TouchPoint.State.RELEASED, 2, 140, 140, 140, 140);
1418         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
1419 
1420 
1421         assertEquals(5, touched);
1422     }
1423 
1424     @Test
1425     public void shouldIgnoreIndirectTouchEvents() {
1426         Scene scene = createScene();
1427         Rectangle rect =
1428                 (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(0);
1429 
1430         rect.addEventHandler(TouchEvent.ANY, event -> fail("Delivered indirect touch event"));
1431 
1432         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
1433                 System.currentTimeMillis(), 1, false, true, false, true, false);
1434         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1435                 TouchPoint.State.PRESSED, 1, 110, 110, 110, 110);
1436         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
1437 
1438         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
1439                 System.currentTimeMillis(), 1, false, true, false, true, false);
1440         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1441                 TouchPoint.State.RELEASED, 1, 110, 110, 110, 110);
1442         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
1443     }
1444 
1445     @Test(expected=RuntimeException.class)
1446     public void shouldThrowREOnWrongSmallId() {
1447         Scene scene = createScene();
1448         Rectangle rect =
1449                 (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(0);
1450 
1451         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
1452                 System.currentTimeMillis(), 1, true, false, false, false, false);
1453         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1454                 TouchPoint.State.PRESSED, 1, 110, 110, 110, 110);
1455         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
1456 
1457         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
1458                 System.currentTimeMillis(), 1, true, false, false, false, false);
1459         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1460                 TouchPoint.State.MOVED, 2, 110, 110, 110, 110);
1461         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
1462     }
1463 
1464     @Test(expected=RuntimeException.class)
1465     public void shouldThrowREOnWrongLargeId() {
1466         Scene scene = createScene();
1467         Rectangle rect =
1468                 (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(0);
1469 
1470         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
1471                 System.currentTimeMillis(), 1, true, false, false, false, false);
1472         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1473                 TouchPoint.State.PRESSED, 1368, 110, 110, 110, 110);
1474         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
1475 
1476         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
1477                 System.currentTimeMillis(), 1, true, false, false, false, false);
1478         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1479                 TouchPoint.State.MOVED, 127, 110, 110, 110, 110);
1480         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
1481     }
1482 
1483     @Test(expected=RuntimeException.class)
1484     public void shouldThrowREOnBigTPNumber() {
1485         Scene scene = createScene();
1486         Rectangle rect =
1487                 (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(0);
1488 
1489         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
1490                 System.currentTimeMillis(), 1, true, false, false, false, false);
1491         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1492                 TouchPoint.State.PRESSED, 1368, 110, 110, 110, 110);
1493         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1494                 TouchPoint.State.PRESSED, 1, 110, 110, 110, 110);
1495         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
1496     }
1497 
1498     @Test(expected=RuntimeException.class)
1499     public void shouldThrowREOnSmallTPNumber() {
1500         Scene scene = createScene();
1501         Rectangle rect =
1502                 (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(0);
1503 
1504         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
1505                 System.currentTimeMillis(), 2, true, false, false, false, false);
1506         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1507                 TouchPoint.State.PRESSED, 1368, 110, 110, 110, 110);
1508         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
1509     }
1510 
1511     @Test(expected=RuntimeException.class)
1512     public void shouldThrowREOnLostRelease() {
1513         Scene scene = createScene();
1514         Rectangle rect =
1515                 (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(0);
1516 
1517         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
1518                 System.currentTimeMillis(), 1, true, false, false, false, false);
1519         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1520                 TouchPoint.State.PRESSED, 1368, 110, 110, 110, 110);
1521         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
1522 
1523         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
1524                 System.currentTimeMillis(), 1, true, false, false, false, false);
1525         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1526                 TouchPoint.State.PRESSED, 1, 110, 110, 110, 110);
1527         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
1528     }
1529 
1530     // Reenable once indirect events are used
1531     @Ignore("For now we've decided to ingore indirect events completely.")
1532     @Test(expected=RuntimeException.class)
1533     public void shouldThrowREOnLostIndirectRelease() {
1534         Scene scene = createScene();
1535         Rectangle rect =
1536                 (Rectangle) scene.getRoot().getChildrenUnmodifiable().get(0);
1537 
1538         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
1539                 System.currentTimeMillis(), 1, false, false, false, false, false);
1540         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1541                 TouchPoint.State.PRESSED, 1368, 110, 110, 110, 110);
1542         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
1543 
1544         ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
1545                 System.currentTimeMillis(), 1, false, false, false, false, false);
1546         ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1547                 TouchPoint.State.PRESSED, 1, 110, 110, 110, 110);
1548         ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
1549     }
1550 
1551     private Scene createScene() {
1552         final Group root = new Group();
1553 
1554         final Scene scene = new Scene(root, 400, 400);
1555 
1556         Rectangle rect = new Rectangle(100, 100, 100, 100);
1557         Rectangle rect2 = new Rectangle(200, 200, 100, 100);
1558 
1559         root.getChildren().addAll(rect, rect2);
1560 
1561         Stage stage = new Stage();
1562         stage.setScene(scene);
1563         stage.show();
1564 
1565         return scene;
1566     }
1567 
1568     @Test
1569     @Ignore("This is a benchmark, not any functional test. Run it individually if you wish.")
1570     public void saneOrderingBenchmark() {
1571         long[] ids = new long[] { 2, 3, 4, 5, 6 };
1572         boolean[] active = new boolean[] { false, false, false, false, false };
1573         int count = 0;
1574         int tick = 5;
1575         int available = 5;
1576         Random rand = new Random();
1577 
1578         Scene scene = createScene();
1579 
1580 
1581         int ticker = 0;
1582         int added = -1;
1583         int removed = -1;
1584         long timer = System.currentTimeMillis();
1585         for (int i = 0; i < SANE_BENCHMARK_CYCLES; i++) {
1586             ticker++;
1587             if (ticker == tick) {
1588                 ticker = 0;
1589 
1590                 boolean up;
1591                 if (count == available) {
1592                     up = false;
1593                 } else if (count == 0) {
1594                     up = true;
1595                 } else {
1596                     up = Math.random() > 0.4;
1597                 }
1598 
1599                 if (up) {
1600                     for (int j = 0; j < available; j++) {
1601                         if (!active[j]) {
1602                             active[j] = true;
1603                             added = j;
1604                             count++;
1605                             break;
1606                         }
1607                     }
1608                 } else {
1609                     int which = rand.nextInt(count);
1610                     int k = 0;
1611                     for (int j = 0; j < available; j++) {
1612                         if (active[j]) {
1613                             k++;
1614                             if (k == which) {
1615                                 active[j] = false;
1616                                 removed = j;
1617                                 count--;
1618                                 break;
1619                             }
1620                         }
1621                     }
1622                 }
1623             }
1624 
1625             int reporting = count + (removed >= 0 ? 1 : 0);
1626 
1627             ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
1628                     System.currentTimeMillis(), reporting, true, false, false, false, false);
1629 
1630             for (int j = 0; j < available; j++) {
1631                 if (active[j] || removed == j) {
1632                     TouchPoint.State state = TouchPoint.State.MOVED;
1633                     if (added == j) {
1634                         state = TouchPoint.State.PRESSED;
1635                     } else if (removed == j) {
1636                         state = TouchPoint.State.RELEASED;
1637                     } else {
1638                     }
1639 
1640                     ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1641                             state, ids[j], 150, 150, 150, 150);
1642                 }
1643             }
1644 
1645             ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
1646             removed = -1;
1647             added = -1;
1648         }
1649         long timer2 = System.currentTimeMillis();
1650         System.out.println("*************************************************");
1651         System.out.println("Benchmark1 time: " + (timer2 - timer));
1652         System.out.println("*************************************************");
1653         System.out.println("");
1654     }
1655 
1656     @Test
1657     @Ignore("This is a benchmark, not any functional test. Run it individually if you wish.")
1658     public void crazyOrderingBenchmark() {
1659         long[] ids = new long[] { 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 };
1660         boolean[] active = new boolean[] { false, false, false, false, false,
1661                 false, false, false, false, false };
1662         int count = 0;
1663         int tick = 5;
1664         int available = 10;
1665         Random rand = new Random();
1666 
1667         Scene scene = createScene();
1668 
1669 
1670         int ticker = 0;
1671         int added = -1;
1672         int removed = -1;
1673         long timer = System.currentTimeMillis();
1674         for (int i = 0; i < CRAZY_BENCHMARK_CYCLES; i++) {
1675             ticker++;
1676             if (ticker == tick) {
1677                 ticker = 0;
1678 
1679                 boolean up;
1680                 if (count == available) {
1681                     up = false;
1682                 } else if (count == 0) {
1683                     up = true;
1684                 } else {
1685                     up = Math.random() > 0.4;
1686                 }
1687 
1688                 if (up) {
1689                     int which = rand.nextInt(available - count);
1690                     int k = 0;
1691                     for (int j = 0; j < available; j++) {
1692                         if (!active[j]) {
1693                             k++;
1694                             if (k == which) {
1695                                 active[j] = true;
1696                                 added = j;
1697                                 count++;
1698                                 ids[j] = Math.abs(rand.nextLong());
1699                                 if (ids[j] == 0) {
1700                                     ids[j] = 1;
1701                                 }
1702                                 break;
1703                             }
1704                         }
1705                     }
1706                 } else {
1707                     int which = rand.nextInt(count);
1708                     int k = 0;
1709                     for (int j = 0; j < available; j++) {
1710                         if (active[j]) {
1711                             k++;
1712                             if (k == which) {
1713                                 active[j] = false;
1714                                 removed = j;
1715                                 count--;
1716                                 break;
1717                             }
1718                         }
1719                     }
1720                 }
1721             }
1722 
1723             int reporting = count + (removed >= 0 ? 1 : 0);
1724 
1725             ((StubScene) scene.impl_getPeer()).getListener().touchEventBegin(
1726                     System.currentTimeMillis(), reporting, true, false, false, false, false);
1727 
1728             for (int j = 0; j < available; j++) {
1729                 if (active[j] || removed == j) {
1730                     TouchPoint.State state = TouchPoint.State.MOVED;
1731                     if (added == j) {
1732                         state = TouchPoint.State.PRESSED;
1733                     } else if (removed == j) {
1734                         state = TouchPoint.State.RELEASED;
1735                     }
1736 
1737                     ((StubScene) scene.impl_getPeer()).getListener().touchEventNext(
1738                             state, ids[j], 150, 150, 150, 150);
1739                 }
1740             }
1741 
1742             ((StubScene) scene.impl_getPeer()).getListener().touchEventEnd();
1743             removed = -1;
1744             added = -1;
1745         }
1746         long timer2 = System.currentTimeMillis();
1747         System.out.println("*************************************************");
1748         System.out.println("Benchmark2 time: " + (timer2 - timer));
1749         System.out.println("*************************************************");
1750         System.out.println("");
1751     }
1752 
1753 }