Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions api-internal/src/main/java/at/pavlov/internal/Key.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;

import java.util.Collection;
import java.util.Locale;
import java.util.regex.Pattern;

Expand Down Expand Up @@ -40,6 +41,10 @@ public static Key from(String compositeKey) {
return new Key(strings[0].trim(), strings[1].trim());
}

public static Collection<Key> from(Collection<String> collection) {
return collection.stream().map(Key::from).toList();
}

public String full() {
return namespace + ":" + key;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package at.pavlov.internal.key;

import at.pavlov.internal.Key;

public interface EntityKeyHolder {
Key getEntityKey();
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package at.pavlov.internal.registries;
package at.pavlov.internal.key;

import at.pavlov.internal.Key;

public interface KeyHolder {
Key key();
Key getKey();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package at.pavlov.internal.key.registries;

import at.pavlov.internal.Key;
import at.pavlov.internal.projectile.definition.CustomProjectileDefinition;
import at.pavlov.internal.projectile.definition.DefaultProjectileDefinition;
import at.pavlov.internal.projectile.definition.ProjectilePhysics;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class Registries {
public static final Registry.Composite<ProjectilePhysics> PROJECTILE_PHYSICS;
public static final Registry<CustomProjectileDefinition> CUSTOM_PROJECTILE_DEFINITION;
public static final Registry<DefaultProjectileDefinition> DEFAULT_PROJECTILE_DEFINITION_REGISTRY;

static {
CUSTOM_PROJECTILE_DEFINITION = new Registry<>();
DEFAULT_PROJECTILE_DEFINITION_REGISTRY = new Registry<>(() -> {
List<DefaultProjectileDefinition> toAdd = new ArrayList<>();

Collection<Key> fireballs = Key.from(
List.of("minecraft:fireball", "minecraft:small_fireball", "minecraft:dragon_fireball", "minecraft:wither_skull", "minecraft:shulker_bullet")
);
var fireballBuilder = DefaultProjectileDefinition.builder()
.gravity(0.0)
.drag(0.95)
.waterDrag(0.95)
.constantAcceleration(0.1);
for (Key fireball : fireballs) {
toAdd.add(
fireballBuilder
.key(fireball)
.build()
);
}

Collection<Key> arrows = Key.from(List.of("minecraft:arrow", "minecraft:spectral_arrow"));
var arrowBuilder = DefaultProjectileDefinition.builder()
.gravity(0.05)
.drag(0.99)
.waterDrag(0.6);
for (Key arrow : arrows) {
toAdd.add(
arrowBuilder
.key(arrow)
.build()
);
}

toAdd.add(
DefaultProjectileDefinition.builder()
.gravity(0.05)
.drag(0.99)
.waterDrag(0.99)
.key(Key.mc("trident"))
.build()
);

toAdd.add(
DefaultProjectileDefinition.builder()
.gravity(0.0)
.drag(1.0)
.waterDrag(1.0)
.key(Key.mc("breeze_wind_charge"))
.build()
);

return toAdd;
});
SharedRegistryKeyValidator<ProjectilePhysics> validator = new SharedRegistryKeyValidator<>(CUSTOM_PROJECTILE_DEFINITION, DEFAULT_PROJECTILE_DEFINITION_REGISTRY);
CUSTOM_PROJECTILE_DEFINITION.setValidator(validator);
DEFAULT_PROJECTILE_DEFINITION_REGISTRY.setValidator(validator);
DEFAULT_PROJECTILE_DEFINITION_REGISTRY.setFrozen(true);

PROJECTILE_PHYSICS = new Registry.Composite<>(CUSTOM_PROJECTILE_DEFINITION, DEFAULT_PROJECTILE_DEFINITION_REGISTRY);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
package at.pavlov.internal.key.registries;

import at.pavlov.internal.Key;
import at.pavlov.internal.key.KeyHolder;
import at.pavlov.internal.key.registries.exceptions.RegistryDuplicate;
import at.pavlov.internal.key.registries.exceptions.RegistryFrozen;
import at.pavlov.internal.key.registries.exceptions.RegistryValidator;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

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

@NoArgsConstructor
public class Registry<T extends KeyHolder> implements RegistryAccess<T> {
protected final Map<Key, T> map = new HashMap<>();
@Setter
@Getter
protected boolean frozen = false;
@Setter
protected @NotNull RegistryValidator<? super T> validator = (key, value) -> {};

public static class Composite<T extends KeyHolder> implements RegistryAccess<T> {
protected final List<Registry<? extends T>> list = new ArrayList<>();

@SafeVarargs
public Composite(Registry<? extends T>... args) {
list.addAll(Arrays.asList(args));
}

@Override
public boolean has(@NotNull Key key) {
for (var registry : list) {
if (registry.map.containsKey(key)) {
return true;
}
}

return false;
}

@Override
public @NotNull T of(@Nullable Key key, @NotNull T defaultValue) {
if (key == null) {
return defaultValue;
}

for (var registry : list) {
T value = registry.map.get(key);
if (value != null) {
return value;
}
}

return defaultValue;
}

@Override
public @Nullable T of(@Nullable Key key) {
if (key == null) {
return null;
}

for (var registry : list) {
T value = registry.map.get(key);
if (value != null) {
return value;
}
}

return null;
}
}

public Registry(Supplier<Collection<@NotNull T>> args) {
Collection<@NotNull T> arguments = args.get();
for (T arg : arguments) {
register(arg);
}
}

@Override
public boolean has(@NotNull Key key) {
return map.containsKey(key);
}

@Override
public @NotNull T of(@Nullable Key key, @NotNull T defaultValue) {
if (key == null) {
return defaultValue;
}

return map.getOrDefault(key, defaultValue);
}

@Override
public @Nullable T of(@Nullable Key key) {
if (key == null) {
return null;
}

return map.get(key);
}

@SafeVarargs
public final void register(@NotNull T... entries) {
if (frozen) {
throw new RegistryFrozen("Can't register key for frozen registry");
}

for (T entry : entries) {
Key key = entry.getKey();
if (map.containsKey(key)) {
throw new RegistryDuplicate("Duplicate key in registry of class: " + entry.getClass());
}

try {
validator.test(key, entry);
map.put(key, entry);
} catch (Exception e) {
e.printStackTrace();
}
}
}

public void register(Supplier<@NotNull T> entry) {
if (frozen) {
throw new RegistryFrozen("Can't register key for frozen registry");
}

T result = entry.get();
Key key = result.getKey();
validator.test(key, result);

if (map.containsKey(key)) {
throw new RegistryDuplicate("Duplicate key in registry of class: " + entry.getClass());
}

map.put(key, result);
}

public void clear() {
map.clear();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package at.pavlov.internal.key.registries;

import at.pavlov.internal.Key;
import at.pavlov.internal.key.KeyHolder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public interface RegistryAccess<T extends KeyHolder> {
boolean has(@NotNull Key key);

default boolean has(@NotNull String key) {
return has(Key.from(key));
}

@NotNull T of(@Nullable Key key, @NotNull T defaultValue);

default @NotNull T of(@Nullable String string, @NotNull T defaultValue) {
if (string == null) {
return defaultValue;
}

return of(Key.from(string), defaultValue);
}

@Nullable T of(@Nullable Key key);

default @Nullable T of(@Nullable String string) {
if (string == null) {
return null;
}

return of(Key.from(string));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package at.pavlov.internal.key.registries;

import at.pavlov.internal.Key;
import at.pavlov.internal.key.KeyHolder;
import at.pavlov.internal.key.registries.exceptions.RegistryException;
import at.pavlov.internal.key.registries.exceptions.RegistryValidator;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class SharedRegistryKeyValidator<T extends KeyHolder> implements RegistryValidator<T> {
private final List<RegistryAccess<? extends T>> list = new ArrayList<>();

@SafeVarargs
public SharedRegistryKeyValidator(RegistryAccess<? extends T>... registries) {
list.addAll(Arrays.asList(registries));
}

@Override
public void test(Key key, T value) throws RegistryException {
for (RegistryAccess<? extends T> registry : list) {
if (registry.has(key)) {
throw new RegistryException("Duplicate key detected across registries: " + key);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package at.pavlov.internal.key.registries.exceptions;

public class RegistryDuplicate extends RegistryException {
public RegistryDuplicate(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package at.pavlov.internal.key.registries.exceptions;

public class RegistryException extends RuntimeException {
public RegistryException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package at.pavlov.internal.key.registries.exceptions;

public class RegistryFrozen extends RegistryException {
public RegistryFrozen(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package at.pavlov.internal.key.registries.exceptions;

import at.pavlov.internal.Key;
import at.pavlov.internal.key.KeyHolder;

public interface RegistryValidator<T extends KeyHolder> {
void test(Key key, T value) throws RegistryException;
}
Loading