001package arez.component; 002 003import arez.Arez; 004import javax.annotation.Nonnull; 005import javax.annotation.Nullable; 006import static org.realityforge.braincheck.Guards.*; 007 008/** 009 * Interface implemented by components so that observers can observe the component without 010 * observing a particular property. 011 */ 012public interface ComponentObservable 013{ 014 /** 015 * Return true if the component is "alive" a.k.a. not disposing or disposed. 016 * This method MUST be invoked within a non-DISPOSE transaction and will add 017 * the component as a dependency if the transaction is tracking, unless 018 * this component is disposing or disposed. 019 * 020 * @return true if the component is "alive" a.k.a. not disposing or disposed. 021 */ 022 boolean observe(); 023 024 /** 025 * Invoke {@link #observe()} on the supplied object. 026 * 027 * @param object the object to observe. 028 * @return true if the component is not disposing or disposed, false otherwise. 029 */ 030 static boolean observe( @Nonnull final Object object ) 031 { 032 return asComponentObservable( object ).observe(); 033 } 034 035 /** 036 * Invoke {@link #observe()} on the supplied object if not null. 037 * 038 * @param object the object to observe if not null. 039 * @return true if the component is null or not disposing or disposed, false otherwise. 040 */ 041 static boolean maybeObserve( @Nullable final Object object ) 042 { 043 return null == object || asComponentObservable( object ).observe(); 044 } 045 046 /** 047 * Return true if {@link #observe(Object)} returns false for the same parameter. 048 * 049 * @param object the object to observe if any. 050 * @return true if {@link #observe(Object)} returns false for the same parameter, false otherwise. 051 */ 052 static boolean notObserved( @Nonnull final Object object ) 053 { 054 return !observe( object ); 055 } 056 057 /** 058 * Cast specified object to an instance of ComponentObservable. 059 * Invariant checks will verify that the cast is valid before proceeding. 060 * 061 * @param object the object. 062 * @return the object cast to ComponentObservable. 063 */ 064 @Nonnull 065 static ComponentObservable asComponentObservable( @Nonnull final Object object ) 066 { 067 if ( Arez.shouldCheckApiInvariants() ) 068 { 069 apiInvariant( () -> object instanceof ComponentObservable, 070 () -> "Arez-0179: Object passed to asComponentObservable does not implement " + 071 "ComponentObservable. Object: " + object ); 072 } 073 return (ComponentObservable) object; 074 } 075}