removed tail assumption of known number of function arguments. Added task_thread

This commit is contained in:
gnembon committed 2020-09-21 09:37:30 -03:00
1 parent 43757d6e5f
commit 7de132eb56
2 files changed
+19 -10

No files matched your search

+6 -7
View File
@@ -100,22 +100,21 @@ from other threads, just because the only possibility of a deadlock in this case
bad code, not the internal world access behaviour. Some things tough like player or entity manipulation, can be bad code, not the internal world access behaviour. Some things tough like player or entity manipulation, can be
effectively parallelized. effectively parallelized.
### `task(function, ?args...., ?executor)` ### `task(function, ... args)`, `task_thread(executor, function, ... args)`
Creates and runs a parallel task, returning the handle to the task object. Task will return the return value of the Creates and runs a parallel task, returning the handle to the task object. Task will return the return value of the
function when its completed, or will return `null` immediately if task is still in progress, so grabbing a value of function when its completed, or will return `null` immediately if task is still in progress, so grabbing a value of
a task object is non-blocking. Function can be either function value, or function lambda, or a name of an existing a task object is non-blocking. Function can be either function value, or function lambda, or a name of an existing
defined function. In case function needs arguments to be called with, they should be supplied after the function defined function. In case function needs arguments to be called with, they should be supplied after the function
name, or value. Optional `executor` identifier is to place the task in a specific queue identified by this value. name, or value. `executor` identifier in `task_thread`, places the task in a specific queue identified by this value.
The default thread value is the `null` thread. There is no limits on number of parallel tasks for any executor, The default thread value is the `null` thread. There are no limits on number of parallel tasks for any executor,
so using different queues is solely for synchronization purposes. Also, since `task` function knows how many extra so using different queues is solely for synchronization purposes.
arguments it requires, the use of tailing optional parameter for the custom executor thread pool is not ambiguous.
<pre> <pre>
task( _() -> print('Hello Other World') ) => Runs print command on a separate thread task( _() -> print('Hello Other World') ) => Runs print command on a separate thread
foo(a, b) -> print(a+b); task('foo',2,2) => Uses existing function definition to start a task foo(a, b) -> print(a+b); task('foo',2,2) => Uses existing function definition to start a task
task('foo',3,5,'temp'); => runs function foo with a different thread executor, identified as 'temp' task_thread('temp', 'foo',3,5); => runs function foo with a different thread executor, identified as 'temp'
a = 3; task( _(outer(a), b) -> foo(a,b), 5, 'temp') a = 3; task_thread('temp', _(outer(a), b) -> foo(a,b), 5)
=> Another example of running the same thing passing arguments using closure over anonymous function as well as passing a parameter. => Another example of running the same thing passing arguments using closure over anonymous function as well as passing a parameter.
</pre> </pre>
@@ -15,14 +15,24 @@ public class Threading
{ {
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, expression.module, lv, 0, true, false); FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, lv, 0, true, true);
Value queue = Value.NULL; ThreadValue thread = new ThreadValue(Value.NULL, functionArgument.function, expr, tok, c, functionArgument.args);
if (lv.size() > functionArgument.offset) queue = lv.get(functionArgument.offset).evalValue(c); Thread.yield();
return (cc, tt) -> thread;
});
expression.addLazyFunctionWithDelegation("task_thread", -1, (c, t, expr, tok, lv) ->
{
if (lv.size() < 2)
throw new InternalExpressionException("'task' requires at least function to call as a parameter");
Value queue = lv.get(0).evalValue(c);
FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, lv, 1, true, true);
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;
}); });
expression.addFunction("task_count", (lv) -> expression.addFunction("task_count", (lv) ->
{ {
if (lv.size() > 0) if (lv.size() > 0)