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