diff --git a/docs/main/contents/developer_guides/how_to_guides/coro_guide.md b/docs/main/contents/developer_guides/how_to_guides/coro_guide.md new file mode 100644 index 0000000000..927bfd3956 --- /dev/null +++ b/docs/main/contents/developer_guides/how_to_guides/coro_guide.md @@ -0,0 +1,68 @@ +# Coroutine Guide + +Starting from LeviLamina 1.0.0, coroutines replace the Scheduler. + +## Usage + +1. Include the header files: + ```cpp + #include "ll/api/chrono/GameChrono.h" + #include "ll/api/coro/CoroTask.h" + ``` +2. Call `ll::coro::keepThis` in a function, passing a lambda function that returns `ll::coro::CoroTask`. +3. Call the `launch` or `syncLaunch` method after `keepThis`, the latter will block server thread, passing an `Executor` + class, such as `ll::thread::ServerThreadExecutor`. + +!!! tip "Available Executors" + `ll::thread::ServerThreadExecutor` (ll/api/thread/ServerThreadExecutor.h): Server thread + `ll::thread::ThreadPoolExecutor` (ll/api/thread/ThreadPoolExecutor.h): Thread pool + For more Executors, refer to `ll/api/thread/`. + +## Examples + +### ServerThreadExecutor + +The following function uses a coroutine to print a string to the console every 20 ticks on the server thread, for a total of 20 times. + +```cpp +#include "ll/api/chrono/GameChrono.h" +#include "ll/api/coro/CoroTask.h" +#include "ll/api/thread/ServerThreadExecutor.h" + +void createServerThreadCoro() { + using namespace ll::chrono_literals; + ll::coro::keepThis([]() -> ll::coro::CoroTask<> { + co_await 20_tick; + static int i = 0; + while (i < 20) { + std::cout << "This is coro in server thread\n"; + ++i; + } + co_return; + }).launch(ll::thread::ServerThreadExecutor::getDefault()); +} +``` + +### ThreadPoolExecutor + +The following function uses a coroutine to print a string to the console every second in the thread pool, for a total of 20 times. + +```cpp +#include "ll/api/chrono/GameChrono.h" +#include "ll/api/coro/CoroTask.h" +#include "ll/api/thread/ThreadPoolExecutor.h" + +void createServerThreadCoro() { + using namespace ll::chrono_literals; + ll::coro::keepThis([]() -> ll::coro::CoroTask<> { + co_await 1s; + static int i = 0; + while (i < 20) { + std::cout << "This is coro in server thread\n"; + ++i; + } + co_return; + }).launch(ll::thread::ThreadPoolExecutor::getDefault()); +} +``` + diff --git a/docs/main/contents/developer_guides/how_to_guides/coro_guide.zh.md b/docs/main/contents/developer_guides/how_to_guides/coro_guide.zh.md new file mode 100644 index 0000000000..3d8bbf2da5 --- /dev/null +++ b/docs/main/contents/developer_guides/how_to_guides/coro_guide.zh.md @@ -0,0 +1,67 @@ +# 协程指南 + +从LeviLamina 1.0.0开始,协程替代了Scheduler。 + +## 用法 + +1. 引用头文件 + ```cpp + #include "ll/api/chrono/GameChrono.h" + #include "ll/api/coro/CoroTask.h" + ``` +2. 在函数中调用`ll::coro::keepThis`,传入返回值为`ll::coro::CoroTask`的lambda函数 +3. 在`keepThis`后调用`launch`或`syncLaunch`方法,后者会阻塞服务器线程,传入`Executor`类,比如 + `ll::thread::ServerThreadExecutor` + +!!! tip "可用的Executor" + `ll::thread::ServerThreadExecutor`(ll/api/thread/ServerThreadExecutor.h): 服务器线程 + `ll::thread::ThreadPoolExecutor`(ll/api/thread/ThreadPoolExecutor.h): 线程池 + 更多Executor请参见`ll/api/thread/` + +## 示例 + +### ServerThreadExecutor + +以下函数使用协程实现了在服务器线程每20 tick输出字符串到控制台1次,共计20次。 + +```cpp +#include "ll/api/chrono/GameChrono.h" +#include "ll/api/coro/CoroTask.h" +#include "ll/api/thread/ServerThreadExecutor.h" + +void createServerThreadCoro() { + using namespace ll::chrono_literals; + ll::coro::keepThis([]() -> ll::coro::CoroTask<> { + co_await 20_tick; + static int i = 0; + while (i < 20) { + std::cout << "This is coro in server thread\n"; + ++i; + } + co_return; + }).launch(ll::thread::ServerThreadExecutor::getDefault()); +} +``` + +### ThreadPoolExecutor + +以下函数使用协程实现了在线程池中每秒输出字符串到控制台1次,共计20次。 + +```cpp +#include "ll/api/chrono/GameChrono.h" +#include "ll/api/coro/CoroTask.h" +#include "ll/api/thread/ThreadPoolExecutor.h" + +void createServerThreadCoro() { + using namespace ll::chrono_literals; + ll::coro::keepThis([]() -> ll::coro::CoroTask<> { + co_await 1s; + static int i = 0; + while (i < 20) { + std::cout << "This is coro in server thread\n"; + ++i; + } + co_return; + }).launch(ll::thread::ThreadPoolExecutor::getDefault()); +} +``` \ No newline at end of file diff --git a/docs/main/mkdocs.yml b/docs/main/mkdocs.yml index b26dc59b55..b1c504ac9a 100644 --- a/docs/main/mkdocs.yml +++ b/docs/main/mkdocs.yml @@ -27,6 +27,7 @@ nav: - developer_guides/how_to_guides/i18n_guide.md - developer_guides/how_to_guides/item_guide.md - developer_guides/how_to_guides/command_guide.md + - developer_guides/how_to_guides/coro_guide.md - API 🔗: https://lamina.levimc.org/api diff --git a/src-server/ll/core/Statistics.cpp b/src-server/ll/core/Statistics.cpp index 8da7c25b1c..822305e356 100644 --- a/src-server/ll/core/Statistics.cpp +++ b/src-server/ll/core/Statistics.cpp @@ -1,30 +1,22 @@ #include "ll/core/Statistics.h" - #include "ll/api/Versions.h" #include "ll/api/base/Containers.h" #include "ll/api/chrono/GameChrono.h" #include "ll/api/coro/CoroTask.h" -#include "ll/api/event/EventBus.h" -#include "ll/api/event/server/ServerStartedEvent.h" #include "ll/api/i18n/I18n.h" -#include "ll/api/io/FileUtils.h" #include "ll/api/memory/Hook.h" #include "ll/api/mod/ModManagerRegistry.h" #include "ll/api/service/Bedrock.h" #include "ll/api/service/ServerInfo.h" #include "ll/api/thread/ServerThreadExecutor.h" #include "ll/api/thread/ThreadPoolExecutor.h" -#include "ll/api/utils/ErrorUtils.h" #include "ll/api/utils/RandomUtils.h" -#include "ll/api/utils/StringUtils.h" #include "ll/api/utils/SystemUtils.h" #include "ll/core/LeviLamina.h" - #include "mc/common/BuildInfo.h" #include "mc/common/Common.h" -#include "mc/platform/UUID.h" #include "mc/server/PropertiesSettings.h" #include "mc/world/actor/player/Player.h" #include "mc/world/level/Level.h"