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