|
3 | 3 | import ch.njol.skript.Skript;
|
4 | 4 | import ch.njol.skript.classes.Changer.ChangeMode;
|
5 | 5 | import ch.njol.skript.classes.ClassInfo;
|
6 |
| -import ch.njol.skript.classes.Parser; |
7 |
| -import ch.njol.skript.config.EntryNode; |
8 | 6 | import ch.njol.skript.config.Node;
|
9 | 7 | import ch.njol.skript.doc.Description;
|
10 | 8 | import ch.njol.skript.doc.Examples;
|
|
14 | 12 | import ch.njol.skript.lang.Expression;
|
15 | 13 | import ch.njol.skript.lang.ExpressionType;
|
16 | 14 | import ch.njol.skript.lang.Literal;
|
17 |
| -import ch.njol.skript.lang.ParseContext; |
18 | 15 | import ch.njol.skript.lang.SkriptParser.ParseResult;
|
| 16 | +import ch.njol.skript.lang.util.common.AnyValued; |
19 | 17 | import ch.njol.skript.registrations.Feature;
|
20 | 18 | import ch.njol.util.Kleenean;
|
21 |
| -import ch.njol.util.coll.CollectionUtils; |
22 | 19 | import org.bukkit.event.Event;
|
23 | 20 | import org.jetbrains.annotations.NotNull;
|
24 | 21 | import org.jetbrains.annotations.Nullable;
|
25 | 22 |
|
26 | 23 | import java.lang.reflect.Array;
|
27 | 24 |
|
28 |
| -@Name("Value (Experimental)") |
| 25 | +@Name("Value") |
29 | 26 | @Description({
|
30 |
| - "Returns the value of a node in a loaded config.", |
| 27 | + "Returns the value of something that has a value, e.g. a node in a config.", |
31 | 28 | "The value is automatically converted to the specified type (e.g. text, number) where possible."
|
32 | 29 | })
|
33 | 30 | @Examples({
|
|
44 | 41 | # timespan value of {_node} = 12 hours (duration)""",
|
45 | 42 |
|
46 | 43 | })
|
47 |
| -@Since("2.10") |
48 |
| -public class ExprNodeValue extends SimplePropertyExpression<Node, Object> { |
| 44 | +@Since("2.10 (Nodes), INSERT VERSION (Any)") |
| 45 | +public class ExprValue extends SimplePropertyExpression<Object, Object> { |
49 | 46 |
|
50 | 47 | static {
|
51 |
| - Skript.registerExpression(ExprNodeValue.class, Object.class, ExpressionType.PROPERTY, |
52 |
| - "[the] %*classinfo% value [at] %string% (from|in) %node%", |
53 |
| - "[the] %*classinfo% value of %node%", |
54 |
| - "[the] %*classinfo% values of %nodes%", |
55 |
| - "%node%'s %*classinfo% value", |
56 |
| - "%nodes%'[s] %*classinfo% values" |
| 48 | + Skript.registerExpression(ExprValue.class, Object.class, ExpressionType.PROPERTY, |
| 49 | + "[the] %*classinfo% value [at] %string% (from|in) %node%", |
| 50 | + "[the] %*classinfo% value of %valued%", |
| 51 | + "[the] %*classinfo% values of %valueds%", |
| 52 | + "%valued%'s %*classinfo% value", |
| 53 | + "%valueds%'[s] %*classinfo% values" |
57 | 54 | );
|
58 | 55 | }
|
59 | 56 |
|
60 | 57 | private boolean isSingle;
|
61 | 58 | private ClassInfo<?> classInfo;
|
62 |
| - private Parser<?> parser; |
63 | 59 | private @Nullable Expression<String> pathExpression;
|
64 | 60 |
|
65 | 61 | @Override
|
66 | 62 | @SuppressWarnings("unchecked")
|
67 | 63 | public boolean init(Expression<?>[] expressions, int pattern, Kleenean isDelayed, ParseResult parseResult) {
|
68 |
| - if (!this.getParser().hasExperiment(Feature.SCRIPT_REFLECTION)) |
69 |
| - return false; |
70 | 64 | @NotNull Literal<ClassInfo<?>> format;
|
71 | 65 | switch (pattern) {
|
72 | 66 | case 0:
|
| 67 | + if (!this.getParser().hasExperiment(Feature.SCRIPT_REFLECTION)) |
| 68 | + return false; |
73 | 69 | this.isSingle = true;
|
74 | 70 | format = (Literal<ClassInfo<?>>) expressions[0];
|
75 | 71 | this.pathExpression = (Expression<String>) expressions[1];
|
76 |
| - this.setExpr((Expression<? extends Node>) expressions[2]); |
77 |
| - break; |
| 72 | + this.setExpr(expressions[2]); |
| 73 | + break; |
78 | 74 | case 1:
|
79 | 75 | this.isSingle = true;
|
80 | 76 | case 2:
|
81 | 77 | format = (Literal<ClassInfo<?>>) expressions[0];
|
82 |
| - this.setExpr((Expression<? extends Node>) expressions[1]); |
| 78 | + this.setExpr(expressions[1]); |
83 | 79 | break;
|
84 | 80 | case 3:
|
85 | 81 | this.isSingle = true;
|
86 | 82 | default:
|
87 | 83 | format = (Literal<ClassInfo<?>>) expressions[1];
|
88 |
| - this.setExpr((Expression<? extends Node>) expressions[0]); |
| 84 | + this.setExpr(expressions[0]); |
89 | 85 | }
|
90 | 86 | this.classInfo = format.getSingle();
|
91 |
| - if (classInfo.getC() == String.class) // don't bother with parser |
92 |
| - return true; |
93 |
| - this.parser = classInfo.getParser(); |
94 |
| - if (this.parser == null || !this.parser.canParse(ParseContext.CONFIG)) { |
95 |
| - Skript.error("The type '" + classInfo.getName() + "' cannot be used to parse config values."); |
96 |
| - return false; |
97 |
| - } |
98 | 87 | return true;
|
99 | 88 | }
|
100 | 89 |
|
101 | 90 | @Override
|
102 |
| - |
103 |
| - public @Nullable Object convert(@Nullable Node node) { |
104 |
| - if (!(node instanceof EntryNode entryNode)) |
| 91 | + public @Nullable Object convert(@Nullable Object object) { |
| 92 | + if (object == null) |
105 | 93 | return null;
|
106 |
| - String string = entryNode.getValue(); |
107 |
| - if (classInfo.getC() == String.class) |
108 |
| - return string; |
109 |
| - return parser.parse(string, ParseContext.CONFIG); |
| 94 | + if (object instanceof AnyValued<?> valued) |
| 95 | + return valued.convertedValue(classInfo); |
| 96 | + return null; |
110 | 97 | }
|
111 | 98 |
|
112 | 99 | @Override
|
113 |
| - protected Object[] get(Event event, Node[] source) { |
| 100 | + protected Object[] get(Event event, Object[] source) { |
114 | 101 | if (pathExpression != null) {
|
| 102 | + if (!(source[0] instanceof Node main)) |
| 103 | + return (Object[]) Array.newInstance(this.getReturnType(), 0); |
115 | 104 | String path = pathExpression.getSingle(event);
|
116 |
| - Node node = source[0].getNodeAt(path); |
| 105 | + Node node = main.getNodeAt(path); |
117 | 106 | Object[] array = (Object[]) Array.newInstance(this.getReturnType(), 1);
|
118 |
| - array[0] = this.convert(node); |
| 107 | + if (!(node instanceof AnyValued<?> valued)) |
| 108 | + return (Object[]) Array.newInstance(this.getReturnType(), 0); |
| 109 | + array[0] = this.convert(valued); |
119 | 110 | return array;
|
120 | 111 | }
|
121 | 112 | return super.get(source, this);
|
122 | 113 | }
|
123 | 114 |
|
124 | 115 | @Override
|
125 | 116 | public Class<?> @Nullable [] acceptChange(ChangeMode mode) {
|
126 |
| - return null; // todo editable configs in future |
| 117 | + if (pathExpression != null) // todo editable configs soon |
| 118 | + return null; |
| 119 | + return switch (mode) { |
| 120 | + case SET -> new Class<?>[] {Object.class}; |
| 121 | + case RESET, DELETE -> new Class<?>[0]; |
| 122 | + default -> null; |
| 123 | + }; |
| 124 | + } |
| 125 | + |
| 126 | + @Override |
| 127 | + public void change(Event event, Object @Nullable [] delta, ChangeMode mode) { |
| 128 | + if (pathExpression != null) |
| 129 | + return; |
| 130 | + Object newValue = delta != null ? delta[0] : null; |
| 131 | + for (Object object : getExpr().getArray(event)) { |
| 132 | + if (!(object instanceof AnyValued<?> valued)) |
| 133 | + continue; |
| 134 | + if (valued.supportsValueChange()) |
| 135 | + valued.changeValueSafely(newValue); |
| 136 | + } |
127 | 137 | }
|
128 | 138 |
|
129 | 139 | @Override
|
|
0 commit comments