On Tue, 14 Nov 2023 09:41:08 GMT, John Hendrikx <[email protected]> wrote:
>> Michael Strauß has updated the pull request incrementally with one
>> additional commit since the last revision:
>>
>> Test whether two Interpolatable instances are compatible
>
> modules/javafx.graphics/src/main/java/com/sun/javafx/css/TransitionTimer.java
> line 179:
>
>> 177: if (newTimer.delay < 0) {
>> 178: double adjustedDelay = nanosToMillis(newTimer.delay) *
>> newTimer.reversingShorteningFactor;
>> 179: newTimer.startTime = now + millisToNanos(adjustedDelay);
>
> I don't see the value of converting these back and forth to milliseconds.
> Why not just:
>
> Suggestion:
>
> newTimer.startTime = now + newTimer.delay *
> newTimer.reversingShorteningFactor;
>
> I checked the calculations, and it makes no difference (the millis aren't
> rounded or anything), so you're just moving the decimal point before/after
> doing a multiplication that doesn't care where the decimal point is.
>
> If there is a reason that I missed, then I think this really needs a comment.
I've removed the conversions.
> modules/javafx.graphics/src/main/java/com/sun/javafx/css/TransitionTimer.java
> line 196:
>
>> 194: double frac = (double)(nanos - (millis * 1_000_000L)) /
>> 1_000_000D;
>> 195: return (double)millis + frac;
>> 196: }
>
> This function seems to want to preserve extra decimals in some way. If the
> original long has a magnitude that is so large that some least significant
> digits get lost in the double conversion, then trying to add them later
> (`millis + frac`) will not restore them.
>
> In other words, you can just do:
>
> Suggestion:
>
> private static double nanosToMillis(long nanos) {
> return nanos / 1_000_000.0;
> }
>
>
> Or avoiding the (generally slower) division completely:
>
> Suggestion:
>
> private static double nanosToMillis(long nanos) {
> return nanos * 0.000_001;
> }
>
>
> All the extra operations are only likely to introduce small errors.
Changed as suggested.
> modules/javafx.graphics/src/main/java/com/sun/javafx/css/TransitionTimer.java
> line 207:
>
>> 205: long wholeMillis = (long)millis;
>> 206: double frac = millis - (double)wholeMillis;
>> 207: return wholeMillis * 1_000_000L + (long)(frac * 1_000_000D);
>
> I'd recommend keeping this simple (it seems to want to recover extra
> significant digits, but that's not possible):
>
> Suggestion:
>
> return ((long)(millis * 1_000_000.0);
Changed as suggested.
> modules/javafx.graphics/src/main/java/com/sun/javafx/css/TransitionTimer.java
> line 234:
>
>> 232:
>> 233: Node node = (Node)timer.getProperty().getBean();
>> 234: node.fireEvent(new TransitionEvent(eventType,
>> timer.getProperty(), elapsedTime));
>
> minor:
> Suggestion:
>
> long elapsedTime;
>
> // Elapsed time specification:
> https://www.w3.org/TR/css-transitions-1/#event-transitionevent
> if (eventType == TransitionEvent.RUN || eventType ==
> TransitionEvent.START) {
> elapsedTime = Math.min(Math.max(-timer.delay, 0),
> timer.duration);
> } else if (eventType == TransitionEvent.CANCEL) {
> elapsedTime = Math.max(0, timer.currentTime -
> timer.startTime);
> } else if (eventType == TransitionEvent.END) {
> elapsedTime = timer.duration;
> } else {
> throw new IllegalArgumentException("eventType");
> }
>
> Node node = (Node)timer.getProperty().getBean();
> node.fireEvent(new TransitionEvent(eventType,
> timer.getProperty(), Duration.millis(nanosToMillis(elapsedTime))));
Changed as suggested.
> modules/javafx.graphics/src/main/java/javafx/css/StyleableDoubleProperty.java
> line 111:
>
>> 109: private TransitionTimer<?, ?> timer = null;
>> 110:
>> 111: private static class TransitionTimerImpl extends
>> TransitionTimer<Number, StyleableDoubleProperty> {
>
> I think you can simplify this. TransitionTimer does not need any of its
> generic parameters if you provide an abstract method to get the property
> (just the general interface), which is sufficient for the `getBean` call you
> do on it, and for passing it along as the source of events.
>
> The constructor, `onUpdate` and `onStop` don't need the property parameter at
> all if you make the `TransistionTimerImpl` non-static.
>
> I also have the feeling that instead of subclassing `TransitionTimer`,
> implementing an interface, which acts as the adapter you need between the
> general timer infrastructure and a specific property, would be more clean.
> My main reason for thinking so is the akward way the timer is put to use:
>
> TransitionTimer.run(new TransitionTimerImpl(this, v), transition)
>
> ...calling a static method on `TransitionTimer` while providing a subclass
> instance of it.
>
> It could then look something like this:
>
> class InternalTransitionAdapter implements TransitionAdapter {
> InternalTransitionAdapter(Number value) {
> this.oldValue = property.get();
> this.newValue = value != null ? value.doubleValue() : 0;
> }
>
> @Override
> protected void onUpdate(double progress) {
> set(progress < 1 ? oldValue + (newValue - oldValue) * progress :
> newValue);
> }
>
> @Override
> public void onStop() {
> timer = null;
> }
>
> @Override
> public Property<?> getProperty() {
> return StyleableDoubleProperty.this;
> }
>
> @Override
> protected boolean equalsTargetValue(TransitionAdapter adapter) {
> return newValue ==
> ((InternalTransitionTimerImpl)adapter).newValue;
> }
> }
>
> I also think the `equalsTargetValue` stuff can be done inside this property
> itself (see other comment)
This is now implemented with `TransitionMediator`.
-------------
PR Review Comment: https://git.openjdk.org/jfx/pull/870#discussion_r1529033318
PR Review Comment: https://git.openjdk.org/jfx/pull/870#discussion_r1529033525
PR Review Comment: https://git.openjdk.org/jfx/pull/870#discussion_r1529033615
PR Review Comment: https://git.openjdk.org/jfx/pull/870#discussion_r1529033418
PR Review Comment: https://git.openjdk.org/jfx/pull/870#discussion_r1529033655