001package arez;
002
003import arez.component.Verifiable;
004import grim.annotations.OmitClinit;
005import grim.annotations.OmitSymbol;
006import javax.annotation.Nonnull;
007import org.realityforge.braincheck.BrainCheckConfig;
008import static org.realityforge.braincheck.Guards.*;
009
010/**
011 * Provide access to an instance of ArezContext and Arez global configuration settings.
012 * The {@link #context()} should always return the current context. If {@link #areZonesEnabled()}
013 * is false it will return a singleton otherwise the appropriate context for the zone will be
014 * invoked.
015 */
016@OmitClinit
017public final class Arez
018{
019  private Arez()
020  {
021  }
022
023  /**
024   * Return true if zones are enabled, false otherwise.
025   *
026   * @return true if zones are enabled, false otherwise.
027   */
028  @OmitSymbol
029  public static boolean areZonesEnabled()
030  {
031    return ArezConfig.areZonesEnabled();
032  }
033
034  /**
035   * Return true if user should pass names into API methods, false if should pass null.
036   *
037   * @return true if user should pass names into API methods, false if should pass null.
038   */
039  @OmitSymbol
040  public static boolean areNamesEnabled()
041  {
042    return ArezConfig.areNamesEnabled();
043  }
044
045  /**
046   * Return true if {@link Verifiable} will verify components be used, false if not.
047   *
048   * @return true if {@link Verifiable} will verify components be used, false if not.
049   */
050  @OmitSymbol
051  public static boolean isVerifyEnabled()
052  {
053    return ArezConfig.isVerifyEnabled();
054  }
055
056  /**
057   * Return true if spies are enabled.
058   *
059   * @return true if spies are enabled, false otherwise.
060   */
061  @OmitSymbol
062  public static boolean areSpiesEnabled()
063  {
064    /*
065     * Spy's use debug names so we can not enable spies without names.
066     */
067    return areNamesEnabled() && ArezConfig.areSpiesEnabled();
068  }
069
070  /**
071   * Return true if references are enabled.
072   *
073   * @return true if references are enabled, false otherwise.
074   */
075  @OmitSymbol
076  public static boolean areReferencesEnabled()
077  {
078    return ArezConfig.areReferencesEnabled();
079  }
080
081  /**
082   * Return true if observable properties, computable properties or query results that are of type collection are wrapped in unmodifiable variant prior to returning.
083   *
084   * @return true if observable properties, computable properties or query results that are of type collection are wrapped in unmodifiable variant prior to returning.
085   */
086  @OmitSymbol
087  public static boolean areCollectionsPropertiesUnmodifiable()
088  {
089    return ArezConfig.areCollectionsPropertiesUnmodifiable();
090  }
091
092  /**
093   * Return true if property introspectors for Observables are enabled.
094   *
095   * @return true if property introspectors for Observables are enabled, false otherwise.
096   */
097  @OmitSymbol
098  public static boolean arePropertyIntrospectorsEnabled()
099  {
100    return areSpiesEnabled() && ArezConfig.arePropertyIntrospectorsEnabled();
101  }
102
103  /**
104   * Return true if registries for top level reactive components are enabled.
105   *
106   * @return true if registries for top level reactive components are enabled, false otherwise.
107   */
108  @OmitSymbol
109  public static boolean areRegistriesEnabled()
110  {
111    return areNamesEnabled() && ArezConfig.areRegistriesEnabled();
112  }
113
114  /**
115   * Return true if native components are enabled.
116   *
117   * @return true if native components are enabled, false otherwise.
118   */
119  @OmitSymbol
120  public static boolean areNativeComponentsEnabled()
121  {
122    return ArezConfig.areNativeComponentsEnabled();
123  }
124
125  /**
126   * Return true if observer error handlers are enabled.
127   *
128   * @return true if observer error handlers are enabled, false otherwise.
129   */
130  @OmitSymbol
131  public static boolean areObserverErrorHandlersEnabled()
132  {
133    return ArezConfig.areObserverErrorHandlersEnabled();
134  }
135
136  /**
137   * Return true if Arez should enforce transaction modes.
138   *
139   * @return true if Arez should enforce transaction modes.
140   */
141  @OmitSymbol
142  static boolean shouldEnforceTransactionType()
143  {
144    return ArezConfig.enforceTransactionType();
145  }
146
147  /**
148   * Return true if a task interceptor can be specified.
149   *
150   * @return true if a task interceptor can be specified
151   */
152  @OmitSymbol
153  public static boolean isTaskInterceptorEnabled()
154  {
155    return ArezConfig.isTaskInterceptorEnabled();
156  }
157
158  /**
159   * Return true if invariants will be checked.
160   *
161   * @return true if invariants will be checked.
162   */
163  @OmitSymbol
164  public static boolean shouldCheckInvariants()
165  {
166    return ArezConfig.checkInvariants() && BrainCheckConfig.checkInvariants();
167  }
168
169  /**
170   * Return true if apiInvariants will be checked.
171   *
172   * @return true if apiInvariants will be checked.
173   */
174  @OmitSymbol
175  public static boolean shouldCheckApiInvariants()
176  {
177    return ArezConfig.checkApiInvariants() && BrainCheckConfig.checkApiInvariants();
178  }
179
180  /**
181   * Return true if active tasks will be purged if the scheduler is still running after 100 rounds.
182   *
183   * @return true if active tasks will be purged if the scheduler is still running after 100 rounds.
184   */
185  @OmitSymbol
186  public static boolean purgeTasksWhenRunawayDetected()
187  {
188    return ArezConfig.purgeTasksWhenRunawayDetected();
189  }
190
191  /**
192   * Return the ArezContext from the provider.
193   *
194   * @return the ArezContext.
195   */
196  @Nonnull
197  public static ArezContext context()
198  {
199    return areZonesEnabled() ? ZoneHolder.context() : ArezContextHolder.context();
200  }
201
202  /**
203   * Create a new zone.
204   * This zone is not yet activated.
205   *
206   * @return the new zone.
207   */
208  @OmitSymbol( unless = "arez.enable_zones" )
209  @Nonnull
210  public static Zone createZone()
211  {
212    if ( shouldCheckApiInvariants() )
213    {
214      apiInvariant( Arez::areZonesEnabled, () -> "Arez-0001: Invoked Arez.createZone() but zones are not enabled." );
215    }
216    return new Zone();
217  }
218
219  /**
220   * Save the old zone and make the specified zone the current zone.
221   */
222  @OmitSymbol( unless = "arez.enable_zones" )
223  static void activateZone( @Nonnull final Zone zone )
224  {
225    ZoneHolder.activateZone( zone );
226  }
227
228  /**
229   * Restore the old zone.
230   * This takes the zone that was current when {@link #activateZone(Zone)} was called for the active zone
231   * and restores it to being the current zone.
232   */
233  @OmitSymbol( unless = "arez.enable_zones" )
234  static void deactivateZone( @Nonnull final Zone zone )
235  {
236    ZoneHolder.deactivateZone( zone );
237  }
238
239  /**
240   * Return the current zone.
241   *
242   * @return the current zone.
243   */
244  @OmitSymbol( unless = "arez.enable_zones" )
245  @Nonnull
246  static Zone currentZone()
247  {
248    return ZoneHolder.currentZone();
249  }
250}