Implemented config save and reload
Always caching config value if it hasn't been cached
This commit is contained in:
parent
7289385a33
commit
25b9caa903
8 changed files with 77 additions and 20 deletions
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" version="4">
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
||||
<output url="file://$MODULE_DIR$/target/classes" />
|
||||
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package buttondevteam.core;
|
||||
|
||||
import buttondevteam.lib.TBMCCoreAPI;
|
||||
import buttondevteam.lib.architecture.ButtonPlugin;
|
||||
import buttondevteam.lib.architecture.Component;
|
||||
import buttondevteam.lib.chat.Command2;
|
||||
import buttondevteam.lib.chat.Command2.Subcommand;
|
||||
|
@ -24,7 +25,10 @@ public class ComponentCommand extends ICommand2MC {
|
|||
|
||||
@Subcommand
|
||||
public boolean enable(CommandSender sender, Plugin plugin, String component) {
|
||||
plugin.reloadConfig(); //Reload config so the new config values are read - All changes are saved to disk on disable
|
||||
if (plugin instanceof ButtonPlugin)
|
||||
((ButtonPlugin) plugin).justReload();
|
||||
else
|
||||
plugin.reloadConfig(); //Reload config so the new config values are read - All changes are saved to disk on disable
|
||||
return enable_disable(sender, plugin, component, true);
|
||||
}
|
||||
|
||||
|
|
|
@ -34,9 +34,10 @@ public final class ComponentManager {
|
|||
/**
|
||||
* Unregister all components of a plugin that are enabled - called on {@link ButtonPlugin} disable
|
||||
*/
|
||||
public static void unregComponents(ButtonPlugin plugin) {
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends ButtonPlugin> void unregComponents(T plugin) {
|
||||
while (!plugin.getComponentStack().empty()) //Unregister in reverse order
|
||||
Component.unregisterComponent(plugin, plugin.getComponentStack().pop()); //Components are pushed on register
|
||||
Component.unregisterComponent(plugin, (Component<T>) plugin.getComponentStack().pop()); //Components are pushed on register
|
||||
componentsEnabled = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package buttondevteam.core;
|
||||
|
||||
import buttondevteam.lib.chat.Command2;
|
||||
import buttondevteam.lib.chat.CommandClass;
|
||||
import buttondevteam.lib.chat.ICommand2MC;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
@CommandClass
|
||||
public class ThorpeCommand extends ICommand2MC {
|
||||
@Command2.Subcommand //TODO: Main permissions (groups) like 'mod'
|
||||
public void reload(CommandSender sender) {
|
||||
MainPlugin.Instance.reloadConfig();
|
||||
}
|
||||
}
|
|
@ -20,10 +20,10 @@ public abstract class ButtonPlugin extends JavaPlugin {
|
|||
@Getter(AccessLevel.PROTECTED)
|
||||
private IHaveConfig data; //TODO
|
||||
/**
|
||||
* Used to unregister components in the right order
|
||||
* Used to unregister components in the right order - and to reload configs
|
||||
*/
|
||||
@Getter
|
||||
private Stack<Component> componentStack = new Stack<>();
|
||||
private Stack<Component<?>> componentStack = new Stack<>();
|
||||
|
||||
protected abstract void pluginEnable();
|
||||
|
||||
|
@ -40,9 +40,7 @@ public abstract class ButtonPlugin extends JavaPlugin {
|
|||
|
||||
@Override
|
||||
public final void onEnable() {
|
||||
var section = super.getConfig().getConfigurationSection("global");
|
||||
if (section == null) section = super.getConfig().createSection("global");
|
||||
iConfig = new IHaveConfig(section, this::saveConfig);
|
||||
loadConfig();
|
||||
try {
|
||||
pluginEnable();
|
||||
} catch (Exception e) {
|
||||
|
@ -50,6 +48,12 @@ public abstract class ButtonPlugin extends JavaPlugin {
|
|||
}
|
||||
}
|
||||
|
||||
private void loadConfig() {
|
||||
var section = super.getConfig().getConfigurationSection("global");
|
||||
if (section == null) section = super.getConfig().createSection("global");
|
||||
iConfig = new IHaveConfig(section, this::saveConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onDisable() {
|
||||
try {
|
||||
|
@ -63,4 +67,19 @@ public abstract class ButtonPlugin extends JavaPlugin {
|
|||
TBMCCoreAPI.SendException("Error while disabling plugin " + getName() + "!", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reloadConfig() {
|
||||
justReload();
|
||||
loadConfig();
|
||||
componentStack.forEach(c -> Component.updateConfig(this, c));
|
||||
}
|
||||
|
||||
public void justReload() {
|
||||
if (ConfigData.saveNow(getConfig())) {
|
||||
getLogger().warning("Saved pending configuration changes to the file, didn't reload (try again).");
|
||||
return;
|
||||
}
|
||||
super.reloadConfig();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -140,7 +140,7 @@ public abstract class Component<TP extends JavaPlugin> {
|
|||
}
|
||||
}
|
||||
|
||||
private static void updateConfig(JavaPlugin plugin, Component component) {
|
||||
public static void updateConfig(JavaPlugin plugin, Component component) {
|
||||
if (plugin.getConfig() != null) { //Production
|
||||
var compconf = plugin.getConfig().getConfigurationSection("components");
|
||||
if (compconf == null) compconf = plugin.getConfig().createSection("components");
|
||||
|
@ -237,10 +237,10 @@ public abstract class Component<TP extends JavaPlugin> {
|
|||
var cs=c.getConfigurationSection(key);
|
||||
if(cs==null) cs=c.createSection(key);
|
||||
val res = cs.getValues(false).entrySet().stream().filter(e -> e.getValue() instanceof ConfigurationSection)
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, kv -> new IHaveConfig((ConfigurationSection) kv.getValue())));
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, kv -> new IHaveConfig((ConfigurationSection) kv.getValue(), getPlugin()::saveConfig)));
|
||||
if (res.size() == 0) {
|
||||
for (val entry : defaultProvider.entrySet()) {
|
||||
val conf = new IHaveConfig(cs.createSection(entry.getKey()));
|
||||
val conf = new IHaveConfig(cs.createSection(entry.getKey()), getPlugin()::saveConfig);
|
||||
entry.getValue().accept(conf);
|
||||
res.put(entry.getKey(), conf);
|
||||
}
|
||||
|
|
|
@ -2,12 +2,12 @@ package buttondevteam.lib.architecture;
|
|||
|
||||
import buttondevteam.core.MainPlugin;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.Configuration;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
|
@ -23,7 +23,7 @@ import java.util.function.Function;
|
|||
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
|
||||
//@AllArgsConstructor(access = AccessLevel.PACKAGE)
|
||||
public class ConfigData<T> {
|
||||
private static final HashMap<Configuration, BukkitTask> saveTasks= new HashMap<>();
|
||||
private static final HashMap<Configuration, SaveTask> saveTasks = new HashMap<>();
|
||||
/**
|
||||
* May be null for testing
|
||||
*/
|
||||
|
@ -45,8 +45,12 @@ public class ConfigData<T> {
|
|||
* The config value should not change outside this instance
|
||||
*/
|
||||
private T value;
|
||||
/**
|
||||
* Whether the default value is saved in the yaml
|
||||
*/
|
||||
private boolean saved = false;
|
||||
|
||||
//This constructor is needed because it sets the getter and setter
|
||||
public ConfigData(ConfigurationSection config, String path, T def, Object primitiveDef, Function<Object, T> getter, Function<T, Object> setter, Runnable saveAction) {
|
||||
this.config = config;
|
||||
this.path = path;
|
||||
|
@ -88,9 +92,9 @@ public class ConfigData<T> {
|
|||
else if (def instanceof Double)
|
||||
val = ((Number) val).doubleValue();
|
||||
}
|
||||
if (val instanceof List && def.getClass().isArray())
|
||||
if (val instanceof List && def != null && def.getClass().isArray())
|
||||
val = ((List<T>) val).toArray((T[]) Array.newInstance(def.getClass().getComponentType(), 0));
|
||||
return (T) val;
|
||||
return value = (T) val; //Always cache, if not cached yet
|
||||
}
|
||||
|
||||
public void set(T value) {
|
||||
|
@ -102,15 +106,32 @@ public class ConfigData<T> {
|
|||
config.set(path, val);
|
||||
if(!saveTasks.containsKey(config.getRoot())) {
|
||||
synchronized (saveTasks) {
|
||||
saveTasks.put(config.getRoot(), Bukkit.getScheduler().runTaskLaterAsynchronously(MainPlugin.Instance, () -> {
|
||||
saveTasks.put(config.getRoot(), new SaveTask(Bukkit.getScheduler().runTaskLaterAsynchronously(MainPlugin.Instance, () -> {
|
||||
synchronized (saveTasks) {
|
||||
saveTasks.remove(config.getRoot());
|
||||
saveAction.run();
|
||||
}
|
||||
}, 100));
|
||||
}, 100), saveAction));
|
||||
}
|
||||
}
|
||||
}
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
private static class SaveTask {
|
||||
BukkitTask task;
|
||||
Runnable saveAction;
|
||||
}
|
||||
|
||||
public static boolean saveNow(Configuration config) {
|
||||
SaveTask st = saveTasks.get(config);
|
||||
if (st != null) {
|
||||
st.task.cancel();
|
||||
saveTasks.remove(config);
|
||||
st.saveAction.run();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.21" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.21" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.21" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.spigotmc:spigot-api:1.12.2-R0.1-SNAPSHOT" level="project" />
|
||||
<orderEntry type="library" name="Maven: commons-lang:commons-lang:2.6" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.googlecode.json-simple:json-simple:1.1.1" level="project" />
|
||||
|
|
Loading…
Reference in a new issue