2020-08-18 14:18:12 +02:00
|
|
|
package net.minestom.server.extensions;
|
|
|
|
|
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-17 17:37:54 +01:00
|
|
|
import java.lang.ref.Reference;
|
|
|
|
import java.lang.ref.ReferenceQueue;
|
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.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")
|
2021-03-23 16:35:52 +01:00
|
|
|
private DiscoveredExtension origin;
|
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.
|
|
|
|
*/
|
2021-03-23 16:35:52 +01:00
|
|
|
protected final Set<WeakReference<IExtensionObserver>> observers = Collections.newSetFromMap(new ConcurrentHashMap<>());
|
|
|
|
protected final ReferenceQueue<IExtensionObserver> observerReferenceQueue = new ReferenceQueue<>();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* List of extensions that depend on this extension.
|
|
|
|
*/
|
|
|
|
protected final Set<String> dependents = new HashSet<>();
|
2021-02-03 20:47:01 +01:00
|
|
|
|
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
|
2021-03-23 16:35:52 +01:00
|
|
|
public DiscoveredExtension getOrigin() {
|
|
|
|
return origin;
|
2020-08-18 14:18:12 +02:00
|
|
|
}
|
|
|
|
|
2021-03-23 16:35:52 +01:00
|
|
|
/**
|
|
|
|
* Gets the logger for the extension
|
|
|
|
* @return The logger for the extension
|
|
|
|
*/
|
2020-10-25 10:41:51 +01:00
|
|
|
@NotNull
|
2021-03-24 13:48:37 +01:00
|
|
|
public Logger getLogger() {
|
2020-08-18 14:18:12 +02:00
|
|
|
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.
|
2021-03-23 16:35:52 +01:00
|
|
|
*
|
|
|
|
* @param observer The observer to add
|
2021-02-03 20:47:01 +01:00
|
|
|
*/
|
|
|
|
public void observe(IExtensionObserver observer) {
|
2021-02-17 17:37:54 +01:00
|
|
|
observers.add(new WeakReference<>(observer, observerReferenceQueue));
|
2021-02-03 20:47:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Calls some action on all valid observers of this extension
|
|
|
|
* @param action code to execute on each observer
|
|
|
|
*/
|
|
|
|
public void triggerChange(Consumer<IExtensionObserver> action) {
|
2021-03-23 16:35:52 +01:00
|
|
|
for (WeakReference<IExtensionObserver> weakObserver : observers) {
|
2021-02-03 20:47:01 +01:00
|
|
|
IExtensionObserver observer = weakObserver.get();
|
2021-03-23 16:35:52 +01:00
|
|
|
if (observer != null) {
|
2021-02-03 20:47:01 +01:00
|
|
|
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() {
|
2021-03-23 16:35:52 +01:00
|
|
|
return !getOrigin().hasFailedToLoadMixin() && getOrigin().getMissingCodeModifiers().isEmpty();
|
2021-02-04 19:11:43 +01:00
|
|
|
}
|
|
|
|
|
2021-02-17 17:37:54 +01:00
|
|
|
/**
|
|
|
|
* Removes all expired reference to observers
|
|
|
|
*
|
|
|
|
* @see #observers
|
|
|
|
*/
|
|
|
|
public void cleanupObservers() {
|
|
|
|
Reference<? extends IExtensionObserver> ref;
|
|
|
|
while((ref = observerReferenceQueue.poll()) != null) {
|
|
|
|
observers.remove(ref);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-23 16:35:52 +01:00
|
|
|
/**
|
|
|
|
* @return A modifiable list of dependents.
|
|
|
|
*/
|
|
|
|
public Set<String> getDependents() {
|
|
|
|
return dependents;
|
2020-09-12 08:56:01 +02:00
|
|
|
}
|
2020-08-18 14:18:12 +02:00
|
|
|
}
|