Start using components (PR to dev) #53
11 changed files with 246 additions and 37 deletions
|
@ -1,13 +1,13 @@
|
|||
<component name="libraryTable">
|
||||
<library name="Maven: com.github.TBMCPlugins.ButtonCore:Towny:master-v1.0-g8d3b6b6-296">
|
||||
<library name="Maven: com.github.TBMCPlugins.ButtonCore:Towny:master-248b0d8d0a-1">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/github/TBMCPlugins/ButtonCore/Towny/master-v1.0-g8d3b6b6-296/Towny-master-v1.0-g8d3b6b6-296.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/github/TBMCPlugins/ButtonCore/Towny/master-248b0d8d0a-1/Towny-master-248b0d8d0a-1.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/github/TBMCPlugins/ButtonCore/Towny/master-v1.0-g8d3b6b6-296/Towny-master-v1.0-g8d3b6b6-296-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/github/TBMCPlugins/ButtonCore/Towny/master-248b0d8d0a-1/Towny-master-248b0d8d0a-1-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/github/TBMCPlugins/ButtonCore/Towny/master-v1.0-g8d3b6b6-296/Towny-master-v1.0-g8d3b6b6-296-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/github/TBMCPlugins/ButtonCore/Towny/master-248b0d8d0a-1/Towny-master-248b0d8d0a-1-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
|
@ -1,13 +1,13 @@
|
|||
<component name="libraryTable">
|
||||
<library name="Maven: com.github.milkbowl:VaultAPI:master-c8cb88f27a-1">
|
||||
<library name="Maven: com.github.milkbowl:VaultAPI:master-431c5273c2-1">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/github/milkbowl/VaultAPI/master-c8cb88f27a-1/VaultAPI-master-c8cb88f27a-1.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/github/milkbowl/VaultAPI/master-431c5273c2-1/VaultAPI-master-431c5273c2-1.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/github/milkbowl/VaultAPI/master-c8cb88f27a-1/VaultAPI-master-c8cb88f27a-1-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/github/milkbowl/VaultAPI/master-431c5273c2-1/VaultAPI-master-431c5273c2-1-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/github/milkbowl/VaultAPI/master-c8cb88f27a-1/VaultAPI-master-c8cb88f27a-1-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/github/milkbowl/VaultAPI/master-431c5273c2-1/VaultAPI-master-431c5273c2-1-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
|
@ -1,13 +1,13 @@
|
|||
<component name="libraryTable">
|
||||
<library name="Maven: org.bukkit:bukkit:1.13.1-R0.1-SNAPSHOT">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bukkit/bukkit/1.13.1-R0.1-SNAPSHOT/bukkit-1.13.1-R0.1-20181003.105254-89.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bukkit/bukkit/1.13.1-R0.1-SNAPSHOT/bukkit-1.13.1-R0.1-20181022.190036-99.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bukkit/bukkit/1.13.1-R0.1-SNAPSHOT/bukkit-1.13.1-R0.1-20181003.105254-89-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bukkit/bukkit/1.13.1-R0.1-SNAPSHOT/bukkit-1.13.1-R0.1-20181022.190036-99-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bukkit/bukkit/1.13.1-R0.1-SNAPSHOT/bukkit-1.13.1-R0.1-20181003.105254-89-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bukkit/bukkit/1.13.1-R0.1-SNAPSHOT/bukkit-1.13.1-R0.1-20181022.190036-99-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
|
@ -1,13 +1,13 @@
|
|||
<component name="libraryTable">
|
||||
<library name="Maven: org.spigotmc:spigot-api:1.12.2-R0.1-SNAPSHOT">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/spigotmc/spigot-api/1.12.2-R0.1-SNAPSHOT/spigot-api-1.12.2-R0.1-20180712.012057-156.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/spigotmc/spigot-api/1.12.2-R0.1-SNAPSHOT/spigot-api-1.12.2-R0.1-SNAPSHOT.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/spigotmc/spigot-api/1.12.2-R0.1-SNAPSHOT/spigot-api-1.12.2-R0.1-20180712.012057-156-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/spigotmc/spigot-api/1.12.2-R0.1-SNAPSHOT/spigot-api-1.12.2-R0.1-SNAPSHOT-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/spigotmc/spigot-api/1.12.2-R0.1-SNAPSHOT/spigot-api-1.12.2-R0.1-20180712.012057-156-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/spigotmc/spigot-api/1.12.2-R0.1-SNAPSHOT/spigot-api-1.12.2-R0.1-SNAPSHOT-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
|
@ -12,6 +12,7 @@
|
|||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="ButtonCore (1) (com.github.TBMCPlugins.ButtonCore)" />
|
||||
<orderEntry type="module" module-name="ButtonCore (1) (com.github.TBMCPlugins.ButtonCore)" />
|
||||
<orderEntry type="library" name="Maven: org.reflections:reflections:0.9.10" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.google.code.findbugs:annotations:2.0.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.javassist:javassist:3.20.0-GA" level="project" />
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package buttondevteam.core;
|
||||
|
||||
import buttondevteam.lib.chat.CommandClass;
|
||||
import buttondevteam.lib.chat.TBMCCommandBase;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
@CommandClass(modOnly = true)
|
||||
public class ComponentCommand extends TBMCCommandBase {
|
||||
@Override
|
||||
public boolean OnCommand(CommandSender sender, String alias, String[] args) {
|
||||
if (args.length < 2)
|
||||
return false;
|
||||
switch (args[0]) {
|
||||
case "enable":
|
||||
break;
|
||||
case "disable":
|
||||
break;
|
||||
case "list":
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] GetHelpText(String alias) {
|
||||
return new String[0];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package buttondevteam.core;
|
||||
|
||||
import buttondevteam.lib.architecture.Component;
|
||||
import buttondevteam.lib.architecture.exceptions.UnregisteredComponentException;
|
||||
|
||||
public final class ComponentManager {
|
||||
private ComponentManager() {}
|
||||
|
||||
/**
|
||||
* Enables components based on a configuration
|
||||
*/
|
||||
public static void enableComponents() {
|
||||
//Component.getComponents().values().stream().filter(c->cs.getConfigurationSection(c.getClass().getSimpleName()).getBoolean("enabled")).forEach(c-> {
|
||||
Component.getComponents().values().stream().filter(c -> c.shouldBeEnabled().get()).forEach(c -> {
|
||||
try {
|
||||
Component.setComponentEnabled(c, true);
|
||||
} catch (UnregisteredComponentException ignored) { //This *should* never happen
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables all components that are enabled
|
||||
*/
|
||||
public static void disableComponents() {
|
||||
Component.getComponents().values().stream().filter(Component::isEnabled).forEach(c -> {
|
||||
try {
|
||||
Component.setComponentEnabled(c, false);
|
||||
} catch (UnregisteredComponentException ignored) { //This *should* never happen
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -40,6 +40,7 @@ public class MainPlugin extends JavaPlugin {
|
|||
setupPermissions();
|
||||
Test = getConfig().getBoolean("test", true);
|
||||
saveConfig();
|
||||
ComponentManager.enableComponents();
|
||||
TBMCCoreAPI.RegisterEventsForExceptions(new PlayerListener(), this);
|
||||
TBMCCoreAPI.RegisterUserClass(TBMCPlayerBase.class);
|
||||
TBMCChatAPI.RegisterChatChannel(Channel.GlobalChat = new Channel("§fOOC§f", Color.White, "ooc", null));
|
||||
|
@ -67,6 +68,7 @@ public class MainPlugin extends JavaPlugin {
|
|||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
ComponentManager.disableComponents();
|
||||
logger.info("Saving player data...");
|
||||
TBMCPlayerBase.savePlayers();
|
||||
logger.info("Player data saved.");
|
||||
|
|
|
@ -1,17 +1,75 @@
|
|||
package buttondevteam.lib.architecture;
|
||||
|
||||
import buttondevteam.lib.TBMCCoreAPI;
|
||||
import buttondevteam.lib.architecture.exceptions.UnregisteredComponentException;
|
||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||
import buttondevteam.lib.chat.TBMCCommandBase;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.experimental.var;
|
||||
import lombok.val;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Configuration is based on class name
|
||||
*/
|
||||
public abstract class Component {
|
||||
private static HashMap<Class<? extends Component>, Component> components;
|
||||
private static HashMap<Class<? extends Component>, Component> components = new HashMap<>();
|
||||
|
||||
@Getter
|
||||
private boolean enabled = false;
|
||||
@Getter(value = AccessLevel.PROTECTED)
|
||||
@NonNull
|
||||
private JavaPlugin plugin;
|
||||
@NonNull
|
||||
private ConfigurationSection config;
|
||||
|
||||
public ConfigData<Boolean> shouldBeEnabled() {
|
||||
return getData("enabled", true);
|
||||
}
|
||||
|
||||
private HashMap<String, ConfigData<?>> datamap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* This method overload should only be used with primitves or String.
|
||||
*
|
||||
* @param path The path in config to use
|
||||
* @param def The value to use by default
|
||||
* @param <T> The type of this variable (only use primitives or String)
|
||||
* @return The data object that can be used to get or set the value
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T> ConfigData<T> getData(String path, T def) {
|
||||
ConfigData<?> data = datamap.get(path);
|
||||
if (data == null) datamap.put(path, data = new ConfigData<>(config, path, def));
|
||||
return (ConfigData<T>) data;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method overload may be used with any class.
|
||||
*
|
||||
* @param path The path in config to use
|
||||
* @param def The value to use by default
|
||||
* @param getter A function that converts a primitive representation to the correct value
|
||||
* @param setter A function that converts a value to a primitive representation
|
||||
* @param <T> The type of this variable (can be any class)
|
||||
* @return The data object that can be used to get or set the value
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T> ConfigData<T> getData(String path, T def, Function<Object, T> getter, Function<T, Object> setter) {
|
||||
ConfigData<?> data = datamap.get(path);
|
||||
if (data == null) datamap.put(path, data = new ConfigData<>(config, path, def, getter, setter));
|
||||
return (ConfigData<T>) data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a component checking it's dependencies and calling {@link #register(JavaPlugin)}.<br>
|
||||
|
@ -20,18 +78,7 @@ public abstract class Component {
|
|||
* @param component The component to register
|
||||
*/
|
||||
public static void registerComponent(JavaPlugin plugin, Component component) {
|
||||
val metaAnn = component.getClass().getAnnotation(ComponentMetadata.class);
|
||||
if (metaAnn != null) {
|
||||
Class<? extends Component>[] dependencies = metaAnn.depends();
|
||||
for (val dep : dependencies) {
|
||||
if (!components.containsKey(dep)) {
|
||||
plugin.getLogger().warning("Failed to register component " + component.getClassName() + " as a required dependency is missing/disabled: " + dep.getSimpleName());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
component.register(plugin);
|
||||
components.put(component.getClass(), component);
|
||||
registerUnregisterComponent(plugin, component, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -44,27 +91,56 @@ public abstract class Component {
|
|||
val component = components.get(componentClass);
|
||||
if (component == null)
|
||||
return; //Failed to load
|
||||
val metaAnn = componentClass.getAnnotation(ComponentMetadata.class);
|
||||
registerUnregisterComponent(plugin, component, false);
|
||||
}
|
||||
|
||||
public static void registerUnregisterComponent(JavaPlugin plugin, Component component, boolean register) {
|
||||
val metaAnn = component.getClass().getAnnotation(ComponentMetadata.class);
|
||||
if (metaAnn != null) {
|
||||
Class<? extends Component>[] dependencies = metaAnn.depends();
|
||||
for (val dep : dependencies) {
|
||||
if (!components.containsKey(dep)) {
|
||||
plugin.getLogger().warning("Failed to unregister component " + component.getClassName() + " as a required dependency is missing/disabled: " + dep.getSimpleName());
|
||||
plugin.getLogger().warning("Failed to " + (register ? "" : "un") + "register component " + component.getClassName() + " as a required dependency is missing/disabled: " + dep.getSimpleName());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
component.unregister(plugin);
|
||||
components.remove(componentClass);
|
||||
if (register) {
|
||||
component.plugin = plugin;
|
||||
var compconf = plugin.getConfig().getConfigurationSection("components");
|
||||
if (compconf == null) compconf = plugin.getConfig().createSection("components");
|
||||
component.config = compconf.getConfigurationSection(component.getClassName());
|
||||
if (component.config == null) component.config = compconf.createSection(component.getClassName());
|
||||
component.register(plugin);
|
||||
components.put(component.getClass(), component);
|
||||
} else {
|
||||
component.unregister(plugin);
|
||||
components.remove(component.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used to send a warning if there are registered components on shutdown.<br>
|
||||
* Registers a component checking it's dependencies and calling {@link #register(JavaPlugin)}.<br>
|
||||
* Make sure to register the dependencies first.
|
||||
*
|
||||
* @return If there are any registered components
|
||||
* @param component The component to register
|
||||
*/
|
||||
public static boolean haveRegisteredComponents() {
|
||||
return components.size() > 0;
|
||||
public static void setComponentEnabled(Component component, boolean enabled) throws UnregisteredComponentException {
|
||||
if (!components.containsKey(component.getClass()))
|
||||
throw new UnregisteredComponentException(component);
|
||||
if (component.enabled = enabled)
|
||||
component.enable();
|
||||
else
|
||||
component.disable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currently registered components<br>
|
||||
*
|
||||
* @return The currently registered components
|
||||
*/
|
||||
public static Map<Class<? extends Component>, Component> getComponents() {
|
||||
return Collections.unmodifiableMap(components);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -73,7 +149,7 @@ public abstract class Component {
|
|||
*
|
||||
* @param plugin Plugin class called to register commands and listeners
|
||||
*/
|
||||
public abstract void register(JavaPlugin plugin);
|
||||
protected abstract void register(JavaPlugin plugin);
|
||||
|
||||
/**
|
||||
* Unregisters the module, when called by the JavaPlugin class. Do
|
||||
|
@ -81,7 +157,21 @@ public abstract class Component {
|
|||
*
|
||||
* @param plugin Plugin class called to register commands and listeners
|
||||
*/
|
||||
public abstract void unregister(JavaPlugin plugin);
|
||||
protected abstract void unregister(JavaPlugin plugin);
|
||||
|
||||
/**
|
||||
* Enables the module, when called by the JavaPlugin class. Call
|
||||
* registerCommand() and registerListener() within this method.<br>
|
||||
* To access the plugin, use {@link #getPlugin()}.
|
||||
*/
|
||||
protected abstract void enable();
|
||||
|
||||
/**
|
||||
* Disables the module, when called by the JavaPlugin class. Do
|
||||
* any cleanups needed within this method.
|
||||
* To access the plugin, use {@link #getPlugin()}.
|
||||
*/
|
||||
protected abstract void disable();
|
||||
|
||||
/**
|
||||
* Registers a TBMCCommand to the plugin. Make sure to add it to plugin.yml and use {@link buttondevteam.lib.chat.CommandClass}.
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
package buttondevteam.lib.architecture;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Use the getter/setter constructor if {@link T} isn't a primitive type or String.
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ConfigData<T> { //TODO: Save after a while
|
||||
private final ConfigurationSection config;
|
||||
private final String path;
|
||||
private final T def;
|
||||
/**
|
||||
* The parameter is of a primitive type as returned by {@link YamlConfiguration#get(String)}
|
||||
*/
|
||||
private Function<Object, T> getter;
|
||||
/**
|
||||
* The result should be a primitive type or string that can be retrieved correctly later
|
||||
*/
|
||||
private Function<T, Object> setter;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public T get() {
|
||||
Object val = config.get(path, def);
|
||||
if (getter != null)
|
||||
return getter.apply(val);
|
||||
return (T) val;
|
||||
}
|
||||
|
||||
public void set(T value) {
|
||||
Object val;
|
||||
if (setter != null)
|
||||
val = setter.apply(value);
|
||||
else val = value;
|
||||
config.set(path, val);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package buttondevteam.lib.architecture.exceptions;
|
||||
|
||||
import buttondevteam.lib.architecture.Component;
|
||||
|
||||
public class UnregisteredComponentException extends Throwable {
|
||||
|
||||
public UnregisteredComponentException(Component component) {
|
||||
super("The component '" + component.getClass().getSimpleName() + "' isn't registered!");
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue