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}