Skip to content

Commit

Permalink
Finish public registry API
Browse files Browse the repository at this point in the history
  • Loading branch information
Jaxydog committed Jun 11, 2024
1 parent bb29659 commit 732849e
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 37 deletions.
110 changes: 92 additions & 18 deletions src/main/java/dev/jaxydog/lodestone/Lodestone.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,27 +64,58 @@ public class Lodestone implements ModInitializer {
* @since 1.0.0
*/
private static final Map<Class<? extends Loaded>, Queue<? extends Loaded>> QUEUE = new Object2ObjectOpenHashMap<>();
/**
* A map containing queues of to-be-loaded mod identifiers.
* <p>
* This is only used during mod initialization, in cases where an environment is loaded before it was registered.
*
* @since 1.0.0
*/
private static final Map<Class<? extends Loaded>, Queue<String>> LOADED = new Object2ObjectOpenHashMap<>();

/**
* Tracks whether the mod has finished loading all environment instances.
*
* @since 1.0.0
*/
private static final AtomicBoolean LOADED_ENVIRONMENTS = new AtomicBoolean(false);

/**
* Creates and registers a new environment for the given {@link Loaded} interface.
* <p>
* This is used to implement custom {@link Loaded} interfaces.
*
* @param type The {@link Loaded} interface.
* @param load A method that loads the given value.
* @param <T> The type of the {@link Loaded} interface.
*
* @since 1.0.0
*/
public static <T extends Loaded> void createEnvironment(Class<? extends T> type, Consumer<? super T> load) {
try {
REGISTRY.register(new LoaderEnvironment<>(type, load));
} catch (IllegalArgumentException exception) {
LOGGER.error(exception.getLocalizedMessage());
}
}

/**
* Registers a value for automatic registration.
*
* @param type The {@link Loaded} interface.
* @param value The value to be registered.
* @param queueIfMissing Whether values should be queued if the environment is missing.
* @param <T> The type of the {@link Loaded} interface.
*
* @since 1.0.0
*/
@SuppressWarnings("unchecked")
private static <T extends Loaded> void register(Class<? extends T> type, T value, boolean queueIfMissing) {
if (!queueIfMissing || REGISTRY.has(type)) {
REGISTRY.addEntrypoint(type, value);
public static <T extends Loaded> void register(Class<? extends T> type, T value) {
if (LOADED_ENVIRONMENTS.get()) {
try {
REGISTRY.addEntrypoint(type, value);
} catch (IllegalArgumentException exception) {
LOGGER.error(exception.getLocalizedMessage());
}
} else {
((Queue<T>) QUEUE.computeIfAbsent(type, t -> new ArrayDeque<T>(1))).add(value);
}
Expand All @@ -101,9 +132,7 @@ private static <T extends Loaded> void register(Class<? extends T> type, T value
*/
@SafeVarargs
public static <T extends Loaded> void register(Class<? extends T> type, T... values) {
final boolean queueIfMissing = !LOADED_ENVIRONMENTS.get();

for (final T value : values) register(type, value, queueIfMissing);
for (final T value : values) register(type, value);
}

/**
Expand All @@ -116,9 +145,7 @@ public static <T extends Loaded> void register(Class<? extends T> type, T... val
* @since 1.0.0
*/
public static <T extends Loaded> void register(Class<? extends T> type, Iterator<? extends T> values) {
final boolean queueIfMissing = !LOADED_ENVIRONMENTS.get();

values.forEachRemaining(value -> register(type, value, queueIfMissing));
values.forEachRemaining(value -> register(type, value));
}

/**
Expand All @@ -131,24 +158,67 @@ public static <T extends Loaded> void register(Class<? extends T> type, Iterator
* @since 1.0.0
*/
public static <T extends Loaded> void register(Class<? extends T> type, Collection<? extends T> values) {
final boolean queueIfMissing = !LOADED_ENVIRONMENTS.get();
values.forEach(value -> register(type, value));
}

values.forEach(value -> register(type, value, queueIfMissing));
/**
* Loads the target environment for the given mod identifier.
*
* @param type The {@link Loaded} interface.
* @param modId The requesting mod's identifier.
* @param <T> The type of the {@link Loaded} interface.
*
* @since 1.0.0
*/
public static <T extends Loaded> void load(Class<? extends T> type, String modId) {
if (LOADED_ENVIRONMENTS.get()) {
try {
REGISTRY.loadEntrypoints(type, modId);
} catch (IllegalArgumentException exception) {
LOGGER.error(exception.getLocalizedMessage());
}
} else {
LOADED.computeIfAbsent(type, t -> new ArrayDeque<>(1)).add(modId);
}
}

/**
* Creates and registers a new environment for the given {@link Loaded} interface.
* <p>
* This is used to implement custom {@link Loaded} interfaces.
* Loads the target environment for the given mod identifier.
*
* @param type The {@link Loaded} interface.
* @param load A method that loads the given value.
* @param modIds The requesting mod's identifiers.
* @param <T> The type of the {@link Loaded} interface.
*
* @since 1.0.0
*/
public static <T extends Loaded> void createEnvironment(Class<? extends T> type, Consumer<? super T> load) {
REGISTRY.register(new LoaderEnvironment<>(type, load));
public static <T extends Loaded> void load(Class<? extends T> type, String... modIds) {
for (final String modId : modIds) load(type, modId);
}

/**
* Loads the target environment for the given mod identifier.
*
* @param type The {@link Loaded} interface.
* @param modIds The requesting mod's identifiers.
* @param <T> The type of the {@link Loaded} interface.
*
* @since 1.0.0
*/
public static <T extends Loaded> void load(Class<? extends T> type, Iterator<String> modIds) {
modIds.forEachRemaining(modId -> load(type, modId));
}

/**
* Loads the target environment for the given mod identifier.
*
* @param type The {@link Loaded} interface.
* @param modIds The requesting mod's identifiers.
* @param <T> The type of the {@link Loaded} interface.
*
* @since 1.0.0
*/
public static <T extends Loaded> void load(Class<? extends T> type, Collection<String> modIds) {
modIds.forEach(modId -> load(type, modId));
}

@Override
Expand All @@ -168,6 +238,10 @@ public void onInitialize() {
LOADED_ENVIRONMENTS.set(true);

QUEUE.forEach(Lodestone::register);
QUEUE.clear();

LOADED.forEach(Lodestone::load);
LOADED.clear();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import org.jetbrains.annotations.ApiStatus.Internal;

import java.util.Map;
import java.util.Optional;
import java.util.Set;

/**
Expand Down Expand Up @@ -96,24 +95,6 @@ public <T extends Loaded> boolean has(Class<? extends T> type) {
return this.entries.containsKey(type);
}

/**
* Returns the {@link LoaderEnvironment} instance associated with the given {@link Loaded} interface, if it was
* previously registered.
*
* @param type The expected {@link Loaded} interface.
* @param <T> The type of the associated {@link Loaded} interface.
*
* @return The {@link LoaderEnvironment} instance, if it exists.
*
* @since 1.0.0
*/
@SuppressWarnings("unchecked")
public <T extends Loaded> Optional<LoaderEnvironment<T>> get(Class<? extends T> type) {
if (!this.has(type)) return Optional.empty();

return Optional.of((LoaderEnvironment<T>) this.entries.get(type).environment());
}

/**
* Adds an entrypoint to the {@link LoaderEnvironmentRegistry} instance associated with the given {@link Loaded}
* interface.
Expand Down

0 comments on commit 732849e

Please sign in to comment.