Skip to content

Commit 7148bf2

Browse files
🍒 [2.7] Structure API Finalization (#5669) (#5981)
Structure API Finalization (#5669) Co-authored-by: Patrick Miller <[email protected]>
1 parent 49d5620 commit 7148bf2

File tree

10 files changed

+168
-189
lines changed

10 files changed

+168
-189
lines changed

src/main/java/ch/njol/skript/ScriptLoader.java

Lines changed: 84 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -516,67 +516,89 @@ private static CompletableFuture<ScriptInfo> loadScripts(List<Config> configs, O
516516
try {
517517
openCloseable.open();
518518

519-
scripts.stream()
520-
.flatMap(pair -> { // Flatten each entry down to a stream of Script-Structure pairs
521-
return pair.getSecond().stream()
522-
.map(structure -> new NonNullPair<>(pair, structure));
523-
})
524-
.sorted(Comparator.comparing(pair -> pair.getSecond().getPriority()))
525-
.forEach(pair -> {
526-
Script script = pair.getFirst().getFirst();
527-
Structure structure = pair.getSecond();
528-
529-
parser.setActive(script);
530-
parser.setCurrentStructure(structure);
531-
parser.setNode(structure.getEntryContainer().getSource());
532-
533-
try {
534-
if (!structure.preLoad())
535-
pair.getFirst().getSecond().remove(structure);
536-
} catch (Exception e) {
537-
//noinspection ThrowableNotThrown
538-
Skript.exception(e, "An error occurred while trying to load a Structure.");
519+
// build sorted list
520+
// this nest of pairs is terrible, but we need to keep the reference to the modifiable structures list
521+
List<NonNullPair<NonNullPair<Script, List<Structure>>, Structure>> pairs = scripts.stream()
522+
.flatMap(pair -> { // Flatten each entry down to a stream of Script-Structure pairs
523+
return pair.getSecond().stream()
524+
.map(structure -> new NonNullPair<>(pair, structure));
525+
})
526+
.sorted(Comparator.comparing(pair -> pair.getSecond().getPriority()))
527+
.collect(Collectors.toCollection(ArrayList::new));
528+
529+
// pre-loading
530+
pairs.removeIf(pair -> {
531+
Structure structure = pair.getSecond();
532+
533+
parser.setActive(pair.getFirst().getFirst());
534+
parser.setCurrentStructure(structure);
535+
parser.setNode(structure.getEntryContainer().getSource());
536+
537+
try {
538+
if (!structure.preLoad()) {
539539
pair.getFirst().getSecond().remove(structure);
540+
return true;
540541
}
541-
});
542-
542+
} catch (Exception e) {
543+
//noinspection ThrowableNotThrown
544+
Skript.exception(e, "An error occurred while trying to preLoad a Structure.");
545+
pair.getFirst().getSecond().remove(structure);
546+
return true;
547+
}
548+
return false;
549+
});
543550
parser.setInactive();
544551

545-
// TODO in the future, Structure#load should be split across multiple threads if parallel loading is enabled.
552+
// TODO in the future, Structure#load/Structure#postLoad should be split across multiple threads if parallel loading is enabled.
546553
// However, this is not possible right now as reworks in multiple areas will be needed.
547554
// For example, the "Commands" class still uses a static list for currentArguments that is cleared between loads.
548555
// Until these reworks happen, limiting main loading to asynchronous (not parallel) is the only choice we have.
549-
for (NonNullPair<Script, List<Structure>> pair : scripts) {
550-
parser.setActive(pair.getFirst());
551-
pair.getSecond().removeIf(structure -> {
552-
parser.setCurrentStructure(structure);
553-
parser.setNode(structure.getEntryContainer().getSource());
554-
try {
555-
return !structure.load();
556-
} catch (Exception e) {
557-
//noinspection ThrowableNotThrown
558-
Skript.exception(e, "An error occurred while trying to load a Structure.");
556+
557+
// loading
558+
pairs.removeIf(pair -> {
559+
Structure structure = pair.getSecond();
560+
561+
parser.setActive(pair.getFirst().getFirst());
562+
parser.setCurrentStructure(structure);
563+
parser.setNode(structure.getEntryContainer().getSource());
564+
565+
try {
566+
if (!structure.load()) {
567+
pair.getFirst().getSecond().remove(structure);
559568
return true;
560569
}
561-
});
562-
}
563-
570+
} catch (Exception e) {
571+
//noinspection ThrowableNotThrown
572+
Skript.exception(e, "An error occurred while trying to load a Structure.");
573+
pair.getFirst().getSecond().remove(structure);
574+
return true;
575+
}
576+
return false;
577+
});
564578
parser.setInactive();
565579

566-
for (NonNullPair<Script, List<Structure>> pair : scripts) {
567-
parser.setActive(pair.getFirst());
568-
pair.getSecond().removeIf(structure -> {
569-
parser.setCurrentStructure(structure);
570-
parser.setNode(structure.getEntryContainer().getSource());
571-
try {
572-
return !structure.postLoad();
573-
} catch (Exception e) {
574-
//noinspection ThrowableNotThrown
575-
Skript.exception(e, "An error occurred while trying to load a Structure.");
580+
// post-loading
581+
pairs.removeIf(pair -> {
582+
Structure structure = pair.getSecond();
583+
584+
parser.setActive(pair.getFirst().getFirst());
585+
parser.setCurrentStructure(structure);
586+
parser.setNode(structure.getEntryContainer().getSource());
587+
588+
try {
589+
if (!structure.postLoad()) {
590+
pair.getFirst().getSecond().remove(structure);
576591
return true;
577592
}
578-
});
579-
}
593+
} catch (Exception e) {
594+
//noinspection ThrowableNotThrown
595+
Skript.exception(e, "An error occurred while trying to postLoad a Structure.");
596+
pair.getFirst().getSecond().remove(structure);
597+
return true;
598+
}
599+
return false;
600+
});
601+
parser.setInactive();
580602

581603
return scriptInfo;
582604
} catch (Exception e) {
@@ -593,7 +615,7 @@ private static CompletableFuture<ScriptInfo> loadScripts(List<Config> configs, O
593615
/**
594616
* Creates a script and loads the provided config into it.
595617
* @param config The config to load into a script.
596-
* @return The script that was loaded.
618+
* @return A pair containing the script that was loaded and a modifiable version of the structures list.
597619
*/
598620
// Whenever you call this method, make sure to also call PreScriptLoadEvent
599621
private static NonNullPair<Script, List<Structure>> loadScript(Config config) {
@@ -1009,20 +1031,6 @@ public static FileFilter getDisabledScriptsFilter() {
10091031
* by new methods in this class.
10101032
*/
10111033

1012-
/**
1013-
* Reloads a single script.
1014-
* @param scriptFile The file representing the script to reload.
1015-
* @return Future of statistics of the newly loaded script.
1016-
* @deprecated Use {@link #reloadScript(Script, OpenCloseable)}.
1017-
*/
1018-
@Deprecated
1019-
public static CompletableFuture<ScriptInfo> reloadScript(File scriptFile, OpenCloseable openCloseable) {
1020-
Script script = getScript(scriptFile);
1021-
if (script == null)
1022-
return CompletableFuture.completedFuture(new ScriptInfo());
1023-
return reloadScript(script, openCloseable);
1024-
}
1025-
10261034
/**
10271035
* Unloads the provided script.
10281036
* @param scriptFile The file representing the script to unload.
@@ -1049,6 +1057,18 @@ private static ScriptInfo unloadScripts(File folder) {
10491057
return unloadScripts(getScripts(folder));
10501058
}
10511059

1060+
/**
1061+
* Reloads a single script.
1062+
* @param scriptFile The file representing the script to reload.
1063+
* @return Future of statistics of the newly loaded script.
1064+
* @deprecated Use {@link #reloadScript(Script, OpenCloseable)}.
1065+
*/
1066+
@Deprecated
1067+
public static CompletableFuture<ScriptInfo> reloadScript(File scriptFile, OpenCloseable openCloseable) {
1068+
unloadScript(scriptFile);
1069+
return loadScripts(scriptFile, openCloseable);
1070+
}
1071+
10521072
/**
10531073
* Reloads all scripts in the given folder and its subfolders.
10541074
* @param folder A folder.
@@ -1058,7 +1078,7 @@ private static ScriptInfo unloadScripts(File folder) {
10581078
@Deprecated
10591079
public static CompletableFuture<ScriptInfo> reloadScripts(File folder, OpenCloseable openCloseable) {
10601080
unloadScripts(folder);
1061-
return loadScripts(loadStructures(folder), openCloseable);
1081+
return loadScripts(folder, openCloseable);
10621082
}
10631083

10641084
/**

src/main/java/ch/njol/skript/structures/StructCommand.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ public class StructCommand extends Structure {
9696
.addEntry("description", "", true)
9797
.addEntry("prefix", null, true)
9898
.addEntry("permission", "", true)
99-
.addEntryData(new VariableStringEntryData("permission message", null, true, ScriptCommandEvent.class))
99+
.addEntryData(new VariableStringEntryData("permission message", null, true))
100100
.addEntryData(new KeyValueEntryData<List<String>>("aliases", new ArrayList<>(), true) {
101101
private final Pattern pattern = Pattern.compile("\\s*,\\s*/?");
102102

@@ -131,9 +131,9 @@ protected Integer getValue(String value) {
131131
}
132132
})
133133
.addEntryData(new LiteralEntryData<>("cooldown", null, true, Timespan.class))
134-
.addEntryData(new VariableStringEntryData("cooldown message", null, true, ScriptCommandEvent.class))
134+
.addEntryData(new VariableStringEntryData("cooldown message", null, true))
135135
.addEntry("cooldown bypass", null, true)
136-
.addEntryData(new VariableStringEntryData("cooldown storage", null, true, StringMode.VARIABLE_NAME, ScriptCommandEvent.class))
136+
.addEntryData(new VariableStringEntryData("cooldown storage", null, true, StringMode.VARIABLE_NAME))
137137
.addSection("trigger", false)
138138
.unexpectedEntryMessage(key ->
139139
"Unexpected entry '" + key + "'. Check that it's spelled correctly, and ensure that you have put all code into a trigger."
@@ -152,7 +152,6 @@ public boolean init(Literal<?>[] args, int matchedPattern, ParseResult parseResu
152152
}
153153

154154
@Override
155-
@SuppressWarnings("unchecked")
156155
public boolean load() {
157156
getParser().setCurrentEvent("command", ScriptCommandEvent.class);
158157

@@ -272,8 +271,8 @@ public boolean load() {
272271
if (permissionMessage != null && permission.isEmpty())
273272
Skript.warning("command /" + command + " has a permission message set, but not a permission");
274273

275-
List<String> aliases = (List<String>) entryContainer.get("aliases", true);
276-
int executableBy = (Integer) entryContainer.get("executable by", true);
274+
List<String> aliases = entryContainer.get("aliases", List.class,true);
275+
int executableBy = entryContainer.get("executable by", Integer.class, true);
277276

278277
Timespan cooldown = entryContainer.getOptional("cooldown", Timespan.class, false);
279278
VariableString cooldownMessage = entryContainer.getOptional("cooldown message", VariableString.class, false);

src/main/java/ch/njol/skript/structures/StructOptions.java

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.bukkit.event.Event;
3333
import org.jetbrains.annotations.Nullable;
3434
import org.skriptlang.skript.lang.entry.EntryContainer;
35+
import org.skriptlang.skript.lang.script.Script;
3536
import org.skriptlang.skript.lang.script.ScriptData;
3637
import org.skriptlang.skript.lang.structure.Structure;
3738

@@ -75,20 +76,16 @@ public class StructOptions extends Structure {
7576
public boolean init(Literal<?>[] args, int matchedPattern, ParseResult parseResult, EntryContainer entryContainer) {
7677
SectionNode node = entryContainer.getSource();
7778
node.convertToEntries(-1);
78-
79-
OptionsData optionsData = new OptionsData();
80-
loadOptions(node, "", optionsData.options);
81-
getParser().getCurrentScript().addData(optionsData);
82-
79+
loadOptions(node, "", getParser().getCurrentScript().getData(OptionsData.class, OptionsData::new).options);
8380
return true;
8481
}
8582

8683
private void loadOptions(SectionNode sectionNode, String prefix, Map<String, String> options) {
87-
for (Node n : sectionNode) {
88-
if (n instanceof EntryNode) {
89-
options.put(prefix + n.getKey(), ((EntryNode) n).getValue());
90-
} else if (n instanceof SectionNode) {
91-
loadOptions((SectionNode) n, prefix + n.getKey() + ".", options);
84+
for (Node node : sectionNode) {
85+
if (node instanceof EntryNode) {
86+
options.put(prefix + node.getKey(), ((EntryNode) node).getValue());
87+
} else if (node instanceof SectionNode) {
88+
loadOptions((SectionNode) node, prefix + node.getKey() + ".", options);
9289
} else {
9390
Skript.error("Invalid line in options");
9491
}
@@ -111,7 +108,7 @@ public Priority getPriority() {
111108
}
112109

113110
@Override
114-
public String toString(@Nullable Event e, boolean debug) {
111+
public String toString(@Nullable Event event, boolean debug) {
115112
return "options";
116113
}
117114

src/main/java/org/skriptlang/skript/lang/entry/EntryContainer.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,11 @@ public List<Node> getUnhandledNodes() {
8989
* @return The entry's value.
9090
* @throws RuntimeException If the entry's value is null, or if it is not of the expected type.
9191
*/
92-
public <T> T get(String key, Class<T> expectedType, boolean useDefaultValue) {
93-
T parsed = getOptional(key, expectedType, useDefaultValue);
94-
if (parsed == null)
92+
public <E, R extends E> R get(String key, Class<E> expectedType, boolean useDefaultValue) {
93+
R value = getOptional(key, expectedType, useDefaultValue);
94+
if (value == null)
9595
throw new RuntimeException("Null value for asserted non-null value");
96-
return parsed;
96+
return value;
9797
}
9898

9999
/**
@@ -124,13 +124,13 @@ public Object get(String key, boolean useDefaultValue) {
124124
*/
125125
@Nullable
126126
@SuppressWarnings("unchecked")
127-
public <T> T getOptional(String key, Class<T> expectedType, boolean useDefaultValue) {
127+
public <E, R extends E> R getOptional(String key, Class<E> expectedType, boolean useDefaultValue) {
128128
Object parsed = getOptional(key, useDefaultValue);
129129
if (parsed == null)
130130
return null;
131131
if (!expectedType.isInstance(parsed))
132132
throw new RuntimeException("Expected entry with key '" + key + "' to be '" + expectedType + "', but got '" + parsed.getClass() + "'");
133-
return (T) parsed;
133+
return (R) parsed;
134134
}
135135

136136
/**

0 commit comments

Comments
 (0)