Skip to content

Commit f2346f4

Browse files
committed
Exposed a way to implement DSL from external
1 parent 34c88bd commit f2346f4

9 files changed

Lines changed: 162 additions & 6 deletions

File tree

api/src/main/java/fr/jamailun/ultimatespellsystem/api/UltimateSpellSystem.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import fr.jamailun.ultimatespellsystem.api.bind.SpellCostRegistry;
66
import fr.jamailun.ultimatespellsystem.api.bind.SpellsTriggerManager;
77
import fr.jamailun.ultimatespellsystem.api.entities.SummonsManager;
8+
import fr.jamailun.ultimatespellsystem.api.spells.ExternalExecutor;
89
import fr.jamailun.ultimatespellsystem.api.spells.SpellsManager;
910
import fr.jamailun.ultimatespellsystem.api.utils.ItemReader;
1011
import fr.jamailun.ultimatespellsystem.api.utils.Scheduler;
@@ -101,6 +102,15 @@ public static boolean isValid() {
101102
return plugin.getScheduler();
102103
}
103104

105+
106+
/**
107+
* Get the external executor. Used to evaluate any DSL expressions.
108+
* @return the non-null reference.
109+
*/
110+
public static @NotNull ExternalExecutor getExternalExecutor() {
111+
return plugin.getExternalExecutor();
112+
}
113+
104114
/**
105115
* Reload the configuration.
106116
*/

api/src/main/java/fr/jamailun/ultimatespellsystem/api/UltimateSpellSystemPlugin.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import fr.jamailun.ultimatespellsystem.api.bind.SpellCostRegistry;
66
import fr.jamailun.ultimatespellsystem.api.bind.SpellsTriggerManager;
77
import fr.jamailun.ultimatespellsystem.api.entities.SummonsManager;
8+
import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime;
9+
import fr.jamailun.ultimatespellsystem.api.spells.ExternalExecutor;
810
import fr.jamailun.ultimatespellsystem.api.spells.SpellsManager;
911
import fr.jamailun.ultimatespellsystem.api.utils.ItemReader;
1012
import fr.jamailun.ultimatespellsystem.api.utils.Scheduler;
@@ -64,6 +66,12 @@ public interface UltimateSpellSystemPlugin {
6466
*/
6567
@NotNull Scheduler getScheduler();
6668

69+
/**
70+
* Get the externa executor. Used to evaluate string expressions.
71+
* @return non-null instance.
72+
*/
73+
@NotNull ExternalExecutor getExternalExecutor();
74+
6775
/**
6876
* Reload the configuration.
6977
*/
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package fr.jamailun.ultimatespellsystem.api.spells;
2+
3+
import fr.jamailun.ultimatespellsystem.api.entities.SpellEntity;
4+
import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression;
5+
import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement;
6+
import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime;
7+
import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode;
8+
import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode;
9+
import org.bukkit.entity.LivingEntity;
10+
import org.jetbrains.annotations.Contract;
11+
import org.jetbrains.annotations.NotNull;
12+
import org.jetbrains.annotations.Nullable;
13+
import org.jetbrains.annotations.UnmodifiableView;
14+
15+
import java.util.List;
16+
17+
/**
18+
* This allows for external APIs to evaluate expressions.
19+
*/
20+
public interface ExternalExecutor {
21+
22+
/**
23+
* Create a new spell runtime instance.
24+
* @param caster spell entity to consider as "caster".
25+
* @return a new spell runtime.
26+
*/
27+
@Contract("_ -> new")
28+
@NotNull SpellRuntime generateRuntime(@NotNull SpellEntity caster);
29+
30+
/**
31+
* Create a new spell runtime instance.
32+
* @param caster bukkit entity to consider as "caster".
33+
* @return a new spell runtime.
34+
*/
35+
@Contract("_ -> new")
36+
@NotNull SpellRuntime generateRuntime(@NotNull LivingEntity caster);
37+
38+
/**
39+
* Evaluate an expression.
40+
* @param expression expression to evaluate
41+
* @param caster the spell-entity caster.
42+
* @return expression output.
43+
*/
44+
default @Nullable Object evaluateExpression(@NotNull RuntimeExpression expression, @NotNull SpellEntity caster) {
45+
return expression.evaluate( generateRuntime(caster) );
46+
}
47+
48+
/**
49+
* Evaluate an expression.
50+
* @param expression expression to evaluate
51+
* @param caster the Bukkit caster.
52+
* @return expression output.
53+
*/
54+
default @Nullable Object evaluateExpression(@NotNull RuntimeExpression expression, @NotNull LivingEntity caster) {
55+
return expression.evaluate( generateRuntime(caster) );
56+
}
57+
58+
/**
59+
* Implement DSL into a runnable statement.
60+
* @param dsl DSL to implement.
61+
* @return a new unmodifiable list of runnable statements.
62+
* @throws fr.jamailun.ultimatespellsystem.dsl.errors.UssException in case of issue.
63+
*/
64+
@NotNull @UnmodifiableView
65+
List<RuntimeStatement> handleImplementation(@NotNull List<StatementNode> dsl);
66+
67+
/**
68+
* Implement DSL into a runnable expression.
69+
* @param dsl DSL to implement.
70+
* @return a single DSL expression.
71+
* @throws fr.jamailun.ultimatespellsystem.dsl.errors.UssException in case of issue.
72+
*/
73+
@NotNull RuntimeExpression handleImplementation(@NotNull ExpressionNode dsl);
74+
75+
}

dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/UltimateSpellSystemDSL.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package fr.jamailun.ultimatespellsystem.dsl;
22

33
import fr.jamailun.ultimatespellsystem.dsl.metadata.rules.DefaultMetadataRules;
4+
import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode;
45
import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode;
56
import fr.jamailun.ultimatespellsystem.dsl.tokenization.*;
67
import org.jetbrains.annotations.NotNull;
@@ -33,7 +34,6 @@ private UltimateSpellSystemDSL() {}
3334
StatementNode node = StatementNode.parseNextStatement(tokens);
3435
statements.add(node);
3536
}
36-
3737
return statements;
3838
}
3939

@@ -65,4 +65,14 @@ private UltimateSpellSystemDSL() {}
6565
return parse(CharStream.from(file));
6666
}
6767

68+
/**
69+
* Parse any expression... Will stop at the first one !
70+
* @param string string to parse.
71+
* @return a non-null expression.
72+
*/
73+
public static @NotNull ExpressionNode parseExpression(@NotNull String string) {
74+
TokenStream tokens = Tokenizer.tokenize(CharStream.from(string));
75+
return ExpressionNode.readNextExpression(tokens);
76+
}
77+
6878
}

example-plugin/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
<dependencies>
1919
<dependency>
2020
<groupId>fr.jamailun.paper</groupId>
21-
<version>2.1.0</version>
21+
<version>2.1.1-SNAPSHOT</version>
2222
<artifactId>ultimate-spell-system-api</artifactId>
2323
<scope>provided</scope>
2424
</dependency>

plugin/src/main/java/fr/jamailun/ultimatespellsystem/UssMain.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import fr.jamailun.ultimatespellsystem.api.UltimateSpellSystemPlugin;
55
import fr.jamailun.ultimatespellsystem.api.bind.SpellCostRegistry;
66
import fr.jamailun.ultimatespellsystem.api.bind.SpellsTriggerManager;
7+
import fr.jamailun.ultimatespellsystem.api.spells.ExternalExecutor;
78
import fr.jamailun.ultimatespellsystem.api.utils.ItemReader;
89
import fr.jamailun.ultimatespellsystem.api.utils.Scheduler;
910
import fr.jamailun.ultimatespellsystem.plugin.animations.AnimationsManagerImpl;
@@ -15,6 +16,7 @@
1516
import fr.jamailun.ultimatespellsystem.plugin.listeners.*;
1617
import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions.SendAttributeNode;
1718
import fr.jamailun.ultimatespellsystem.plugin.spells.SpellsManagerImpl;
19+
import fr.jamailun.ultimatespellsystem.plugin.spells.external.ExternalExecutorImpl;
1820
import fr.jamailun.ultimatespellsystem.plugin.updater.UpdateCheck;
1921
import fr.jamailun.ultimatespellsystem.plugin.configuration.UssConfig;
2022
import fr.jamailun.ultimatespellsystem.extension.ExtensionLoader;
@@ -44,6 +46,7 @@ public final class UssMain extends JavaPlugin implements UltimateSpellSystemPlug
4446
@Getter private final Scheduler scheduler = new UssScheduler(this);
4547
@Getter private final ItemReader itemReader = new ItemReaderImpl();
4648
@Getter private final SpellsTriggerManager spellsTriggerManager = new SpellTriggerManagerImpl();
49+
@Getter private final ExternalExecutor externalExecutor = new ExternalExecutorImpl();
4750

4851
private UssConfig config;
4952

plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/SpellBuilderVisitor.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression;
1818
import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement;
1919
import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions.*;
20+
import lombok.Getter;
2021
import org.jetbrains.annotations.NotNull;
2122
import org.jetbrains.annotations.Nullable;
2223

@@ -32,7 +33,7 @@
3233
public class SpellBuilderVisitor implements StatementVisitor {
3334

3435
private final ExpressionQueue expressionQueue = new ExpressionQueue();
35-
private List<RuntimeStatement> currentQueue; // dynamic pointer toward the top of the queue stack.
36+
@Getter private List<RuntimeStatement> currentQueue; // dynamic pointer toward the top of the queue stack.
3637
private final List<RuntimeStatement> statementsAccumulator = new ArrayList<>();
3738
private final Deque<List<RuntimeStatement>> accumulatorsStack = new ArrayDeque<>();
3839

@@ -231,7 +232,7 @@ public void handleBreakContinue(@NotNull BreakContinueStatement statement) {
231232
add(new BreakContinueNode(statement.isContinue()));
232233
}
233234

234-
private RuntimeExpression convert(ExpressionNode expression) {
235+
public RuntimeExpression convert(ExpressionNode expression) {
235236
if(expression == null)
236237
return null;
237238
expression.visit(expressionQueue);

plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/SpellDefinition.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,7 @@ public SpellDefinition(@NotNull File file, @NotNull String name, @NotNull List<R
7979
public static @Nullable SpellDefinition loadFile(@NotNull String name, @NotNull File file) {
8080
try {
8181
List<StatementNode> dsl = UltimateSpellSystemDSL.parse(file);
82-
DslValidator.validateDsl(dsl);
83-
List<RuntimeStatement> steps = SpellBuilderVisitor.build(dsl);
82+
List<RuntimeStatement> steps = load(dsl);
8483
return new SpellDefinition(file, name, steps);
8584
} catch(Exception e) {
8685
UssLogger.logError("In "+file+" : " + e.getMessage());
@@ -91,6 +90,11 @@ public SpellDefinition(@NotNull File file, @NotNull String name, @NotNull List<R
9190
}
9291
}
9392

93+
public static @NotNull List<RuntimeStatement> load(@NotNull List<StatementNode> dsl) {
94+
DslValidator.validateDsl(dsl);
95+
return SpellBuilderVisitor.build(dsl);
96+
}
97+
9498
public static @NotNull String debugFile(@NotNull File file) {
9599
if(!file.exists())
96100
return "file["+file+"] doesn't exist.";
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package fr.jamailun.ultimatespellsystem.plugin.spells.external;
2+
3+
import fr.jamailun.ultimatespellsystem.api.entities.SpellEntity;
4+
import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression;
5+
import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement;
6+
import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime;
7+
import fr.jamailun.ultimatespellsystem.api.spells.ExternalExecutor;
8+
import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode;
9+
import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode;
10+
import fr.jamailun.ultimatespellsystem.plugin.runner.SpellRuntimeImpl;
11+
import fr.jamailun.ultimatespellsystem.plugin.runner.builder.SpellBuilderVisitor;
12+
import fr.jamailun.ultimatespellsystem.plugin.spells.SpellDefinition;
13+
import org.bukkit.entity.LivingEntity;
14+
import org.jetbrains.annotations.NotNull;
15+
import org.jetbrains.annotations.UnmodifiableView;
16+
17+
import java.util.Collections;
18+
import java.util.List;
19+
20+
/**
21+
* Implementation of a {@link ExternalExecutor}.
22+
*/
23+
public class ExternalExecutorImpl implements ExternalExecutor {
24+
25+
@Override
26+
public @NotNull SpellRuntime generateRuntime(@NotNull SpellEntity caster) {
27+
return new SpellRuntimeImpl(caster);
28+
}
29+
30+
@Override
31+
public @NotNull SpellRuntime generateRuntime(@NotNull LivingEntity caster) {
32+
return new SpellRuntimeImpl(caster);
33+
}
34+
35+
@Override
36+
public @NotNull @UnmodifiableView List<RuntimeStatement> handleImplementation(@NotNull List<StatementNode> dsl) {
37+
return Collections.unmodifiableList(SpellDefinition.load(dsl));
38+
}
39+
40+
@Override
41+
public @NotNull RuntimeExpression handleImplementation(@NotNull ExpressionNode dsl) {
42+
return new SpellBuilderVisitor().convert(dsl);
43+
}
44+
45+
}

0 commit comments

Comments
 (0)