Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SecRunnable #7389

Open
wants to merge 3 commits into
base: dev/feature
Choose a base branch
from
Open
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 133 additions & 0 deletions src/main/java/ch/njol/skript/sections/SecRunnable.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package ch.njol.skript.sections;

import ch.njol.skript.Skript;
import ch.njol.skript.config.Node;
import ch.njol.skript.config.SectionNode;
import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Examples;
import ch.njol.skript.doc.Name;
import ch.njol.skript.doc.Since;
import ch.njol.skript.lang.*;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.util.Timespan;
import ch.njol.skript.util.Timespan.TimePeriod;
import ch.njol.skript.variables.Variables;
import ch.njol.util.Kleenean;
import org.bukkit.Bukkit;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer;

import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

@Name("Runnable")
@Description({
"This section will run the code within after waiting the provided timespam.",
"This will not halt the script from the code after this section from being ran.",
"Any local variables defined before hand will be usable within the section, but any modifications done within the section do not precedent outside of the section.",
"Any local variables defined within this section will not be usable outside of the section.",
"Any local variables defined after this section will not be accessible in the section."
})
@Examples({
"set {_a} to 1",
"after 2 seconds run:",
"\tadd 1 to {_a}",
"\tset {_b} to 3",
"\tif {_c} is set:",
"\t\t# This will fail because this variable was not defined before or within this section.",
"set {_c} to 4",
"if {_a} = 2:",
"\t# This will fail because the code within the section does not change the local variables outside of it.",
"if {_b} is set:",
"\t# This will fail because local variables defined within the section is not accessible outside of it.",
"",
"after a second run:",
"\tbroadcast \"Bye\"",
"\t# This will be broadcasted second",
"broadcast \"Hi\"",
"# This will be broadcasted first"
})
@Since("INSERT VERSION")
public class SecRunnable extends Section implements SyntaxRuntimeErrorProducer {

public static class RunnableEvent extends Event {
@Override
public @NotNull HandlerList getHandlers() {
throw new IllegalStateException();
}
}

static {
Skript.registerSection(SecRunnable.class, "after %timespan% run");
}

private Trigger trigger;
private Expression<Timespan> timespan;
private Node node;
private String rawExpr;

@Override
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult, SectionNode sectionNode, List<TriggerItem> triggerItems) {
if (sectionNode.isEmpty()) {
Skript.error("This section cannot be empty.");
return false;
}
AtomicBoolean delayed = new AtomicBoolean(false);
Runnable afterLoading = () -> delayed.set(!getParser().getHasDelayBefore().isFalse());
trigger = loadCode(sectionNode, "runnable", afterLoading, RunnableEvent.class);
//noinspection unchecked
timespan = (Expression<Timespan>) exprs[0];
node = getParser().getNode();
rawExpr = parseResult.expr;
if (timespan instanceof Literal<Timespan> literal && literal.getSingle().getAs(TimePeriod.TICK) == 0) {
Skript.warning("The provided timespan is equal to 0 seconds. Consider running the code directly rather than within this section.");
}
return true;
}

@Override
protected @Nullable TriggerItem walk(Event event) {
Object locals = Variables.copyLocalVariables(event);
Timespan timespan = this.timespan.getSingle(event);
if (timespan == null) {
error("The provided timespan cannot be null.");
} else {
long ticks = timespan.getAs(TimePeriod.TICK);
if (ticks == 0) {
warning("The provided timespan is equal to 0 seconds. Consider running the code directly rather than within this section.");
execute(locals);
} else {
Bukkit.getScheduler().scheduleSyncDelayedTask(Skript.getInstance(), () -> {
execute(locals);
}, ticks);
}
}
return getActualNext();
}

private void execute(Object locals) {
RunnableEvent runnableEvent = new RunnableEvent();
Variables.setLocalVariables(runnableEvent, locals);
TriggerItem.walk(trigger, runnableEvent);
Variables.removeLocals(runnableEvent);
}
TheAbsolutionism marked this conversation as resolved.
Show resolved Hide resolved

@Override
public @Nullable String toHighlight() {
return rawExpr;
}

@Override
public Node getNode() {
return node;
}

@Override
public String toString(@Nullable Event event, boolean debug) {
return "after " + timespan.toString(event, debug) + " run";
}

}
Loading