On Fri, 19 May 2023 16:24:44 GMT, Andy Goryachev <ango...@openjdk.org> wrote:

>> Adding `Toolkit::firePulse` is not making the tests stable. In fact I'm 
>> getting new failure after adding this in 
>> `testTextFlowInsertionIndexUsingMultipleEmojis()` test.
>> 
>> TextFlowSurrogatePairInsertionIndexTest > 
>> testTextFlowInsertionIndexUsingMultipleEmojis FAILED
>>     java.lang.NullPointerException: Cannot read the array length because 
>> "runs" is null
>>         at 
>> javafx.graphics@21-internal/javafx.scene.text.Text.getSpanBounds(Text.java:359)
>>         at 
>> javafx.graphics@21-internal/javafx.scene.text.Text.doComputeGeomBounds(Text.java:1159)
>>         at 
>> javafx.graphics@21-internal/javafx.scene.text.Text$1.doComputeGeomBounds(Text.java:149)
>>         at 
>> javafx.graphics@21-internal/com.sun.javafx.scene.shape.TextHelper.computeGeomBoundsImpl(TextHelper.java:90)
>>         at 
>> javafx.graphics@21-internal/com.sun.javafx.scene.NodeHelper.computeGeomBounds(NodeHelper.java:117)
>>         at 
>> javafx.graphics@21-internal/javafx.scene.Node.updateGeomBounds(Node.java:3813)
>>         at 
>> javafx.graphics@21-internal/javafx.scene.Node.getGeomBounds(Node.java:3775)
>>         at 
>> javafx.graphics@21-internal/javafx.scene.Node.getLocalBounds(Node.java:3723)
>>         at 
>> javafx.graphics@21-internal/javafx.scene.Node.updateTxBounds(Node.java:3877)
>>         at 
>> javafx.graphics@21-internal/javafx.scene.Node.getTransformedBounds(Node.java:3669)
>>         at 
>> javafx.graphics@21-internal/javafx.scene.Node.updateBounds(Node.java:777)
>>         at 
>> javafx.graphics@21-internal/javafx.scene.Parent.updateBounds(Parent.java:1834)
>>         at 
>> javafx.graphics@21-internal/javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2615)
>>         at 
>> javafx.graphics@21-internal/com.sun.javafx.tk.Toolkit.lambda$runPulse$2(Toolkit.java:401)
>>         at 
>> java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
>>         at 
>> javafx.graphics@21-internal/com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:400)
>>         at 
>> javafx.graphics@21-internal/com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:430)
>>         at 
>> test.robot.javafx.scene.TextFlowSurrogatePairInsertionIndexTest.testTextFlowInsertionIndexUsingMultipleEmojis(TextFlowSurrogatePairInsertionIndexTest.java:233)
>> 
>> Could increasing the delay time is the only solution now for the test 
>> failure seen previously and then we follow up with the approach suggested by 
>> @kevinrushforth ?
>> 
>> @andy-goryachev-oracle  could you please help me in understanding how 
>> `Util.runAndWait(() -> { });` help in this case? 
>> Also I'm using the...
>
>> could you please help me in understanding how `Util.runAndWait(() -> { });` 
>> help in this case
> 
> After discussing the issue with @kevinrushforth it probably won't.
> 
> The idea was to replace Thread.sleep() with something that can work reliably 
> even when the process takes a long time (i.e. cold boot).  Simply increasing 
> the sleep time to 1000 ms may not be sufficient, I think.
> 
> What we need is an equivalent of java.awt.Robot.waitForIdle() which we don't 
> have in FX.  The problem here is that all the processing involving CSS, 
> layout may take several pulses, and it certainly not guaranteed to be over 
> when the next event is processed in `Util.runAndWait()`.
> 
> We could still use Toolkit.firePulse(), but this apparently is a hack, and it 
> alters the normal control flow - that is something we are trying to avoid.
> 
> Another variant is to add something like that to Util and use that in place 
> of Thread.sleep().  This method will trigger and wait for an arbitrary number 
> of pulses (currently 10, but we can pick any reasonable number):
> 
> 
>     /**
>      * Triggers and waits for 10 pulses to complete in the specified scene.
>      */
>     public static void waitForIdle(Scene scene) {
>         int count = 10;
>         CountDownLatch latch = new CountDownLatch(count);
>         Runnable pulseListener = () -> {
>             latch.countDown();
>             Platform.requestNextPulse();
>         };
> 
>         runAndWait(() -> {
>             scene.addPostLayoutPulseListener(pulseListener);
>         });
> 
>         try {
>             Platform.requestNextPulse();
>             waitForLatch(latch, 30, "waitForIdle timeout");
>         } finally {
>             runAndWait(() -> {
>                 scene.removePostLayoutPulseListener(pulseListener);
>             });
>         }
>     }
> 
> 
> I am not sure why we have Scene.addPulseListener() and not a static 
> equivalent of Robot.waitForIdle(), but here is some earlier work on the pulse 
> listener:
> 
> https://bugs.openjdk.org/browse/JDK-8097917

@andy-goryachev-oracle Do you think this needs a second reviewer, or are you 
satisfied that a single review is sufficient?

-------------

PR Comment: https://git.openjdk.org/jfx/pull/1091#issuecomment-1557471464

Reply via email to