On Sun, 5 Feb 2023 13:07:25 GMT, John Hendrikx <jhendr...@openjdk.org> wrote:

> This PR contains changes to make it easier to implement properties which want 
> to conserve resources until they're observed themselves.  
> 
> `isObserved` is promoted from `ObjectBinding` to the `ObservableValue` 
> interface, allowing you to ask any `ObservableValue` if it is currently 
> observed (ie. if it has any listeners registered on it).  All JavaFX 
> `ObservableValue`s implementations are modified to implement this method.
> 
> The protected methods `observed` and `unobserved` are added to all extendable 
> (non final) `ObservableValue`s provided by JavaFX.  The `observed` call back 
> is only called when the observable currently has 0 listeners and will soon 
> have 1 listener.  During the call back, `isObserved` still returns `false` 
> (see below for why this was chosen).  The `unobserved` call back is only 
> called when the last listener was removed and the observable has 0 listeners. 
>  During the call back, `isObserved` will already return `false`.
> 
> The reason why `observed` is called before `isObserved` starts returning 
> `true` (and also why `unobserved` works the opposite) is to make it easy to 
> implement a parent-child relationship where a nested property becoming 
> observed may need to trigger behavior in its parent. Given a parent class and 
> two nested properties `foo` and `bar`:
> 
>      class FooProperty extends ObjectPropertyBase<Foo> {
>           void observed() {
>                nestedPropertyObserved();  // call to parent
>           }
> 
>           void unobserved() {
>                nestedPropertyUnobserved();  // call to parent
>           }
>      }
> 
> The parent may determine whether any of the properties is observed with a 
> helper:
> 
>       private boolean isANestedPropertyObserved() {
>            return foo.isObserved() || bar.isObserved();
>       }
> 
> The `nestedPropertyObserved` and `nestedPropertyUnobserved` methods can now 
> be implemented simply as:
> 
>       private void nestedPropertyObserved() {
>             if (!isANestedPropertyObserved()) {
>                 // take action as no properties were observed before, but now 
> one will become observed
>             }
>       }
> 
>       private void nestedPropertyUnobserved() {
>             if (!isANestedPropertyObserved()) {
>                 // take action as a property was observed before, but the 
> last listener is about to be removed
>             }
>       }
> 
> If `isObserved` would change immediately, this becomes more difficult as the 
> observed status of the property that has just become observed would need to 
> be excluded to determine if this is the first observation of a nested 
> property or a later one.
> 
> - Add `isObserved` to `ObservableValue` to check if it is observed and 
> implement it in all overriding classes
> - Add `observed`/`unobserved` protected methods to all extendable observables
> - Use *Base classes in a few places (avoids duplication code)
> - Simplify `LazyObjectBinding`
> - In `ObjectBinding`, `isObserved` has become public as it is specified by 
> the `ObservableValue` interface now

@nlisker do you also want to review this?

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

PR Comment: https://git.openjdk.org/jfx/pull/1023#issuecomment-1479635579

Reply via email to