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}