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