Skip to content

Commit

Permalink
Release 1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Raft08 committed Nov 2, 2024
1 parent 921f023 commit 3188f6e
Show file tree
Hide file tree
Showing 8 changed files with 227 additions and 26 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ org.gradle.daemon = true
name = AtlasRegistries
description = AtlasWorld's Universal Registry API

project_group = fr.atlasworld.registries
project_group = fr.atlasworld.registry

java_version = 21

Expand Down

This file was deleted.

96 changes: 96 additions & 0 deletions src/main/java/fr/atlasworld/registry/Register.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package fr.atlasworld.registry;

import com.google.common.base.Preconditions;
import fr.atlasworld.registry.event.RegistrationEvent;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;

/**
* Register, handles the registering of all provided entries.
*
* @param <T> type of values to be registered.
*/
public final class Register<T> {
private final String namespace;

private final Map<RegistryKey, Supplier<T>> registeredValues;
private final List<RegistryObject<T>> objects;

private boolean registered = false;

public Register(@NotNull String namespace) {
Preconditions.checkArgument(RegistryKey.isValidNamespace(namespace), "Invalid namespace, must be [a-z0-9._-]: %s", namespace);

this.namespace = namespace;

this.registeredValues = new HashMap<>();
this.objects = new ArrayList<>();
}

/**
* Registers an element to the register.
*
* @param name name of the element, must also be a valid key for a {@link RegistryKey}.
* @param constructor supplier that will supply the object when the register is called for registering.
*
* @return registry object for the registered object,
* reference will only be provided when the register is called for registering.
*
* @throws IllegalArgumentException if the name is not a valid key for a {@link RegistryKey}.
* @throws IllegalStateException if an element with the provided name has already been registered before.
*/
public RegistryObject<T> register(@NotNull String name, @NotNull Supplier<T> constructor) {
Preconditions.checkArgument(!this.registered, "Entries cannot be added after the register has been registered!");

Preconditions.checkArgument(RegistryKey.isValidKey(name), "Invalid name, must be [a-z0-9/._-]: %s", name);
Preconditions.checkNotNull(constructor);

RegistryKey key = new RegistryKey(this.namespace, name);
if (this.registeredValues.containsKey(key))
throw new IllegalStateException("Element with this name has already been registered.");

RegistryObject<T> holder = new RegistryObject<>(key);

this.registeredValues.put(key, constructor);
this.objects.add(holder);

return holder;
}

/**
* Register the elements of this register to the provided registry.
*
* @param registry registry to register the elements to.
*
* @throws IllegalStateException if the register has already been registered.
*/
public void register(@NotNull Registry<T> registry) {
Preconditions.checkNotNull(registry);
Preconditions.checkArgument(!this.registered, "Register ahs already seen the registry!");

this.registered = true;
this.registeredValues.forEach((key, sup) -> {
T value = sup.get();
registry.register(key, value);
});

this.objects.forEach(holder -> holder.updateReference(registry));
}

/**
* Register the elements of this register to the provided registry.
*
* @param event event containing the registry.
*
* @throws IllegalStateException if the register has already been registered.
*/
public void register(@NotNull RegistrationEvent<T> event) {
Preconditions.checkNotNull(event);
event.register(this);
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package fr.atlasworld.registries;
package fr.atlasworld.registry;

import fr.atlasworld.registries.event.RegistrationEvent;
import fr.atlasworld.registry.event.RegistrationEvent;
import org.jetbrains.annotations.NotNull;

import javax.annotation.concurrent.ThreadSafe;
import java.util.ConcurrentModificationException;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package fr.atlasworld.registries;
package fr.atlasworld.registry;

import com.google.common.base.Preconditions;
import org.jetbrains.annotations.NotNull;
Expand Down Expand Up @@ -133,7 +133,7 @@ private static boolean isValidNamespaceChar(char c) {
* @return true if the key char is valid, false otherwise.
*/
private static boolean isValidKeyChar(char c) {
return isValidNamespaceChar(c) || c == '/';
return c == '/' || isValidNamespaceChar(c);
}

/**
Expand Down
82 changes: 82 additions & 0 deletions src/main/java/fr/atlasworld/registry/RegistryObject.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package fr.atlasworld.registry;

import com.google.common.base.Preconditions;
import org.jetbrains.annotations.NotNull;

import javax.annotation.concurrent.ThreadSafe;
import java.util.NoSuchElementException;
import java.util.Optional;

/**
* Holds the instance of a registered object.
*
* @param <T> type of values hold in the registry.
*/
@ThreadSafe
public class RegistryObject<T> {
private final RegistryKey key;
private volatile T value;

public RegistryObject(@NotNull RegistryKey key) {
Preconditions.checkNotNull(key);

this.key = key;
}

/**
* Update the reference of the object.
*
* @param registry registry to update from.
*
* @throws IllegalStateException if the registry object already holds the reference.
* @throws IllegalArgumentException if the registry does not contain a reference to this object.
*/
public synchronized void updateReference(@NotNull Registry<T> registry) {
Preconditions.checkNotNull(registry);
Preconditions.checkArgument(this.value == null, "Reference has already been updated!");

this.value = registry.retrieveValue(this.key).orElseThrow(() -> new IllegalArgumentException("Registry does not contain any reference to the object."));
}

/**
* Verify if the reference is present.
*
* @return true if the reference is present, false otherwise.
*/
public boolean referencePresent() {
return this.value != null;
}

/**
* Retrieve the reference of the object.
*
* @return reference of the object.
* @throws NoSuchElementException if this registry object does not contain the reference to the object.
*/
@NotNull
public T get() {
if (this.value == null)
throw new NoSuchElementException("Registry reference is not present!");

return this.value;
}

/**
* Retrieve the key of the object.
*
* @return key of the object.
*/
@NotNull
public RegistryKey key() {
return this.key;
}

/**
* Retrieve the reference of this object as an optional.
*
* @return optional containing the reference of this object.
*/
public Optional<T> asOptional() {
return Optional.ofNullable(this.value);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package fr.atlasworld.registries;
package fr.atlasworld.registry;

import com.google.common.base.Preconditions;
import com.google.common.base.Supplier;
Expand Down
43 changes: 43 additions & 0 deletions src/main/java/fr/atlasworld/registry/event/RegistrationEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package fr.atlasworld.registry.event;

import com.google.common.base.Preconditions;
import fr.atlasworld.event.api.Event;
import fr.atlasworld.registry.Register;
import fr.atlasworld.registry.Registry;
import fr.atlasworld.registry.RegistryKey;
import org.jetbrains.annotations.NotNull;

public class RegistrationEvent<T> implements Event {
private final Registry<T> registry;

protected RegistrationEvent(@NotNull Registry<T> registry) {
Preconditions.checkNotNull(registry);

this.registry = registry;
}

/**
* Register an element directly to the registry.
* <p>
* This way is not most recommended, the usage of a {@link Register} is recommended.
*
* @param key key to register the value with.
* @param value value to register.
*/
public void register(@NotNull RegistryKey key, @NotNull T value) {
Preconditions.checkNotNull(key);
Preconditions.checkNotNull(value);

this.registry.register(key, value);
}

/**
* Register a register to the registry.
*
* @param register register to register.
*/
public void register(@NotNull Register<T> register) {
Preconditions.checkNotNull(register);
register.register(this.registry);
}
}

0 comments on commit 3188f6e

Please sign in to comment.