Merge branch 'master' into 1.16

This commit is contained in:
gnembon committed 2020-05-10 17:25:21 -03:00
commit 5e5393ba3d
7 files changed
+58 -74

No files matched your search

+12
View File
@@ -790,6 +790,18 @@ Returns true if task has completed, or false otherwise.
Evaluates `expression` synchronized with respect to the lock `lock`. Returns the value of the expression. Evaluates `expression` synchronized with respect to the lock `lock`. Returns the value of the expression.
### `task_dock(expr)`
In a not-task (running regular code on the main game thread) it is a pass-through command. In tasks - it docks
the current thread on the main server thread and executes expression as one server offline server task.
This is especially helpful in case a task has several docking operations to perform, such as setting a block, and
it would be much more efficient to do them all at once rather then packing each block access in each own call.
Be mindful, that docking the task means that the tick execution will be delayed until the expression is evaluated.
This will synchronize your task with other tasks using `task_dock`, but if you should be using `synchronize` to
synchronize tasks without locking the main thread.
* * * * * *
## Auxiliary functions ## Auxiliary functions
+12
View File
@@ -147,6 +147,18 @@ Returns true if task has completed, or false otherwise.
Evaluates `expression` synchronized with respect to the lock `lock`. Returns the value of the expression. Evaluates `expression` synchronized with respect to the lock `lock`. Returns the value of the expression.
### `task_dock(expr)`
In a not-task (running regular code on the main game thread) it is a pass-through command. In tasks - it docks
the current thread on the main server thread and executes expression as one server offline server task.
This is especially helpful in case a task has several docking operations to perform, such as setting a block, and
it would be much more efficient to do them all at once rather then packing each block access in each own call.
Be mindful, that docking the task means that the tick execution will be delayed until the expression is evaluated.
This will synchronize your task with other tasks using `task_dock`, but if you should be using `synchronize` to
synchronize tasks without locking the main thread.
* * * * * *
## Auxiliary functions ## Auxiliary functions
@@ -85,6 +85,7 @@ tanh
task task
task_completed task_completed
task_count task_count
task_dock
task_join task_join
task_value task_value
throw throw
@@ -36,7 +36,7 @@
print return exit throw try print return exit throw try
task task_count task_value task_join task_completed synchronize task task_count task_value task_join task_completed synchronize task_dock
system_variable_get system_variable_set system_variable_get system_variable_set
@@ -2809,6 +2809,18 @@ public class CarpetExpression
return (_c, _t) -> ret; return (_c, _t) -> ret;
}); });
this.expr.addLazyFunction("task_dock", 1, (c, t, lv) -> {
CarpetContext cc = (CarpetContext)c;
MinecraftServer server = cc.s.getMinecraftServer();
if (server.isOnThread()) return lv.get(1); // pass through for on thread tasks
Value[] result = new Value[]{Value.NULL};
((CarpetContext) c).s.getMinecraftServer().submitAndJoin(() -> result[0] = lv.get(0).evalValue(c, t));
Value ret = result[0]; // preventing from lazy evaluating of the result in case a future completes later
return (_c, _t) -> ret;
// pass through placeholder
// implmenetation should dock the task on the main thread.
});
this.expr.addLazyFunction("logger", 1, (c, t, lv) -> this.expr.addLazyFunction("logger", 1, (c, t, lv) ->
{ {
Value res = lv.get(0).evalValue(c); Value res = lv.get(0).evalValue(c);
@@ -2985,7 +2997,7 @@ public class CarpetExpression
throw new InternalExpressionException("'schedule' should have at least 2 arguments, delay and call name"); throw new InternalExpressionException("'schedule' should have at least 2 arguments, delay and call name");
long delay = NumericValue.asNumber(lv.get(0).evalValue(c)).getLong(); long delay = NumericValue.asNumber(lv.get(0).evalValue(c)).getLong();
FunctionArgument functionArgument = FunctionArgument.findIn(c, this.expr.module, lv, 1, true); FunctionArgument functionArgument = FunctionArgument.findIn(c, this.expr.module, lv, 1, true, true);
CarpetServer.scriptServer.events.scheduleCall( CarpetServer.scriptServer.events.scheduleCall(
(CarpetContext) c, (CarpetContext) c,
@@ -2994,29 +3006,6 @@ public class CarpetExpression
delay delay
); );
return (c_, t_) -> Value.TRUE; return (c_, t_) -> Value.TRUE;
/*
Value functionValue = lv.get(1).evalValue(c);
if (!(functionValue instanceof FunctionValue))
{
String name = functionValue.getString();
functionValue = c.host.getAssertFunction(this.expr.module, name);
}
FunctionValue function = (FunctionValue)functionValue;
CarpetContext cc = (CarpetContext)c;
List<Value> args = new ArrayList<>();
for (int i=2; i < lv.size(); i++)
{
Value arg = lv.get(i).evalValue(cc);
args.add(arg);
}
if (function.getArguments().size() != args.size())
throw new InternalExpressionException("Function "+function.getString()+" takes "+
function.getArguments().size()+" arguments, "+args.size()+" provided.");
CarpetServer.scriptServer.events.scheduleCall(cc, function, args, delay);
return (c_, t_) -> Value.TRUE;
*/
}); });
this.expr.addLazyFunction("load_app_data", -1, (c, t, lv) -> this.expr.addLazyFunction("load_app_data", -1, (c, t, lv) ->
+8 -42
View File
@@ -440,27 +440,10 @@ public class Expression
//lv.remove(lv.size()-1); // aint gonna cut it // maybe it will because of the eager eval changes //lv.remove(lv.size()-1); // aint gonna cut it // maybe it will because of the eager eval changes
if (t != Context.SIGNATURE) // just call the function if (t != Context.SIGNATURE) // just call the function
{ {
FunctionArgument functionArgument = FunctionArgument.findIn(c, module, lv, 0, true); FunctionArgument functionArgument = FunctionArgument.findIn(c, module, lv, 0, false, true);
FunctionValue fun = functionArgument.function; FunctionValue fun = functionArgument.function;
Value retval = fun.callInContext(expr, c, t, fun.getExpression(), fun.getToken(), functionArgument.args).evalValue(c); Value retval = fun.callInContext(expr, c, t, fun.getExpression(), fun.getToken(), functionArgument.args).evalValue(c);
return (cc, tt) -> retval; ///!!!! dono might need to store expr and token in statics? (e? t?) return (cc, tt) -> retval; ///!!!! dono might need to store expr and token in statics? (e? t?)
/*
Value functionValue = lv.get(0).evalValue(c);
if (!(functionValue instanceof FunctionValue))
{
String name = functionValue.getString();
functionValue = c.host.getAssertFunction(module, name);
}
List<LazyValue> lvargs = new ArrayList<>(lv.size()-1);
for (int i=1; i< lv.size(); i++)
{
lvargs.add(lv.get(i));
}
FunctionValue fun = (FunctionValue)functionValue;
Value retval = fun.callInContext(expr, c, t, fun.getExpression(), fun.getToken(), lvargs).evalValue(c);
return (cc, tt) -> retval; ///!!!! dono might need to store expr and token in statics? (e? t?)
*/
} }
// gimme signature // gimme signature
String name = lv.get(0).evalValue(c).getString(); String name = lv.get(0).evalValue(c).getString();
@@ -1878,35 +1861,12 @@ public class Expression
addLazyFunctionWithDelegation("task", -1, (c, t, expr, tok, lv) -> { addLazyFunctionWithDelegation("task", -1, (c, t, expr, tok, lv) -> {
if (lv.size() == 0) if (lv.size() == 0)
throw new InternalExpressionException("'task' requires at least function to call as a parameter"); throw new InternalExpressionException("'task' requires at least function to call as a parameter");
FunctionArgument functionArgument = FunctionArgument.findIn(c, module, lv, 0); FunctionArgument functionArgument = FunctionArgument.findIn(c, module, lv, 0, true, false);
Value queue = Value.NULL; Value queue = Value.NULL;
if (lv.size() > functionArgument.offset) queue = lv.get(functionArgument.offset).evalValue(c); if (lv.size() > functionArgument.offset) queue = lv.get(functionArgument.offset).evalValue(c);
ThreadValue thread = new ThreadValue(queue, functionArgument.function, expr, tok, c, functionArgument.args); ThreadValue thread = new ThreadValue(queue, functionArgument.function, expr, tok, c, functionArgument.args);
Thread.yield(); Thread.yield();
return (cc, tt) -> thread; return (cc, tt) -> thread;
/*
Value funcDesc = lv.get(0).evalValue(c);
if (!(funcDesc instanceof FunctionValue))
{
String name = funcDesc.getString();
funcDesc = c.host.getAssertFunction(module, name);
}
FunctionValue fun = (FunctionValue)funcDesc;
int extraargs = lv.size() - fun.getArguments().size();
if (extraargs != 1 && extraargs != 2)
{
throw new InternalExpressionException("Function takes "+fun.getArguments().size()+" arguments.");
}
List<LazyValue> lvargs = new ArrayList<>();
for (int i=0; i< fun.getArguments().size(); i++)
{
lvargs.add(lv.get(i+1));
}
Value queue = Value.NULL;
if (extraargs == 2) queue = lv.get(lv.size()-1).evalValue(c);
ThreadValue thread = new ThreadValue(queue, fun, expr, tok, c, lvargs);
Thread.yield();
return (cc, tt) -> thread;*/
}); });
addFunction("task_count", (lv) -> addFunction("task_count", (lv) ->
@@ -1930,6 +1890,12 @@ public class Expression
return ((ThreadValue) v).join(); return ((ThreadValue) v).join();
}); });
addLazyFunction("task_dock", 1, (c, t, lv) -> {
// pass through placeholder
// implmenetation should dock the task on the main thread.
return lv.get(0);
});
addUnaryFunction("task_completed", (v) -> { addUnaryFunction("task_completed", (v) -> {
if (!(v instanceof ThreadValue)) if (!(v instanceof ThreadValue))
throw new InternalExpressionException("'task_completed' could only be used with a task value"); throw new InternalExpressionException("'task_completed' could only be used with a task value");
@@ -22,11 +22,7 @@ public class FunctionArgument extends Argument
this.function = function; this.function = function;
this.args = args; this.args = args;
} }
public static FunctionArgument findIn(Context c, Module module, List<LazyValue> params, int offset) public static FunctionArgument findIn(Context c, Module module, List<LazyValue> params, int offset, boolean prematureEvaluation, boolean strict)
{
return findIn(c, module, params, offset, false);
}
public static FunctionArgument findIn(Context c, Module module, List<LazyValue> params, int offset, boolean strict)
{ {
Value functionValue = params.get(offset).evalValue(c); Value functionValue = params.get(offset).evalValue(c);
if (!(functionValue instanceof FunctionValue)) if (!(functionValue instanceof FunctionValue))
@@ -40,9 +36,17 @@ public class FunctionArgument extends Argument
if (extraargs < 0 || (extraargs > 0 && strict)) if (extraargs < 0 || (extraargs > 0 && strict))
throw new InternalExpressionException("Function "+fun.getPrettyString()+" requires "+fun.getArguments().size()+" arguments"); throw new InternalExpressionException("Function "+fun.getPrettyString()+" requires "+fun.getArguments().size()+" arguments");
List<LazyValue> lvargs = new ArrayList<>(); List<LazyValue> lvargs = new ArrayList<>();
for (int i=0; i< argsize; i++) if (prematureEvaluation)
{ {
lvargs.add(params.get(offset+1+i)); for (int i = 0; i < argsize; i++)
{
Value arg = params.get(offset + 1 + i).evalValue(c);
lvargs.add((cc, tt) -> arg);
}
}
else
{
for (int i = 0; i < argsize; i++) lvargs.add(params.get(offset + 1 + i));
} }
return new FunctionArgument(fun, offset+1+argsize, lvargs); return new FunctionArgument(fun, offset+1+argsize, lvargs);
} }