Merge branch 'master' into future
This commit is contained in:
commit
9dad47d7a0
14 files changed
+199
-114
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())
|
||||||
|
|||||||
@@ -489,6 +489,39 @@ public class Expression
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LazyValue lazyEval(Context c, Context.Type i, Expression e, Tokenizer.Token t, List<LazyValue> lazyParams)
|
||||||
|
{
|
||||||
|
ILazyFunction.checkInterrupts();
|
||||||
|
if (num_params >= 0 && lazyParams.size() != num_params)
|
||||||
|
throw new InternalExpressionException("'"+name+"' requires "+num_params+" parameters, "+lazyParams.size()+" provided.");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return fun.apply(c, i, lazyParams);
|
||||||
|
}
|
||||||
|
catch (RuntimeException exc)
|
||||||
|
{
|
||||||
|
throw handleCodeException(c, exc, e, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addLazyFunction(String name, TriFunction<Context, Context.Type, List<LazyValue>, LazyValue> fun)
|
||||||
|
{
|
||||||
|
functions.put(name, new AbstractLazyFunction(-1, name)
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public boolean pure() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean transitive() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LazyValue lazyEval(Context c, Context.Type i, Expression e, Tokenizer.Token t, List<LazyValue> lazyParams)
|
public LazyValue lazyEval(Context c, Context.Type i, Expression e, Tokenizer.Token t, List<LazyValue> lazyParams)
|
||||||
{
|
{
|
||||||
@@ -1216,6 +1249,7 @@ public class Expression
|
|||||||
if (arg.op instanceof LazyValue.ContextFreeLazyValue) continue;
|
if (arg.op instanceof LazyValue.ContextFreeLazyValue) continue;
|
||||||
return optimized;
|
return optimized;
|
||||||
}
|
}
|
||||||
|
// a few exceptions which we don't implement in the framework for simplicity for now
|
||||||
if (!operation.pure())
|
if (!operation.pure())
|
||||||
{
|
{
|
||||||
if (symbol.equals("->") && expectedType == Context.Type.MAPDEF)
|
if (symbol.equals("->") && expectedType == Context.Type.MAPDEF)
|
||||||
@@ -1226,6 +1260,14 @@ public class Expression
|
|||||||
return optimized;
|
return optimized;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (operation.pure())
|
||||||
|
{
|
||||||
|
// element access with constant elements will always resolve the same way.
|
||||||
|
if (symbol.equals(":") && expectedType == Context.Type.LVALUE)
|
||||||
|
{
|
||||||
|
expectedType = Context.Type.NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
List<LazyValue> args = new ArrayList<>(node.args.size());
|
List<LazyValue> args = new ArrayList<>(node.args.size());
|
||||||
for (ExpressionNode arg : node.args) {
|
for (ExpressionNode arg : node.args) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public class BlockIterators {
|
|||||||
public static void apply(Expression expression)
|
public static void apply(Expression expression)
|
||||||
{
|
{
|
||||||
// lazy cause of lazy expression
|
// lazy cause of lazy expression
|
||||||
expression.addLazyFunction("scan", -1, (c, t, llv) ->
|
expression.addLazyFunction("scan", (c, t, llv) ->
|
||||||
{
|
{
|
||||||
if (llv.size() < 3) throw new InternalExpressionException("'scan' needs many more arguments");
|
if (llv.size() < 3) throw new InternalExpressionException("'scan' needs many more arguments");
|
||||||
List<Value> lv = Fluff.AbstractFunction.unpackLazy(llv.subList(0, llv.size()-1), c, Context.NONE);
|
List<Value> lv = Fluff.AbstractFunction.unpackLazy(llv.subList(0, llv.size()-1), c, Context.NONE);
|
||||||
@@ -140,7 +140,7 @@ public class BlockIterators {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// must be lazy
|
// must be lazy
|
||||||
expression.addLazyFunction("volume", -1, (c, t, llv) ->
|
expression.addLazyFunction("volume", (c, t, llv) ->
|
||||||
{
|
{
|
||||||
CarpetContext cc = (CarpetContext)c;
|
CarpetContext cc = (CarpetContext)c;
|
||||||
if (llv.size() < 3) throw new InternalExpressionException("'volume' needs many more arguments");
|
if (llv.size() < 3) throw new InternalExpressionException("'volume' needs many more arguments");
|
||||||
|
|||||||
@@ -219,46 +219,6 @@ public class WorldAccess {
|
|||||||
return bs;
|
return bs;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean tryBreakBlock_copy_from_ServerPlayerInteractionManager(ServerPlayerEntity player, BlockPos blockPos_1)
|
|
||||||
{
|
|
||||||
//this could be done little better, by hooking up event handling not in try_break_block but wherever its called
|
|
||||||
// so we can safely call it here
|
|
||||||
// but that would do for now.
|
|
||||||
BlockState blockState_1 = player.world.getBlockState(blockPos_1);
|
|
||||||
if (!player.getMainHandStack().getItem().canMine(blockState_1, player.world, blockPos_1, player)) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
BlockEntity blockEntity_1 = player.world.getBlockEntity(blockPos_1);
|
|
||||||
Block block_1 = blockState_1.getBlock();
|
|
||||||
if ((block_1 instanceof CommandBlock || block_1 instanceof StructureBlock || block_1 instanceof JigsawBlock) && !player.isCreativeLevelTwoOp()) {
|
|
||||||
player.world.updateListeners(blockPos_1, blockState_1, blockState_1, 3);
|
|
||||||
return false;
|
|
||||||
} else if (player.isBlockBreakingRestricted(player.world, blockPos_1, player.interactionManager.getGameMode())) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
block_1.onBreak(player.world, blockPos_1, blockState_1, player);
|
|
||||||
boolean boolean_1 = player.world.removeBlock(blockPos_1, false);
|
|
||||||
if (boolean_1) {
|
|
||||||
block_1.onBroken(player.world, blockPos_1, blockState_1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (player.isCreative()) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
ItemStack itemStack_1 = player.getMainHandStack();
|
|
||||||
boolean boolean_2 = player.canHarvest(blockState_1);
|
|
||||||
itemStack_1.postMine(player.world, blockState_1, blockPos_1, player);
|
|
||||||
if (boolean_1 && boolean_2) {
|
|
||||||
ItemStack itemStack_2 = itemStack_1.isEmpty() ? ItemStack.EMPTY : itemStack_1.copy();
|
|
||||||
block_1.afterBreak(player.world, player, blockPos_1, blockState_1, blockEntity_1, itemStack_2);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void BooYah(ChunkGenerator generator)
|
private static void BooYah(ChunkGenerator generator)
|
||||||
{
|
{
|
||||||
synchronized (generator)
|
synchronized (generator)
|
||||||
@@ -928,7 +888,7 @@ public class WorldAccess {
|
|||||||
Block block = state.getBlock();
|
Block block = state.getBlock();
|
||||||
boolean success = false;
|
boolean success = false;
|
||||||
if (!((block == Blocks.BEDROCK || block == Blocks.BARRIER) && player.interactionManager.isSurvivalLike()))
|
if (!((block == Blocks.BEDROCK || block == Blocks.BARRIER) && player.interactionManager.isSurvivalLike()))
|
||||||
success = tryBreakBlock_copy_from_ServerPlayerInteractionManager(player, where);
|
success = player.interactionManager.tryBreakBlock(where);
|
||||||
if (success)
|
if (success)
|
||||||
world.syncWorldEvent(null, 2001, where, Block.getRawIdFromState(state));
|
world.syncWorldEvent(null, 2001, where, Block.getRawIdFromState(state));
|
||||||
return BooleanValue.of(success);
|
return BooleanValue.of(success);
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public class ControlFlow {
|
|||||||
|
|
||||||
|
|
||||||
// obvious lazy due to conditional evaluation of arguments
|
// obvious lazy due to conditional evaluation of arguments
|
||||||
expression.addLazyFunction("if", -1, (c, t, lv) ->
|
expression.addLazyFunction("if", (c, t, lv) ->
|
||||||
{
|
{
|
||||||
if ( lv.size() < 2 )
|
if ( lv.size() < 2 )
|
||||||
throw new InternalExpressionException("'if' statement needs to have at least one condition and one case");
|
throw new InternalExpressionException("'if' statement needs to have at least one condition and one case");
|
||||||
@@ -79,7 +79,7 @@ public class ControlFlow {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// needs to be lazy since execution of parameters but first one are conditional
|
// needs to be lazy since execution of parameters but first one are conditional
|
||||||
expression.addLazyFunction("try", -1, (c, t, lv) ->
|
expression.addLazyFunction("try", (c, t, lv) ->
|
||||||
{
|
{
|
||||||
if (lv.size()==0)
|
if (lv.size()==0)
|
||||||
throw new InternalExpressionException("'try' needs at least an expression block, and either a catch_epr, or a number of pairs of filters and catch_expr");
|
throw new InternalExpressionException("'try' needs at least an expression block, and either a catch_epr, or a number of pairs of filters and catch_expr");
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ public class DataStructures {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// needs lazy cause sort function is reused
|
// needs lazy cause sort function is reused
|
||||||
expression.addLazyFunction("sort_key", -1, (c, t, lv) -> //get working with iterators
|
expression.addLazyFunction("sort_key", (c, t, lv) -> //get working with iterators
|
||||||
{
|
{
|
||||||
if (lv.size() == 0)
|
if (lv.size() == 0)
|
||||||
throw new InternalExpressionException("First argument for 'sort_key' should be a List");
|
throw new InternalExpressionException("First argument for 'sort_key' should be a List");
|
||||||
@@ -207,7 +207,7 @@ public class DataStructures {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// lazy cause conditional typing - questionable
|
// lazy cause conditional typing - questionable
|
||||||
expression.addLazyFunction("get", -1, (c, t, lv) ->
|
expression.addLazyFunction("get", (c, t, lv) ->
|
||||||
{
|
{
|
||||||
if (lv.size() == 0)
|
if (lv.size() == 0)
|
||||||
throw new InternalExpressionException("'get' requires parameters");
|
throw new InternalExpressionException("'get' requires parameters");
|
||||||
@@ -235,7 +235,7 @@ public class DataStructures {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// same as `get`
|
// same as `get`
|
||||||
expression.addLazyFunction("has", -1, (c, t, lv) ->
|
expression.addLazyFunction("has", (c, t, lv) ->
|
||||||
{
|
{
|
||||||
if (lv.size() == 0)
|
if (lv.size() == 0)
|
||||||
throw new InternalExpressionException("'has' requires parameters");
|
throw new InternalExpressionException("'has' requires parameters");
|
||||||
@@ -263,7 +263,7 @@ public class DataStructures {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// same as `get`
|
// same as `get`
|
||||||
expression.addLazyFunction("put", -1, (c, t, lv) ->
|
expression.addLazyFunction("put", (c, t, lv) ->
|
||||||
{
|
{
|
||||||
if(lv.size()<2)
|
if(lv.size()<2)
|
||||||
{
|
{
|
||||||
@@ -302,7 +302,7 @@ public class DataStructures {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// same as `get`
|
// same as `get`
|
||||||
expression.addLazyFunction("delete", -1, (c, t, lv) ->
|
expression.addLazyFunction("delete", (c, t, lv) ->
|
||||||
{
|
{
|
||||||
if (lv.size() == 0)
|
if (lv.size() == 0)
|
||||||
throw new InternalExpressionException("'delete' requires parameters");
|
throw new InternalExpressionException("'delete' requires parameters");
|
||||||
|
|||||||
@@ -423,7 +423,7 @@ public class Sys {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// lazy cause default expression may not be executed if not needed
|
// lazy cause default expression may not be executed if not needed
|
||||||
expression.addLazyFunction("system_variable_get", -1, (c, t, lv) ->
|
expression.addLazyFunction("system_variable_get", (c, t, lv) ->
|
||||||
{
|
{
|
||||||
if (lv.size() == 0) throw new InternalExpressionException("'system_variable_get' expects at least a key to be fetched");
|
if (lv.size() == 0) throw new InternalExpressionException("'system_variable_get' expects at least a key to be fetched");
|
||||||
Value key = lv.get(0).evalValue(c);
|
Value key = lv.get(0).evalValue(c);
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ public class Threading
|
|||||||
});
|
});
|
||||||
|
|
||||||
// lazy cause expr is evaluated in the same type
|
// lazy cause expr is evaluated in the same type
|
||||||
expression.addLazyFunction("synchronize", -1, (c, t, lv) ->
|
expression.addLazyFunction("synchronize", (c, t, lv) ->
|
||||||
{
|
{
|
||||||
if (lv.size() == 0) throw new InternalExpressionException("'synchronize' require at least an expression to synchronize");
|
if (lv.size() == 0) throw new InternalExpressionException("'synchronize' require at least an expression to synchronize");
|
||||||
Value lockValue = Value.NULL;
|
Value lockValue = Value.NULL;
|
||||||
@@ -85,7 +85,7 @@ public class Threading
|
|||||||
});
|
});
|
||||||
|
|
||||||
// lazy since exception expression is very conditional
|
// lazy since exception expression is very conditional
|
||||||
expression.addLazyFunction("sleep", -1, (c, t, lv) ->
|
expression.addLazyFunction("sleep", (c, t, lv) ->
|
||||||
{
|
{
|
||||||
long time = lv.isEmpty()?0L:NumericValue.asNumber(lv.get(0).evalValue(c)).getLong();
|
long time = lv.isEmpty()?0L:NumericValue.asNumber(lv.get(0).evalValue(c)).getLong();
|
||||||
boolean interrupted = false;
|
boolean interrupted = false;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1088,7 +1088,7 @@ public class EntityValue extends Value
|
|||||||
}
|
}
|
||||||
List<Value> coords = ((ListValue) v).getItems();
|
List<Value> coords = ((ListValue) v).getItems();
|
||||||
double dx = NumericValue.asNumber(coords.get(0)).getDouble();
|
double dx = NumericValue.asNumber(coords.get(0)).getDouble();
|
||||||
double dy = NumericValue.asNumber(coords.get(0)).getDouble();
|
double dy = NumericValue.asNumber(coords.get(1)).getDouble();
|
||||||
double dz = NumericValue.asNumber(coords.get(2)).getDouble();
|
double dz = NumericValue.asNumber(coords.get(2)).getDouble();
|
||||||
e.setVelocity(dx, dy, dz);
|
e.setVelocity(dx, dy, dz);
|
||||||
updateVelocity(e, MathHelper.absMax(MathHelper.absMax(dx, dy), dz));
|
updateVelocity(e, MathHelper.absMax(MathHelper.absMax(dx, dy), dz));
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package carpet.script.value;
|
|||||||
|
|
||||||
import carpet.fakes.InventoryBearerInterface;
|
import carpet.fakes.InventoryBearerInterface;
|
||||||
import carpet.script.CarpetContext;
|
import carpet.script.CarpetContext;
|
||||||
import carpet.script.LazyValue;
|
|
||||||
import carpet.script.exception.InternalExpressionException;
|
import carpet.script.exception.InternalExpressionException;
|
||||||
import carpet.script.exception.ThrowStatement;
|
import carpet.script.exception.ThrowStatement;
|
||||||
import carpet.script.exception.Throwables;
|
import carpet.script.exception.Throwables;
|
||||||
@@ -21,16 +20,16 @@ import net.minecraft.command.argument.NbtPathArgumentType;
|
|||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.InventoryOwner;
|
import net.minecraft.entity.InventoryOwner;
|
||||||
import net.minecraft.entity.LivingEntity;
|
import net.minecraft.entity.LivingEntity;
|
||||||
import net.minecraft.entity.mob.MobEntity;
|
|
||||||
import net.minecraft.entity.passive.MerchantEntity;
|
|
||||||
import net.minecraft.entity.passive.VillagerEntity;
|
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.inventory.Inventory;
|
import net.minecraft.inventory.Inventory;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.AbstractNbtList;
|
import net.minecraft.nbt.AbstractNbtList;
|
||||||
import net.minecraft.nbt.AbstractNbtNumber;
|
import net.minecraft.nbt.AbstractNbtNumber;
|
||||||
import net.minecraft.nbt.NbtCompound;
|
import net.minecraft.nbt.NbtCompound;
|
||||||
|
import net.minecraft.nbt.NbtInt;
|
||||||
import net.minecraft.nbt.NbtList;
|
import net.minecraft.nbt.NbtList;
|
||||||
|
import net.minecraft.nbt.NbtLong;
|
||||||
|
import net.minecraft.nbt.NbtNull;
|
||||||
import net.minecraft.nbt.StringNbtReader;
|
import net.minecraft.nbt.StringNbtReader;
|
||||||
import net.minecraft.nbt.NbtString;
|
import net.minecraft.nbt.NbtString;
|
||||||
import net.minecraft.nbt.NbtElement;
|
import net.minecraft.nbt.NbtElement;
|
||||||
@@ -326,31 +325,32 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
return slot;
|
return slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Value decodeSimpleTag(NbtElement t)
|
||||||
|
{
|
||||||
|
if (t instanceof AbstractNbtNumber)
|
||||||
|
{
|
||||||
|
if (t instanceof NbtLong || t instanceof NbtInt) // short and byte will never exceed float's precision, even int won't
|
||||||
|
{
|
||||||
|
return NumericValue.of(((AbstractNbtNumber) t).longValue());
|
||||||
|
}
|
||||||
|
return NumericValue.of(((AbstractNbtNumber) t).numberValue());
|
||||||
|
}
|
||||||
|
if (t instanceof NbtString)
|
||||||
|
return StringValue.of(t.asString());
|
||||||
|
if (t instanceof NbtNull)
|
||||||
|
return Value.NULL;
|
||||||
|
|
||||||
|
throw new InternalExpressionException("How did we get here: Unknown nbt element class: "+t.getNbtType().getCrashReportName());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private static Value decodeTag(NbtElement t)
|
private static Value decodeTag(NbtElement t)
|
||||||
{
|
{
|
||||||
if (t instanceof NbtCompound)
|
if (t instanceof NbtCompound || t instanceof AbstractNbtList)
|
||||||
return new NBTSerializableValue(() -> t);
|
return new NBTSerializableValue(() -> t);
|
||||||
if (t instanceof AbstractNbtNumber)
|
return decodeSimpleTag(t);
|
||||||
return new NumericValue(((AbstractNbtNumber) t).doubleValue());
|
|
||||||
// more can be done here
|
|
||||||
return new StringValue(t.asString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Value toValue()
|
|
||||||
{
|
|
||||||
return decodeTagDeep(this.getTag());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Value fromValue(Value v)
|
|
||||||
{
|
|
||||||
if (v instanceof NBTSerializableValue)
|
|
||||||
return v;
|
|
||||||
if (v instanceof NullValue)
|
|
||||||
return Value.NULL;
|
|
||||||
return NBTSerializableValue.parseString(v.getString(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static Value decodeTagDeep(NbtElement t)
|
private static Value decodeTagDeep(NbtElement t)
|
||||||
{
|
{
|
||||||
if (t instanceof NbtCompound)
|
if (t instanceof NbtCompound)
|
||||||
@@ -373,10 +373,21 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
}
|
}
|
||||||
return ListValue.wrap(elems);
|
return ListValue.wrap(elems);
|
||||||
}
|
}
|
||||||
if (t instanceof AbstractNbtNumber)
|
return decodeSimpleTag(t);
|
||||||
return new NumericValue(((AbstractNbtNumber) t).doubleValue());
|
}
|
||||||
// more can be done here
|
|
||||||
return new StringValue(t.asString());
|
public Value toValue()
|
||||||
|
{
|
||||||
|
return decodeTagDeep(this.getTag());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Value fromValue(Value v)
|
||||||
|
{
|
||||||
|
if (v instanceof NBTSerializableValue)
|
||||||
|
return v;
|
||||||
|
if (v instanceof NullValue)
|
||||||
|
return Value.NULL;
|
||||||
|
return NBTSerializableValue.parseString(v.getString(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NbtElement getTag()
|
public NbtElement getTag()
|
||||||
|
|||||||
Reference in new issue
Block a user