fancyholograms-v3: Refactor HologramTrait and registry to use annotations for trait identification

This commit is contained in:
Oliver
2025-05-18 00:11:42 +02:00
parent 1b764b9cb7
commit ccc238bbad
8 changed files with 81 additions and 51 deletions

View File

@@ -1,8 +0,0 @@
package de.oliver.fancyholograms.api.trait;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface DefaultTrait {
}

View File

@@ -22,7 +22,6 @@ import java.util.concurrent.ScheduledExecutorService;
@ApiStatus.Experimental
public abstract class HologramTrait {
protected final String name;
protected final FancyHolograms api = FancyHolograms.get();
protected final ExtendedFancyLogger logger = api.getFancyLogger();
protected final HologramController controller = api.getController();
@@ -31,25 +30,13 @@ public abstract class HologramTrait {
protected Hologram hologram;
protected JDB storage;
/**
* Creates a new hologram trait with the given name.
* @param name the name of the trait
*/
public HologramTrait(String name) {
this.name = name;
}
public HologramTrait() {
this.name = getClass().getSimpleName();
}
public void attachHologram(Hologram hologram) {
if (this.hologram != null) {
throw new IllegalStateException("Trait is already attached to a hologram");
}
this.hologram = hologram;
this.storage = new JDB("plugins/FancyHolograms/data/traits/" + name);
this.storage = new JDB("plugins/FancyHolograms/data/traits/" + getName());
onAttach();
}
@@ -100,7 +87,11 @@ public abstract class HologramTrait {
}
public String getName() {
return name;
if (getClass().isAnnotationPresent(HologramTraitClass.class)) {
return getClass().getAnnotation(HologramTraitClass.class).traitName();
}
throw new IllegalArgumentException("Trait class " + getClass() + " is not annotated with HologramTraitClass");
}
public Hologram getHologram() {

View File

@@ -0,0 +1,19 @@
package de.oliver.fancyholograms.api.trait;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface HologramTraitClass {
/**
* The name of the trait. This is used to identify the trait in the system.
* @return The name of the trait.
*/
String traitName();
/**
* Whether the trait is a default trait or not. Default traits are automatically attached to holograms.
* @return The description of the trait.
*/
boolean defaultTrait() default false;
}

View File

@@ -2,20 +2,31 @@ package de.oliver.fancyholograms.api.trait;
import org.jetbrains.annotations.ApiStatus;
import java.util.Set;
import java.util.List;
@ApiStatus.Experimental
public interface HologramTraitRegistry {
@ApiStatus.Experimental
boolean register(Class<? extends HologramTrait> trait);
void register(Class<? extends HologramTrait> trait);
@ApiStatus.Experimental
boolean unregister(Class<? extends HologramTrait> trait);
void unregister(Class<? extends HologramTrait> trait);
@ApiStatus.Experimental
boolean isRegistered(Class<? extends HologramTrait> trait);
@ApiStatus.Experimental
Set<Class<? extends HologramTrait>> getRegisteredTraits();
TraitInfo getTrait(String name);
@ApiStatus.Experimental
List<TraitInfo> getTraits();
public record TraitInfo(
String name,
Class<? extends HologramTrait> clazz,
boolean isDefault
) {
}
}

View File

@@ -6,14 +6,13 @@ import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@HologramTraitClass(traitName = "trait_trait")
public class HologramTraitTrait extends HologramTrait {
private final List<HologramTrait> traits;
public HologramTraitTrait(Hologram hologram) {
super("trait");
this.traits = new ArrayList<>();
attachHologram(hologram);
}
@@ -30,14 +29,14 @@ public class HologramTraitTrait extends HologramTrait {
@Override
public void onAttach() {
// Attach all default traits to the hologram
Set<Class<? extends HologramTrait>> registeredTraits = api.getTraitRegistry().getRegisteredTraits();
for (Class<? extends HologramTrait> traitClass : registeredTraits) {
if (!traitClass.isAnnotationPresent(DefaultTrait.class)) {
List<HologramTraitRegistry.TraitInfo> registeredTraits = api.getTraitRegistry().getTraits();
for (HologramTraitRegistry.TraitInfo ti : registeredTraits) {
if (!ti.isDefault()) {
continue;
}
try {
HologramTrait trait = traitClass.getConstructor().newInstance();
HologramTrait trait = ti.clazz().getConstructor().newInstance();
if (!new HologramTraitAttachedEvent(hologram, trait, false).callEvent()) {
continue;
}
@@ -45,11 +44,11 @@ public class HologramTraitTrait extends HologramTrait {
trait.attachHologram(hologram);
this.traits.add(trait);
} catch (Exception e) {
logger.error("Failed to instantiate trait " + traitClass.getName());
logger.error("Failed to instantiate trait " + ti.name());
logger.error(e);
}
logger.debug("Attached default trait " + traitClass.getName() + " to hologram " + hologram.getData().getName());
logger.debug("Attached default trait " + ti.name() + " to hologram " + hologram.getData().getName());
}
}

View File

@@ -1,36 +1,55 @@
package de.oliver.fancyholograms.trait;
import de.oliver.fancyholograms.api.trait.HologramTrait;
import de.oliver.fancyholograms.api.trait.HologramTraitClass;
import de.oliver.fancyholograms.api.trait.HologramTraitRegistry;
import java.util.HashSet;
import java.util.Set;
import java.util.HashMap;
import java.util.List;
public class HologramTraitRegistryImpl implements HologramTraitRegistry {
private final Set<Class<? extends HologramTrait>> traits;
private final HashMap<String, TraitInfo> traits;
public HologramTraitRegistryImpl() {
this.traits = new HashSet<>();
this.traits = new HashMap<>();
}
@Override
public boolean register(Class<? extends HologramTrait> trait) {
return traits.add(trait);
public void register(Class<? extends HologramTrait> trait) {
TraitInfo info = getInfo(trait);
traits.put(info.name(), info);
}
@Override
public boolean unregister(Class<? extends HologramTrait> trait) {
return traits.remove(trait);
public void unregister(Class<? extends HologramTrait> trait) {
TraitInfo info = getInfo(trait);
traits.remove(info.name());
}
@Override
public boolean isRegistered(Class<? extends HologramTrait> trait) {
return traits.contains(trait);
TraitInfo info = getInfo(trait);
return traits.containsKey(info.name());
}
@Override
public Set<Class<? extends HologramTrait>> getRegisteredTraits() {
return Set.copyOf(traits);
public TraitInfo getTrait(String name) {
return traits.get(name);
}
@Override
public List<TraitInfo> getTraits() {
return List.copyOf(traits.values());
}
private TraitInfo getInfo(Class<? extends HologramTrait> trait) {
if (trait.isAnnotationPresent(HologramTraitClass.class)) {
String name = trait.getAnnotation(HologramTraitClass.class).traitName();
boolean isDefault = trait.getAnnotation(HologramTraitClass.class).defaultTrait();
return new TraitInfo(name, trait, isDefault);
}
throw new IllegalArgumentException("Trait class " + trait.getName() + " is not annotated with HologramTraitClass");
}
}

View File

@@ -2,6 +2,7 @@ package de.oliver.fancyholograms.trait.builtin;
import de.oliver.fancyholograms.api.data.TextHologramData;
import de.oliver.fancyholograms.api.trait.HologramTrait;
import de.oliver.fancyholograms.api.trait.HologramTraitClass;
import org.jetbrains.annotations.ApiStatus;
import java.io.IOException;
@@ -11,6 +12,7 @@ import java.nio.file.Paths;
import java.util.List;
@ApiStatus.Experimental
@HologramTraitClass(traitName = "file_content_trait")
public class FileContentTrait extends HologramTrait {
private static final Configuration DEFAULT_CONFIG = new Configuration(
@@ -20,10 +22,6 @@ public class FileContentTrait extends HologramTrait {
private Configuration config;
public FileContentTrait() {
super("file_content");
}
@Override
public void onAttach() {
if (!(hologram.getData() instanceof TextHologramData)) {

View File

@@ -2,6 +2,7 @@ package de.oliver.fancyholograms.trait.builtin;
import de.oliver.fancyholograms.api.data.TextHologramData;
import de.oliver.fancyholograms.api.trait.HologramTrait;
import de.oliver.fancyholograms.api.trait.HologramTraitClass;
import org.jetbrains.annotations.ApiStatus;
import java.io.IOException;
@@ -10,6 +11,7 @@ import java.util.List;
import java.util.concurrent.TimeUnit;
@ApiStatus.Experimental
@HologramTraitClass(traitName = "multiple_pages_trait")
public class MultiplePagesTrait extends HologramTrait {
private static final Configuration DEFAULT_CONFIG = new Configuration(
@@ -24,7 +26,6 @@ public class MultiplePagesTrait extends HologramTrait {
private int currentPageIdx;
public MultiplePagesTrait() {
super("multiple_pages");
this.currentPageIdx = 0;
}