-
-
Notifications
You must be signed in to change notification settings - Fork 82
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add annotations to data tag container * Composition over inheritance, concurrency * Concurrent registry * Avoid defaults on non-try/default methods * Field ordering, access modifiers * try method is not try * cleanup * Add javadoc * Remove defaults * Update return type * annotations * annotations * Discreet data tag registry * Fix build * Add iterator over entries
- Loading branch information
Showing
7 changed files
with
133 additions
and
68 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
79 changes: 41 additions & 38 deletions
79
api/src/main/java/net/countercraft/movecraft/craft/datatag/CraftDataTagContainer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,53 +1,56 @@ | ||
package net.countercraft.movecraft.craft.datatag; | ||
|
||
import net.countercraft.movecraft.craft.Craft; | ||
import org.bukkit.NamespacedKey; | ||
import org.jetbrains.annotations.NotNull; | ||
import org.jetbrains.annotations.Nullable; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.function.Function; | ||
import java.util.function.Supplier; | ||
import java.util.Objects; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
import java.util.concurrent.ConcurrentMap; | ||
|
||
public class CraftDataTagContainer extends HashMap<CraftDataTagKey<?>, Object> { | ||
public class CraftDataTagContainer { | ||
private final @NotNull ConcurrentMap<@NotNull CraftDataTagKey<?>, @Nullable Object> backing; | ||
|
||
public static final Map<NamespacedKey, CraftDataTagKey<?>> REGISTERED_TAGS = new HashMap<>(); | ||
|
||
public static <T> CraftDataTagKey<T> tryRegisterTagKey(final NamespacedKey key, final Function<Craft, T> supplier) throws IllegalArgumentException { | ||
if (REGISTERED_TAGS.containsKey(key)) { | ||
throw new IllegalArgumentException("Duplicate keys are not allowed!"); | ||
} else { | ||
CraftDataTagKey<T> result = new CraftDataTagKey<T>(key, supplier); | ||
REGISTERED_TAGS.put(key, result); | ||
return result; | ||
} | ||
public CraftDataTagContainer(){ | ||
backing = new ConcurrentHashMap<>(); | ||
} | ||
|
||
public <T> T get(final Craft craft, CraftDataTagKey<T> tagKey) { | ||
if (!REGISTERED_TAGS.containsKey(tagKey.key)) { | ||
// TODO: Log error | ||
return null; | ||
/** | ||
* Gets the data value associated with the provided tagKey from a craft. | ||
* | ||
* @param craft the craft to perform a lookup against | ||
* @param tagKey the tagKey to use for looking up the relevant data | ||
* @return the tag value associate with the provided tagKey on the specified craft | ||
* @param <T> the value type of the registered data key | ||
* @throws IllegalArgumentException when the provided tagKey is not registered | ||
* @throws IllegalStateException when the provided tagKey does not match the underlying tag value | ||
*/ | ||
public <T> T get(final @NotNull Craft craft, @NotNull CraftDataTagKey<T> tagKey) { | ||
if (!CraftDataTagRegistry.INSTANCE.isRegistered(tagKey.key)) { | ||
throw new IllegalArgumentException(String.format("The provided key %s was not registered.", tagKey)); | ||
} | ||
T result = null; | ||
if (!this.containsKey(tagKey)) { | ||
result = tagKey.createNew(craft); | ||
this.put(tagKey, result); | ||
} else { | ||
Object stored = this.getOrDefault(tagKey, tagKey.createNew(craft)); | ||
try { | ||
T temp = (T) stored; | ||
result = temp; | ||
} catch (ClassCastException cce) { | ||
// TODO: Log error | ||
result = tagKey.createNew(craft); | ||
this.put(tagKey, result); | ||
} | ||
|
||
Object stored = backing.computeIfAbsent(tagKey, ignored -> tagKey.createNew(craft)); | ||
try { | ||
//noinspection unchecked | ||
return (T) stored; | ||
} catch (ClassCastException cce) { | ||
throw new IllegalStateException(String.format("The provided key %s has an invalid value type.", tagKey), cce); | ||
} | ||
return result; | ||
} | ||
|
||
public <T> void set(CraftDataTagKey<T> tagKey, @NotNull T value) { | ||
this.put(tagKey, value); | ||
} | ||
/** | ||
* Set the value associated with the provided tagKey on the associated craft. | ||
* | ||
* @param tagKey the tagKey to use for storing the relevant data | ||
* @param value the value to set for future lookups | ||
* @param <T> the type of the value | ||
*/ | ||
public <T> void set(@NotNull CraftDataTagKey<T> tagKey, @NotNull T value) { | ||
if (!CraftDataTagRegistry.INSTANCE.isRegistered(tagKey.key)) { | ||
throw new IllegalArgumentException(String.format("The provided key %s was not registered.", tagKey)); | ||
} | ||
|
||
backing.put(tagKey, value); | ||
} | ||
} |
54 changes: 54 additions & 0 deletions
54
api/src/main/java/net/countercraft/movecraft/craft/datatag/CraftDataTagRegistry.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package net.countercraft.movecraft.craft.datatag; | ||
|
||
import net.countercraft.movecraft.craft.Craft; | ||
import org.bukkit.NamespacedKey; | ||
import org.jetbrains.annotations.NotNull; | ||
|
||
import java.util.Enumeration; | ||
import java.util.Set; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
import java.util.concurrent.ConcurrentMap; | ||
import java.util.function.Function; | ||
|
||
public class CraftDataTagRegistry { | ||
public static final @NotNull CraftDataTagRegistry INSTANCE = new CraftDataTagRegistry(); | ||
|
||
private final @NotNull ConcurrentMap<@NotNull NamespacedKey, @NotNull CraftDataTagKey<?>> _registeredTags; | ||
|
||
public CraftDataTagRegistry(){ | ||
_registeredTags = new ConcurrentHashMap<>(); | ||
} | ||
|
||
/** | ||
* Registers a data tag to be attached to craft instances. The data tag will initialize to the value supplied by the | ||
* initializer. Once a tag is registered, it can be accessed from crafts using the returned key through various | ||
* methods. | ||
* | ||
* @param key the namespace key to use for registration, which must be unique | ||
* @param initializer a default initializer for the value type | ||
* @return A CraftDataTagKey, which can be used to control an associated value on a Craft instance | ||
* @param <T> the value type | ||
* @throws IllegalArgumentException when the provided key is already registered | ||
*/ | ||
public <T> @NotNull CraftDataTagKey<T> registerTagKey(final @NotNull NamespacedKey key, final @NotNull Function<Craft, T> initializer) throws IllegalArgumentException { | ||
CraftDataTagKey<T> result = new CraftDataTagKey<>(key, initializer); | ||
var previous = _registeredTags.putIfAbsent(key, result); | ||
if(previous != null){ | ||
throw new IllegalArgumentException(String.format("Key %s is already registered.", key)); | ||
} | ||
|
||
return result; | ||
} | ||
|
||
public boolean isRegistered(final @NotNull NamespacedKey key){ | ||
return _registeredTags.containsKey(key); | ||
} | ||
|
||
/** | ||
* Get an iterable over all keys currently registered. | ||
* @return An immutable iterable over the registry keys | ||
*/ | ||
public @NotNull Iterable<@NotNull NamespacedKey> getAllKeys(){ | ||
return _registeredTags.keySet().stream().toList(); | ||
} | ||
} |