2020-08-18 14:18:12 +02:00
|
|
|
package net.minestom.server.extensions;
|
|
|
|
|
2021-02-03 20:47:01 +01:00
|
|
|
import net.minestom.server.event.handler.EventHandler;
|
2020-09-12 08:56:01 +02:00
|
|
|
import org.jetbrains.annotations.NotNull;
|
2020-08-18 14:18:12 +02:00
|
|
|
import org.slf4j.Logger;
|
|
|
|
|
2021-02-03 20:47:01 +01:00
|
|
|
import java.lang.ref.WeakReference;
|
2021-02-04 19:11:43 +01:00
|
|
|
import java.util.*;
|
2021-02-03 20:47:01 +01:00
|
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
|
|
import java.util.concurrent.ConcurrentSkipListSet;
|
|
|
|
import java.util.concurrent.CopyOnWriteArrayList;
|
|
|
|
import java.util.function.Consumer;
|
2020-09-12 08:56:01 +02:00
|
|
|
|
2020-08-18 14:18:12 +02:00
|
|
|
public abstract class Extension {
|
2020-10-25 10:41:51 +01:00
|
|
|
// Set by reflection
|
|
|
|
@SuppressWarnings("unused")
|
2020-09-12 08:56:01 +02:00
|
|
|
private ExtensionDescription description;
|
2020-10-25 10:41:51 +01:00
|
|
|
// Set by reflection
|
|
|
|
@SuppressWarnings("unused")
|
2020-08-18 14:18:12 +02:00
|
|
|
private Logger logger;
|
|
|
|
|
2021-02-03 20:47:01 +01:00
|
|
|
/**
|
|
|
|
* Observers that will be notified of events related to this extension.
|
2021-02-03 20:56:36 +01:00
|
|
|
* Kept as WeakReference because entities can be observers, but could become candidate to be garbage-collected while
|
2021-02-03 20:47:01 +01:00
|
|
|
* this extension holds a reference to it. A WeakReference makes sure this extension does not prevent the memory
|
|
|
|
* from being cleaned up.
|
|
|
|
*/
|
|
|
|
private Set<WeakReference<IExtensionObserver>> observers = Collections.newSetFromMap(new ConcurrentHashMap<>());
|
|
|
|
|
2020-08-18 14:18:12 +02:00
|
|
|
protected Extension() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public void preInitialize() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public abstract void initialize();
|
|
|
|
|
|
|
|
public void postInitialize() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public void preTerminate() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public abstract void terminate();
|
|
|
|
|
|
|
|
public void postTerminate() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-11-03 21:26:46 +01:00
|
|
|
/**
|
|
|
|
* Called after postTerminate when reloading an extension
|
|
|
|
*/
|
|
|
|
public void unload() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-10-25 10:41:51 +01:00
|
|
|
@NotNull
|
2020-09-12 08:56:01 +02:00
|
|
|
public ExtensionDescription getDescription() {
|
2020-08-18 14:18:12 +02:00
|
|
|
return description;
|
|
|
|
}
|
|
|
|
|
2020-10-25 10:41:51 +01:00
|
|
|
@NotNull
|
2020-08-18 14:18:12 +02:00
|
|
|
protected Logger getLogger() {
|
|
|
|
return logger;
|
|
|
|
}
|
2020-09-12 08:56:01 +02:00
|
|
|
|
2021-02-03 20:47:01 +01:00
|
|
|
/**
|
|
|
|
* Adds a new observer to this extension.
|
|
|
|
* Will be kept as a WeakReference.
|
|
|
|
* @param observer
|
|
|
|
*/
|
|
|
|
public void observe(IExtensionObserver observer) {
|
|
|
|
observers.add(new WeakReference<>(observer));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Calls some action on all valid observers of this extension
|
|
|
|
* @param action code to execute on each observer
|
|
|
|
*/
|
|
|
|
public void triggerChange(Consumer<IExtensionObserver> action) {
|
|
|
|
for(WeakReference<IExtensionObserver> weakObserver : observers) {
|
|
|
|
IExtensionObserver observer = weakObserver.get();
|
|
|
|
if(observer != null) {
|
|
|
|
action.accept(observer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-10-26 16:08:59 +01:00
|
|
|
|
2021-02-04 19:11:43 +01:00
|
|
|
/**
|
|
|
|
* If this extension registers code modifiers and/or mixins, are they loaded correctly?
|
|
|
|
*/
|
|
|
|
public boolean areCodeModifiersAllLoadedCorrectly() {
|
|
|
|
return !getDescription().failedToLoadMixin && getDescription().getMissingCodeModifiers().isEmpty();
|
|
|
|
}
|
|
|
|
|
2020-10-25 10:41:51 +01:00
|
|
|
public static class ExtensionDescription {
|
2020-09-12 08:56:01 +02:00
|
|
|
private final String name;
|
|
|
|
private final String version;
|
|
|
|
private final List<String> authors;
|
2020-11-03 21:26:46 +01:00
|
|
|
private final List<String> dependents = new ArrayList<>();
|
2021-02-04 19:11:43 +01:00
|
|
|
private final List<String> missingCodeModifiers = new LinkedList<>();
|
|
|
|
private final boolean failedToLoadMixin;
|
2020-11-03 21:26:46 +01:00
|
|
|
private final DiscoveredExtension origin;
|
2020-09-12 08:56:01 +02:00
|
|
|
|
2020-11-03 21:26:46 +01:00
|
|
|
ExtensionDescription(@NotNull String name, @NotNull String version, @NotNull List<String> authors, @NotNull DiscoveredExtension origin) {
|
2020-09-12 08:56:01 +02:00
|
|
|
this.name = name;
|
|
|
|
this.version = version;
|
2020-11-18 09:24:59 +01:00
|
|
|
this.authors = authors;
|
2020-11-03 21:26:46 +01:00
|
|
|
this.origin = origin;
|
2021-02-04 19:11:43 +01:00
|
|
|
failedToLoadMixin = origin.hasFailedToLoadMixin();
|
|
|
|
missingCodeModifiers.addAll(origin.getMissingCodeModifiers());
|
2020-09-12 08:56:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@NotNull
|
|
|
|
public String getName() {
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
|
|
|
@NotNull
|
|
|
|
public String getVersion() {
|
|
|
|
return version;
|
|
|
|
}
|
|
|
|
|
|
|
|
@NotNull
|
|
|
|
public List<String> getAuthors() {
|
|
|
|
return authors;
|
|
|
|
}
|
2020-11-03 21:26:46 +01:00
|
|
|
|
|
|
|
@NotNull
|
|
|
|
public List<String> getDependents() {
|
|
|
|
return dependents;
|
|
|
|
}
|
|
|
|
|
|
|
|
@NotNull
|
|
|
|
DiscoveredExtension getOrigin() {
|
|
|
|
return origin;
|
|
|
|
}
|
2021-02-04 19:11:43 +01:00
|
|
|
|
|
|
|
@NotNull
|
|
|
|
public List<String> getMissingCodeModifiers() {
|
|
|
|
return missingCodeModifiers;
|
|
|
|
}
|
|
|
|
|
|
|
|
@NotNull
|
|
|
|
public boolean hasFailedToLoadMixin() {
|
|
|
|
return failedToLoadMixin;
|
|
|
|
}
|
2020-09-12 08:56:01 +02:00
|
|
|
}
|
2020-08-18 14:18:12 +02:00
|
|
|
}
|