Repository navigation
Start Stop
事件处理函数和定时任务都是长期运行的——它们定义之后一直等在那里,直到被触发。HimDSL 用 start 和 stop 控制它们的活跃状态。
Event handlers and scheduled tasks are long-running — after definition they wait until triggered. HimDSL uses start and stop to control their active state.
-
未启动:定义了但不生效。
-
已启动:可被事件或调度触发。
-
已停止:和未启动一样,不再被触发。
-
Not started: defined but inactive.
-
Started: triggers fire.
-
Stopped: inactive again.
start("函数名");
参数是函数名的字符串。这与调用普通函数不同——普通函数写 foo(),这里写 start("foo")。
The argument is the function name as a string — unlike ordinary calls (foo()), you write start("foo").
@EventHandler
void onJoin(event(PlayerJoinEvent)) { ... }
@BukkitRunnable
void tick() sche = 10s { ... }
int main() {
start("onJoin");
start("tick");
}
start 是幂等的吗? 不是。启动一个已经在运行的任务会报错:
Is start idempotent? No — starting an already-running task errors:
start("tick");
start("tick"); // ✗ 报错:已启用
先 stop 再 start 可以重新启动。
stop then start restarts.
stop("函数名");
停止后不再被触发,但函数定义依然存在——可以再次 start。
After stopping, no more triggers, but the definition remains — start again to resume.
@BukkitRunnable
void tick() sche = 10s { ... }
int main() {
start("tick");
// 后面某处
if (someCondition) {
stop("tick");
}
}
停止一个未启动的任务会报错。
Stopping a non-started task errors.
启动由脚本自身决定。可以根据环境、时间、配置选择要不要启动:
Start is decided by the script itself — based on environment, time, or config:
int main() {
var players = @a;
if (players.size() > 0) {
start("onJoin");
runcmd("CONSOLE", "say 已在服务器有人时启动监听");
}
}
定时任务可以执行完自己停:
A scheduled task can stop itself:
int counter;
@BukkitRunnable
void countdown() sche = 1s {
counter += 1;
runcmd("CONSOLE", "say 倒计时 " + (10 - counter));
if (counter >= 10) {
stop("countdown");
runcmd("CONSOLE", "say 倒计时结束");
counter = 0;
}
}
int main() {
counter = 0;
start("countdown");
}
stop("countdown") 在任务自己内部调用是合法的,会停止后续触发。
Calling stop("countdown") inside the task itself is valid and stops further firing.
一个常驻的监听器控制另一个任务:
A long-lived listener toggles another task:
bool fastMode = false;
@BukkitRunnable
void slowTick() sche = 30s {
runcmd("CONSOLE", "say 慢速检查");
}
@BukkitRunnable
void fastTick() sche = 5s {
runcmd("CONSOLE", "say 快速检查");
}
@EventHandler
void onCommand(event(PlayerCommandPreprocessEvent)) {
player p = @s;
string cmd = event.getMessage();
if (cmd.equalsIgnoreCase("/fastmode on")) {
if (!fastMode) {
stop("slowTick");
start("fastTick");
fastMode = true;
runcmd(p.name, "msg 快速模式已开启");
}
}
}
int main() {
start("slowTick");
start("onCommand");
}
脚本重载时(重新执行 /himdsl run),之前启动的事件和任务会先被清理,然后新版本重新执行。这意味着:
When a script reloads (running /himdsl run again), previously started events and tasks are cleared first, then the new version runs:
-
不需要手动
stop旧的任务。 -
变量状态会丢失——
counter之类的计数会重置。 -
数据持久化要靠文件(
fwritelines/freadlines)。 -
No manual
stopneeded for old tasks. -
Variable state is lost — counters reset.
-
Persist data through files (
fwritelines/freadlines).
如果你想保留状态,把状态写进文件,脚本启动时读回。
To keep state across restarts, save to a file and load it at startup.
start 要求函数唯一。如果脚本里有多个同名函数(重载),start 会报"存在重载,无法启动"。
start requires a unique function. With overloaded names, start errors.
void tick() { ... }
void tick(int n) { ... }
int main() {
start("tick"); // ✗ 有重载
}
事件函数和定时任务不要重载。给它们取独特的名字。
Do not overload event handlers or scheduled tasks. Give them unique names.
-
start("name")启动,stop("name")停止。 -
参数是函数名的字符串。
-
启动已启动的、停止未启动的,都会报错。
-
任务可以自己
stop自己。 -
脚本重载会清理所有事件和任务,变量状态丢失。
-
状态持久化用文件。
-
事件和任务函数不要重载。
-
start("name")/stop("name"). -
Argument is a function name as a string.
-
Starting already-started or stopping non-started errors.
-
Tasks can
stopthemselves. -
Reload clears tasks; variable state is lost.
-
Persist via files.
-
Do not overload event/task functions.
事件与调度部分到此结束。五章覆盖了:@EventHandler 注解、事件类型解析、EventWrapper 数据访问、@BukkitRunnable 定时任务、start / stop 生命周期。
The Events & Scheduling section ends here. Five chapters covered: @EventHandler, event type resolution, EventWrapper, @BukkitRunnable, and start / stop.
选择原则:
Decision guide:
-
响应玩家动作 →
@EventHandler。 -
周期性工作 →
@BukkitRunnable+sche。 -
一次性延迟 →
@BukkitRunnable不带sche。 -
启动/停止 → 用
start/stop,不要指望脚本重载自动管理。 -
React to player actions →
@EventHandler. -
Periodic work →
@BukkitRunnablewithsche. -
One-shot delay →
@BukkitRunnablewithoutsche. -
Lifecycle →
start/stop, not reload-based automation.
下一部分进入 GUI 系统。第十章 [创建 GUI / Creating-GUI] 从 new GUI(rows, title) 开始。
The next part covers the GUI system. Chapter [创建 GUI / Creating-GUI] starts with new GUI(rows, title).
- 首页 / Home
- 安装与快速开始 / Installation & Quick Start
- 第一个脚本 / Your First Script
- 命令速查 / Command Reference
- 自动执行脚本 / Auto-run Scripts
- 定义函数 / Defining Functions
- 函数重载 / Function Overloading
- Lambda 表达式 / Lambda Expressions
- 函数式接口 / Functional Interfaces
- 选择器总览 / Selectors Overview
- 选择器过滤器 / Selector Filters
- EntityRef 引用 / EntityRef
- 占位符参考 / Placeholders Reference
- PlaceholderAPI 桥接 / PAPI Bridge
- 创建 GUI / Creating a GUI
- GUISlot 槽位 / GUISlot
- 点击回调 / Click Callbacks
- onClose 回调 / onClose Callback
- GUI 刷新 / GUI Refresh
- 数学函数 / Math Built-ins
- 高精度计算 / BigDecimal Built-ins
- 字符串函数 / String Built-ins
- 集合函数 / Collection Built-ins
- 文件 I/O / File I/O
- 命令与 sleep / Commands & sleep