On Fri, 19 Jan 2024 09:52:23 GMT, John Hendrikx <[email protected]> wrote:
>> modules/javafx.graphics/src/main/java/javafx/css/Selector.java line 179:
>>
>>> 177: * @throws IOException if reading from {@code DataInputStream}
>>> fails
>>> 178: */
>>> 179: protected static Selector readBinary(int bssVersion,
>>> DataInputStream is, String[] strings)
>>
>> This is an API addition, so will need an `@since 23`. Since you are adding
>> new API here, should it be an instance method rather than a static method?
>> Or is is called without having an instance of Selector in some cases?
>
> I'll add the `@since 23`, however it can't be called by anyone except FX
> itself.
>
> Some background: the readBinary/writeBinary methods are ultimately called via
> the publicly accessible methods `loadBinary` and `saveBinary` in
> `javafx.css.Stylesheet`.
>
> The reason it needs to be `protected` now is because `CompoundSelector` is
> using this (but IMHO, it shouldn't have). Why I say it shouldn't? That's
> because it already knows what it will be reading will all be
> `SimpleSelector`s, as it stores a counter (a `short`) and then loads that
> many `SimpleSelector`s. However, by not taking the direct route of using
> `SimpleSelector#readBinary` (and the corresponding
> `SimpleSelector#writeBinary`) there is an additional `byte` prefix indicating
> the type of selector -- this isn't needed and wastes some space in the binary
> format.
>
> Changing that now however would make the binary format incompatible with
> earlier versions, so I think making this `protected` is a reasonable
> solution. It also mirrors the `writeBinary` method then, which was already
> `protected`.
I missed something in my above evaluation. The counterpart method
`writeBinary` is not `static`. Although that makes sense as in that case you
do have an instance you wish to write, it does make the read/write API
asymmetric.
It's not possible to make `readBinary` an instance method though as it is the
method that is creating those instances.
The other way around is possible (make `writeBinary` static), but it would then
again need a pattern match to determine the correct static `writeBinary` to
call when writing an arbitrary `Selector`. However, this would have allowed
`CompoundSelector` to call a static version of `SimpleSelector#writeBinary` and
`readBinary`, avoiding the extra identifying byte in the binary format, and
avoiding the cast when reading it back.
The read/write loops below:
+
final int nSelectors = is.readShort();
final List<SimpleSelector> selectors = new ArrayList<>();
for (int n=0; n<nSelectors; n++) {
selectors.add((SimpleSelector)Selector.readBinary(bssVersion,
is,strings));
}
+
os.writeShort(selectors.size()); // writes the number of
SimpleSelectors to the binary stream
for (int n=0; n< selectors.size(); n++)
selectors.get(n).writeBinary(os,stringStore); // writes each individually
Would then have become:
+
final int nSelectors = is.readShort();
final List<SimpleSelector> selectors = new ArrayList<>();
for (int n=0; n<nSelectors; n++) {
selectors.add(SimpleSelector.readBinary(bssVersion, is,strings));
// cast is gone
}
+
os.writeShort(selectors.size()); // writes the number of
SimpleSelectors to the binary stream
for (int n=0; n< selectors.size(); n++)
SimpleSelector.writeBinaryStatic(selectors.get(n), os, stringStore); // writes
each individually
-------------
PR Review Comment: https://git.openjdk.org/jfx/pull/1333#discussion_r1458762627