Merge branch 'master' of https://github.com/gnembon/fabric-carpet
This commit is contained in:
commit
70db85ca9f
1 file changed
+27
-16
+27
-16
@@ -762,15 +762,15 @@ str('player at: %d %d %d',pos(player())) => 'player at: 567, -2423, 124'
|
||||
* * *
|
||||
## Threading and Parallel Execution
|
||||
|
||||
Scarpet allows to run threads of execution in parallel to the main script execution thread. In Minecraft, the main
|
||||
thread scripts are executed on the main server thread. Since Minecraft is inherently NOT thread safe, it is not that
|
||||
beneficial to parallel execution in order to access world resources faster. Both `GetBlockState` and `setBlockState`
|
||||
Scarpet allows to run threads of execution in parallel to the main script execution thread. In Minecraft, apps
|
||||
are executed on the main server thread. Since Minecraft is inherently NOT thread safe, it is not that
|
||||
beneficial to parallel execution in order to access world resources faster. Both `getBlockState` and `setBlockState`
|
||||
are not thread safe and require the execution to park on the server thread, where these requests can be executed in
|
||||
the off-tick time in between ticks that didn't take 50ms. There are however benefits of running things in parallel,
|
||||
the off-tick time in between ticks that didn't take all 50ms. There are however benefits of running things in parallel,
|
||||
like fine time control not relying on the tick clock, or running things independent on each other. You can still run
|
||||
your actions on tick-by-tick basis, either taking control of the execution using `game_tick()` API function
|
||||
(nasty solution), or scheduling tick using `schedule()` function (much nicer solution), but threading often gives
|
||||
the neatest solution to solve problems in parallel
|
||||
(nasty solution), or scheduling tick using `schedule()` function (preffered solution), but threading gives much more control
|
||||
on the timings without impacting the main game and is the only solution to solve problems in parallel
|
||||
(see [scarpet camera](/src/main/resources/assets/carpet/scripts/camera.sc)).
|
||||
|
||||
Due to limitations with the game, there are some limits to the threading as well. You cannot for
|
||||
@@ -778,9 +778,11 @@ instance `join_task()` at all from the main script and server thread, because an
|
||||
function that require any world access, will require to park and join on the main thread to get world access,
|
||||
meaning that calling join on that task would inevitably lead to a typical deadlock. You can still join tasks
|
||||
from other threads, just because the only possibility of a deadlock in this case would come explicitly from your
|
||||
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 players or entities manipulation, can be
|
||||
effectively parallelized.
|
||||
|
||||
If the app is shutting down, creating new tasks via `task`
|
||||
|
||||
### `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
|
||||
@@ -799,6 +801,24 @@ 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.
|
||||
</pre>
|
||||
|
||||
### `sleep()` `sleep(timeout)`, `sleep(timeout, close_call, ... args)`
|
||||
|
||||
|
||||
Halts the execution of the thread (or the game itself, if run not as a part of a task) for `expr` milliseconds.
|
||||
It checks for interrupted execution, in that case exits the thread (or the entire program, if not run on a thread) in case the app
|
||||
is being stopped/removed. If the closing call is specified, executes the following function when a shutdown signal is triggered.
|
||||
If run on the main thread (not as a taks) the call may only be invocated when the entire game shuts down, so close call only
|
||||
makes sense for threads. For programs use `__on_close()` handler.
|
||||
|
||||
Since `close_call` is executed after app shutdown is initiated, you won't be able to create new tasks in that block. Threads
|
||||
should periodically call `sleep` to ensure all app tasks will finish when the app is closing or right after, but the app engine
|
||||
will not forcefully remove your running tasks so the tasks themselves need to properly react to the closing request.
|
||||
|
||||
<pre>
|
||||
sleep(50) # wait for 50 milliseconds
|
||||
sleep(1000, _() -> print('Interrupted')) # waits for 1 second, outputs a message when thread is shut down.
|
||||
</pre>
|
||||
|
||||
### `task_count(executor?)`
|
||||
|
||||
If no argument provided, returns total number of tasks being executed in parallel at this moment using scarpet
|
||||
@@ -936,15 +956,6 @@ print('pi = '+pi) => prints: pi = 3.141592653589793
|
||||
print(str('pi = %.2f',pi)) => prints: pi = 3.14
|
||||
</pre>
|
||||
|
||||
### `sleep(expr)`
|
||||
|
||||
Halts the execution of the program (and the game itself) for `expr` milliseconds. All in all, its better to
|
||||
use `game_tick(expr)` to let the game do its job while the program waits
|
||||
|
||||
<pre>
|
||||
sleep(50)
|
||||
</pre>
|
||||
|
||||
### `time()`
|
||||
|
||||
Returns the number of milliseconds since 'some point', like Java's `System.nanoTime()`, which varies from system to
|
||||
|
||||
Reference in new issue
Block a user