Skip to content

Commit 7370afb

Browse files
committed
delegate getActualNext and executionIntent
1 parent d57002b commit 7370afb

File tree

2 files changed

+77
-113
lines changed

2 files changed

+77
-113
lines changed

src/main/java/ch/njol/skript/effects/Delay.java

Lines changed: 67 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@
66
import ch.njol.skript.doc.Example;
77
import ch.njol.skript.doc.Name;
88
import ch.njol.skript.doc.Since;
9-
import ch.njol.skript.lang.Effect;
9+
import ch.njol.skript.lang.EffectSection;
1010
import ch.njol.skript.lang.Expression;
1111
import ch.njol.skript.lang.Literal;
12-
import ch.njol.skript.lang.Section;
1312
import ch.njol.skript.lang.SkriptParser.ParseResult;
1413
import ch.njol.skript.lang.Trigger;
1514
import ch.njol.skript.lang.TriggerItem;
@@ -48,21 +47,21 @@
4847
send "...and goodbye" to player
4948
""")
5049
@Since("1.4, 2.15")
51-
public class Delay extends Effect {
50+
public class Delay extends EffectSection {
5251

5352
static {
54-
Skript.registerEffect(Delay.class, "(wait|halt) [for] %timespan%");
55-
Skript.registerSection(DelaySection.class, "(wait|halt) [for] %timespan%");
53+
Skript.registerSection(Delay.class, "(wait|halt) [for] %timespan%");
5654
}
5755

5856
@SuppressWarnings("NotNullFieldNotInitialized")
5957
protected Expression<Timespan> duration;
6058

59+
private @Nullable Trigger trigger;
60+
6161
@SuppressWarnings({"unchecked", "null"})
6262
@Override
63-
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
64-
getParser().setHasDelayBefore(Kleenean.TRUE);
65-
63+
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult,
64+
@Nullable SectionNode sectionNode, @Nullable List<TriggerItem> triggerItems) {
6665
duration = (Expression<Timespan>) exprs[0];
6766
if (duration instanceof Literal) { // If we can, do sanity check for delays
6867
Timespan timespan = ((Literal<Timespan>) duration).getSingle();
@@ -76,53 +75,91 @@ public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelaye
7675
}
7776
}
7877

78+
if (hasSection()) {
79+
assert sectionNode != null;
80+
// Parse the body under the outer event context so event values still resolve inside it.
81+
// Locals are isolated at runtime via the swap dance in walk().
82+
Class<? extends Event>[] outerEvents = getParser().getCurrentEvents();
83+
Runnable beforeLoading = () -> getParser().setHasDelayBefore(Kleenean.TRUE);
84+
trigger = loadCode(sectionNode, "wait", beforeLoading, null, outerEvents);
85+
// Outer trigger is NOT delayed - code after the section runs immediately.
86+
return trigger != null;
87+
}
88+
89+
getParser().setHasDelayBefore(Kleenean.TRUE);
7990
return true;
8091
}
8192

8293
@Override
83-
@Nullable
84-
protected TriggerItem walk(Event event) {
94+
protected @Nullable TriggerItem walk(Event event) {
8595
debug(event, true);
8696
long start = Skript.debug() ? System.nanoTime() : 0;
87-
TriggerItem next = getNext();
88-
if (next != null && Skript.getInstance().isEnabled()) { // See https://github.com/SkriptLang/Skript/issues/3702
8997

90-
Timespan duration = this.duration.getSingle(event);
91-
if (duration == null)
92-
return null;
98+
if (!Skript.getInstance().isEnabled()) // See https://github.com/SkriptLang/Skript/issues/3702
99+
return trigger != null ? super.walk(event, false) : null;
100+
101+
Timespan duration = this.duration.getSingle(event);
102+
if (duration == null)
103+
return trigger != null ? super.walk(event, false) : null;
104+
105+
long ticks = Math.max(duration.getAs(Timespan.TimePeriod.TICK), 1); // Minimum delay is one tick, less than it is useless!
106+
107+
if (trigger != null) {
108+
109+
Object snapshot = Variables.copyLocalVariables(event);
110+
Trigger body = trigger;
111+
Bukkit.getScheduler().scheduleSyncDelayedTask(Skript.getInstance(), () -> {
112+
Skript.debug(getIndentation() + "... running delayed section after " + (System.nanoTime() - start) / 1_000_000_000. + "s");
113+
93114

94-
// Back up local variables
115+
Object outerLocals = Variables.removeLocals(event);
116+
if (snapshot != null)
117+
Variables.setLocalVariables(event, snapshot);
118+
119+
Object timing = null;
120+
if (SkriptTimings.enabled()) {
121+
Trigger parentTrigger = getTrigger();
122+
if (parentTrigger != null)
123+
timing = SkriptTimings.start(parentTrigger.getDebugLabel());
124+
}
125+
try {
126+
TriggerItem.walk(body, event);
127+
} finally {
128+
Variables.setLocalVariables(event, outerLocals);
129+
SkriptTimings.stop(timing); // Stop timing if it was even started
130+
}
131+
}, ticks);
132+
return super.walk(event, false);
133+
}
134+
135+
136+
TriggerItem next = getNext();
137+
if (next != null) {
95138
Object localVars = Variables.removeLocals(event);
96139

97140
Bukkit.getScheduler().scheduleSyncDelayedTask(Skript.getInstance(), () -> {
98141
addDelayedEvent(event);
99142
Skript.debug(getIndentation() + "... continuing after " + (System.nanoTime() - start) / 1_000_000_000. + "s");
100143

101-
// Re-set local variables
102144
if (localVars != null)
103145
Variables.setLocalVariables(event, localVars);
104146

105-
Object timing = null; // Timings reference must be kept so that it can be stopped after TriggerItem execution
106-
if (SkriptTimings.enabled()) { // getTrigger call is not free, do it only if we must
107-
Trigger trigger = getTrigger();
108-
if (trigger != null)
109-
timing = SkriptTimings.start(trigger.getDebugLabel());
147+
Object timing = null;
148+
if (SkriptTimings.enabled()) {
149+
Trigger parentTrigger = getTrigger();
150+
if (parentTrigger != null)
151+
timing = SkriptTimings.start(parentTrigger.getDebugLabel());
110152
}
111153

112154
TriggerItem.walk(next, event);
113155
Variables.removeLocals(event); // Clean up local vars, we may be exiting now
114156

115-
SkriptTimings.stop(timing); // Stop timing if it was even started
116-
}, Math.max(duration.getAs(Timespan.TimePeriod.TICK), 1)); // Minimum delay is one tick, less than it is useless!
157+
SkriptTimings.stop(timing);
158+
}, ticks);
117159
}
118160
return null;
119161
}
120162

121-
@Override
122-
protected void execute(Event event) {
123-
throw new UnsupportedOperationException();
124-
}
125-
126163
@Override
127164
public String toString(@Nullable Event event, boolean debug) {
128165
return "wait for " + duration.toString(event, debug) + (event == null ? "" : "...");
@@ -140,95 +177,12 @@ public static boolean isDelayed(Event event) {
140177
return DELAYED.contains(event);
141178
}
142179

143-
/**
144-
* Section form of {@link Delay}. The body is deferred and executed on the same event after the
145-
* delay elapses; code after the section continues immediately in the outer trigger.
146-
*/
147-
public static class DelaySection extends Section {
148-
149-
@SuppressWarnings("NotNullFieldNotInitialized")
150-
private Expression<Timespan> duration;
151-
private Trigger trigger;
152-
153-
@Override
154-
@SuppressWarnings("unchecked")
155-
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed,
156-
ParseResult parseResult, SectionNode sectionNode, List<TriggerItem> triggerItems) {
157-
duration = (Expression<Timespan>) exprs[0];
158-
if (duration instanceof Literal) { // If we can, do sanity check for delays
159-
Timespan timespan = ((Literal<Timespan>) duration).getSingle();
160-
if (timespan.isInfinite()) {
161-
Skript.error("Delaying for an eternity is not allowed. Use the 'stop' effect instead.");
162-
return false;
163-
}
164-
long millis = timespan.getAs(Timespan.TimePeriod.MILLISECOND);
165-
if (millis < 50) {
166-
Skript.warning("Delays less than one tick are not possible, defaulting to one tick.");
167-
}
168-
}
169-
170-
// Parse the body under the outer event context so event values still resolve inside it.
171-
// Locals are isolated at runtime via the swap dance in walk().
172-
Class<? extends Event>[] outerEvents = getParser().getCurrentEvents();
173-
Runnable beforeLoading = () -> getParser().setHasDelayBefore(Kleenean.TRUE);
174-
trigger = loadCode(sectionNode, "wait", beforeLoading, null, outerEvents);
175-
// Outer trigger is NOT delayed - code after the section runs immediately.
176-
return trigger != null;
177-
}
178-
179-
@Override
180-
protected @Nullable TriggerItem walk(Event event) {
181-
debug(event, true);
182-
long start = Skript.debug() ? System.nanoTime() : 0;
183-
184-
if (!Skript.getInstance().isEnabled()) // See https://github.com/SkriptLang/Skript/issues/3702
185-
return walk(event, false);
186-
187-
Timespan duration = this.duration.getSingle(event);
188-
if (duration == null)
189-
return walk(event, false);
190-
191-
long ticks = Math.max(duration.getAs(Timespan.TimePeriod.TICK), 1); // Minimum delay is one tick, less than it is useless!
192-
193-
Object snapshot = Variables.copyLocalVariables(event);
194-
Trigger body = trigger;
195-
Bukkit.getScheduler().scheduleSyncDelayedTask(Skript.getInstance(), () -> {
196-
Skript.debug(getIndentation() + "... running delayed section after " + (System.nanoTime() - start) / 1_000_000_000. + "s");
197-
198-
// Swap outer locals with the snapshot taken when the section was scheduled,
199-
// so the body sees its own isolated copy and doesn't leak into the outer trigger.
200-
Object outerLocals = Variables.removeLocals(event);
201-
if (snapshot != null)
202-
Variables.setLocalVariables(event, snapshot);
203-
204-
Object timing = null;
205-
if (SkriptTimings.enabled()) {
206-
Trigger parentTrigger = getTrigger();
207-
if (parentTrigger != null)
208-
timing = SkriptTimings.start(parentTrigger.getDebugLabel());
209-
}
210-
try {
211-
TriggerItem.walk(body, event);
212-
} finally {
213-
Variables.setLocalVariables(event, outerLocals);
214-
SkriptTimings.stop(timing);
215-
}
216-
}, ticks);
217-
return walk(event, false);
218-
}
219-
220-
@Override
221-
public String toString(@Nullable Event event, boolean debug) {
222-
return "wait for " + duration.toString(event, debug) + (event == null ? "" : "...");
223-
}
224-
225-
}
226-
227180
/**
228181
* The main method for marking the execution of {@link TriggerItem}s as delayed.
229182
* @param event The event to mark as delayed.
230183
*/
231184
public static void addDelayedEvent(Event event) {
232185
DELAYED.add(event);
233186
}
187+
234188
}

src/main/java/ch/njol/skript/lang/EffectSectionEffect.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,16 @@ public TriggerItem setNext(@Nullable TriggerItem next) {
4949
return effectSection.getNext();
5050
}
5151

52+
@Override
53+
public @Nullable TriggerItem getActualNext() {
54+
return effectSection.getActualNext();
55+
}
56+
57+
@Override
58+
public @Nullable ExecutionIntent executionIntent() {
59+
return effectSection.executionIntent();
60+
}
61+
5262
@Override
5363
public String toString(@Nullable Event event, boolean debug) {
5464
return effectSection.toString(event, debug);

0 commit comments

Comments
 (0)