events handling is disabled now when potentially triggered from the scarpet script preventing from recursive callbacks.
This commit is contained in:
1 parent
8325783bf4
commit
229d0b037b
5 files changed
+104
-32
No files matched your search
@@ -6,6 +6,7 @@ import carpet.helpers.TickSpeed;
|
|||||||
import carpet.script.exception.IntegrityException;
|
import carpet.script.exception.IntegrityException;
|
||||||
import carpet.script.exception.InternalExpressionException;
|
import carpet.script.exception.InternalExpressionException;
|
||||||
import carpet.script.exception.InvalidCallbackException;
|
import carpet.script.exception.InvalidCallbackException;
|
||||||
|
import carpet.script.utils.GlocalFlag;
|
||||||
import carpet.script.value.BlockValue;
|
import carpet.script.value.BlockValue;
|
||||||
import carpet.script.value.BooleanValue;
|
import carpet.script.value.BooleanValue;
|
||||||
import carpet.script.value.EntityValue;
|
import carpet.script.value.EntityValue;
|
||||||
@@ -73,8 +74,7 @@ public class CarpetEventServer
|
|||||||
public final CarpetScriptServer scriptServer;
|
public final CarpetScriptServer scriptServer;
|
||||||
private static final List<Value> NOARGS = Collections.emptyList();
|
private static final List<Value> NOARGS = Collections.emptyList();
|
||||||
public final Map<String, Event> customEvents = new HashMap<>();
|
public final Map<String, Event> customEvents = new HashMap<>();
|
||||||
|
public GlocalFlag handleEvents = new GlocalFlag(true);
|
||||||
|
|
||||||
|
|
||||||
public enum CallbackResult
|
public enum CallbackResult
|
||||||
{
|
{
|
||||||
@@ -194,31 +194,33 @@ public class CarpetEventServer
|
|||||||
*/
|
*/
|
||||||
public void call(Supplier<List<Value>> argumentSupplier, Supplier<ServerCommandSource> cmdSourceSupplier)
|
public void call(Supplier<List<Value>> argumentSupplier, Supplier<ServerCommandSource> cmdSourceSupplier)
|
||||||
{
|
{
|
||||||
if (callList.size() > 0)
|
if (callList.size() > 0 && CarpetServer.scriptServer != null)
|
||||||
{
|
{
|
||||||
CarpetProfiler.ProfilerToken currentSection = CarpetProfiler.start_section(null, "Scarpet events", CarpetProfiler.TYPE.GENERAL);
|
CarpetServer.scriptServer.events.handleEvents.runIfEnabled( () -> {
|
||||||
List<Value> argv = argumentSupplier.get(); // empty for onTickDone
|
CarpetProfiler.ProfilerToken currentSection = CarpetProfiler.start_section(null, "Scarpet events", CarpetProfiler.TYPE.GENERAL);
|
||||||
ServerCommandSource source;
|
List<Value> argv = argumentSupplier.get(); // empty for onTickDone
|
||||||
try
|
ServerCommandSource source;
|
||||||
{
|
try
|
||||||
source = cmdSourceSupplier.get();
|
{
|
||||||
}
|
source = cmdSourceSupplier.get();
|
||||||
catch (NullPointerException noReference) // todo figure out what happens when closing.
|
}
|
||||||
{
|
catch (NullPointerException noReference) // todo figure out what happens when closing.
|
||||||
return;
|
{
|
||||||
}
|
return;
|
||||||
String nameCheck = perPlayerDistribution?source.getName():null;
|
}
|
||||||
assert argv.size() == reqArgs;
|
String nameCheck = perPlayerDistribution ? source.getName() : null;
|
||||||
List<Callback> fails = new ArrayList<>();
|
assert argv.size() == reqArgs;
|
||||||
for (Callback call: callList)
|
List<Callback> fails = new ArrayList<>();
|
||||||
{
|
for (Callback call : callList)
|
||||||
// supressing calls where target player hosts simply don't match
|
{
|
||||||
// handling global hosts with player targets is left to when the host is resolved (few calls deeper).
|
// supressing calls where target player hosts simply don't match
|
||||||
if (nameCheck != null && call.optionalTarget != null && !nameCheck.equals(call.optionalTarget)) continue;
|
// handling global hosts with player targets is left to when the host is resolved (few calls deeper).
|
||||||
if (call.execute(source, argv) == CallbackResult.FAIL) fails.add(call);
|
if (nameCheck != null && call.optionalTarget != null && !nameCheck.equals(call.optionalTarget)) continue;
|
||||||
}
|
if (call.execute(source, argv) == CallbackResult.FAIL) fails.add(call);
|
||||||
for (Callback call : fails) callList.remove(call);
|
}
|
||||||
CarpetProfiler.end_current_section(currentSection);
|
for (Callback call : fails) callList.remove(call);
|
||||||
|
CarpetProfiler.end_current_section(currentSection);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ public class CarpetExpression
|
|||||||
Value playerValue = new EntityValue(e).bindTo("p");
|
Value playerValue = new EntityValue(e).bindTo("p");
|
||||||
context.with("p", (cc, tt) -> playerValue);
|
context.with("p", (cc, tt) -> playerValue);
|
||||||
}
|
}
|
||||||
return this.expr.eval(context).getBoolean();
|
return CarpetServer.scriptServer.events.handleEvents.getWhileDisabled(()-> this.expr.eval(context).getBoolean());
|
||||||
}
|
}
|
||||||
catch (ExpressionException e)
|
catch (ExpressionException e)
|
||||||
{
|
{
|
||||||
@@ -109,7 +109,7 @@ public class CarpetExpression
|
|||||||
Value playerValue = new EntityValue(e).bindTo("p");
|
Value playerValue = new EntityValue(e).bindTo("p");
|
||||||
context.with("p", (cc, tt) -> playerValue);
|
context.with("p", (cc, tt) -> playerValue);
|
||||||
}
|
}
|
||||||
return this.expr.eval(context);
|
return CarpetServer.scriptServer.events.handleEvents.getWhileDisabled(()-> this.expr.eval(context));
|
||||||
}
|
}
|
||||||
catch (ExpressionException e)
|
catch (ExpressionException e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -710,7 +710,7 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return call(source, function, args);
|
return scriptServer.events.handleEvents.getWhileDisabled(() -> call(source, function, args));
|
||||||
}
|
}
|
||||||
catch (CarpetExpressionException exc)
|
catch (CarpetExpressionException exc)
|
||||||
{
|
{
|
||||||
@@ -815,11 +815,11 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
// TODO: this is just for now - invoke would be able to invoke other hosts scripts
|
// TODO: this is just for now - invoke would be able to invoke other hosts scripts
|
||||||
assertAppIntegrity(function.getModule());
|
assertAppIntegrity(function.getModule());
|
||||||
Context context = new CarpetContext(this, source, BlockPos.ORIGIN);
|
Context context = new CarpetContext(this, source, BlockPos.ORIGIN);
|
||||||
return function.getExpression().evalValue(
|
return scriptServer.events.handleEvents.getWhileDisabled(() -> function.getExpression().evalValue(
|
||||||
() -> function.lazyEval(context, Context.VOID, function.getExpression(), function.getToken(), argv),
|
() -> function.lazyEval(context, Context.VOID, function.getExpression(), function.getToken(), argv),
|
||||||
context,
|
context,
|
||||||
Context.VOID
|
Context.VOID
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
catch (ExpressionException e)
|
catch (ExpressionException e)
|
||||||
{
|
{
|
||||||
@@ -891,6 +891,7 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
{
|
{
|
||||||
ServerPlayerEntity player = (user==null)?null:scriptServer.server.getPlayerManager().getPlayer(user);
|
ServerPlayerEntity player = (user==null)?null:scriptServer.server.getPlayerManager().getPlayer(user);
|
||||||
ServerCommandSource source = (player != null)?player.getCommandSource():scriptServer.server.getCommandSource();
|
ServerCommandSource source = (player != null)?player.getCommandSource():scriptServer.server.getCommandSource();
|
||||||
|
return scriptServer.events.handleEvents.getWhileDisabled(()->{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return callUDF(BlockPos.ORIGIN, source, fun, arguments);
|
return callUDF(BlockPos.ORIGIN, source, fun, arguments);
|
||||||
@@ -899,6 +900,7 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -375,7 +375,7 @@ public class CarpetScriptServer
|
|||||||
{
|
{
|
||||||
CarpetProfiler.ProfilerToken token;
|
CarpetProfiler.ProfilerToken token;
|
||||||
token = CarpetProfiler.start_section(null, "Scarpet schedule", CarpetProfiler.TYPE.GENERAL);
|
token = CarpetProfiler.start_section(null, "Scarpet schedule", CarpetProfiler.TYPE.GENERAL);
|
||||||
events.tick();
|
events.handleEvents.getWhileDisabled( () -> {events.tick(); return null;});
|
||||||
CarpetProfiler.end_current_section(token);
|
CarpetProfiler.end_current_section(token);
|
||||||
token = CarpetProfiler.start_section(null, "Scarpet app data", CarpetProfiler.TYPE.GENERAL);
|
token = CarpetProfiler.start_section(null, "Scarpet app data", CarpetProfiler.TYPE.GENERAL);
|
||||||
for (CarpetScriptHost host : modules.values())
|
for (CarpetScriptHost host : modules.values())
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package carpet.script.utils;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class GlocalFlag extends ThreadLocal<Boolean>
|
||||||
|
{
|
||||||
|
private final boolean initial;
|
||||||
|
|
||||||
|
public GlocalFlag(boolean initial)
|
||||||
|
{
|
||||||
|
this.initial = initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean initialValue()
|
||||||
|
{
|
||||||
|
return initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows to thread-safely wrap a call while disabling a global flag and setting it back up right after.
|
||||||
|
* @param action - callback to invoke when the wrapping is all setup
|
||||||
|
* @param <T> - returned value of that action, whatever that might be
|
||||||
|
* @return result of the action
|
||||||
|
*/
|
||||||
|
public <T> T getWhileDisabled(Supplier<T> action)
|
||||||
|
{
|
||||||
|
return whileValueReturn(!initial, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> T whileValueReturn(boolean what, Supplier<T> action)
|
||||||
|
{
|
||||||
|
T result;
|
||||||
|
boolean previous;
|
||||||
|
synchronized (this)
|
||||||
|
{
|
||||||
|
previous = get();
|
||||||
|
set(what);
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
result = action.get();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
set(previous);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean runIfEnabled(Runnable action)
|
||||||
|
{
|
||||||
|
synchronized (this)
|
||||||
|
{
|
||||||
|
if (get() != initial) return false;
|
||||||
|
set(!initial);
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
action.run();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
set(initial);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user