///|
/// 仿真环境状态
pub(all) enum EnvStatus {
Initialized
Running
Finished
} derive(Debug, Eq, ToJson)
///|
/// 从 JSON 反序列化 EnvStatus
pub impl FromJson for EnvStatus with fn from_json(json, path) {
match json {
Json::String(s) =>
match s {
"Initialized" => Initialized
"Running" => Running
"Finished" => Finished
_ =>
raise @json.JsonDecodeError::JsonDecodeError(
(path, "unknown EnvStatus"),
)
}
_ => raise @json.JsonDecodeError::JsonDecodeError((path, "expected string"))
}
}
///|
/// 全局仿真环境
///
/// 管理虚拟仿真时钟、事件队列和主仿真循环。
/// 内核完全无全局可变共享状态,天然支持多实例并行仿真。
/// 支持插件钩子:on_step / on_event / on_finish,由 plugin::attach 设置。
pub(all) struct SimulationEnv {
mut now : Double
until : Double
queue : EventQueue
mut status : EnvStatus
mut next_event_id : EventId
mut next_process_id : ProcessId
// 事件注册表:id -> Event
events : Map[EventId, Event]
// 插件钩子(由 plugin::attach 设置)
mut on_step_hook : ((SimulationEnv, Double) -> Unit)?
mut on_event_hook : ((SimulationEnv, Event) -> Unit)?
mut on_finish_hook : ((SimulationEnv) -> Unit)?
}
///|
/// 创建仿真环境,指定仿真终止时间
///
/// # Example
/// ```mbt check
/// test {
/// let env = @core.new_env(until=100.0)
/// inspect(env.now(), content="0")
/// inspect(env.until, content="100")
/// }
/// ```
pub fn new_env(until~ : Double) -> SimulationEnv {
{
now: 0.0,
until,
queue: new_queue(),
status: Initialized,
next_event_id: 0,
next_process_id: 0,
events: Map([]),
on_step_hook: None,
on_event_hook: None,
on_finish_hook: None,
}
}
///|
/// 获取当前仿真时间
pub fn SimulationEnv::now(self : SimulationEnv) -> Double {
self.now
}
///|
/// 仿真是否已结束
pub fn SimulationEnv::is_finished(self : SimulationEnv) -> Bool {
self.status is Finished
}
///|
/// 分配新的事件 ID
pub fn SimulationEnv::_alloc_event_id(self : SimulationEnv) -> EventId {
let id = self.next_event_id
self.next_event_id = id + 1
id
}
///|
/// 分配新的进程 ID
pub fn SimulationEnv::_alloc_process_id(self : SimulationEnv) -> ProcessId {
let id = self.next_process_id
self.next_process_id = id + 1
id
}
///|
/// 调度一个事件在指定时间触发
///
/// 返回创建的事件对象,可用于后续等待或取消。
pub fn SimulationEnv::schedule(
self : SimulationEnv,
time~ : Double,
priority? : EventPriority = 0,
callback~ : () -> Unit,
) -> Event {
let id = self._alloc_event_id()
let event = new_event(id~, time~, priority~, callback~)
self.events[id] = event
self.queue.push(event)
event
}
///|
/// 创建一个超时事件:在当前时间 + duration 后触发
///
/// # Example
/// ```mbt check
/// test {
/// let env = @core.new_env(until=10.0)
/// let ev = env.timeout(5.0)
/// inspect(ev.time, content="5")
/// inspect(ev.is_pending(), content="true")
/// }
/// ```
pub fn SimulationEnv::timeout(self : SimulationEnv, duration : Double) -> Event {
self.schedule(time=self.now + duration, callback=() => ())
}
///|
/// 注册事件到环境(供外部创建的 Event 加入队列)
pub fn SimulationEnv::_register_event(
self : SimulationEnv,
event : Event,
) -> Unit {
self.events[event.id] = event
self.queue.push(event)
}
///|
/// 按事件 ID 查找事件
pub fn SimulationEnv::get_event(self : SimulationEnv, id : EventId) -> Event? {
self.events.get(id)
}
///|
/// 设置 on_step 钩子(每个事件处理前调用)
pub fn SimulationEnv::_set_on_step_hook(
self : SimulationEnv,
hook : ((SimulationEnv, Double) -> Unit)?,
) -> Unit {
self.on_step_hook = hook
}
///|
/// 设置 on_event 钩子(事件触发后调用)
pub fn SimulationEnv::_set_on_event_hook(
self : SimulationEnv,
hook : ((SimulationEnv, Event) -> Unit)?,
) -> Unit {
self.on_event_hook = hook
}
///|
/// 设置 on_finish 钩子(仿真结束时调用)
pub fn SimulationEnv::_set_on_finish_hook(
self : SimulationEnv,
hook : ((SimulationEnv) -> Unit)?,
) -> Unit {
self.on_finish_hook = hook
}
///|
/// 触发 on_step 钩子
fn SimulationEnv::_fire_on_step(self : SimulationEnv) -> Unit {
match self.on_step_hook {
Some(hook) => hook(self, self.now)
None => ()
}
}
///|
/// 触发 on_event 钩子
fn SimulationEnv::_fire_on_event(self : SimulationEnv, event : Event) -> Unit {
match self.on_event_hook {
Some(hook) => hook(self, event)
None => ()
}
}
///|
/// 触发 on_finish 钩子(仅一次)
fn SimulationEnv::_fire_on_finish(self : SimulationEnv) -> Unit {
match self.on_finish_hook {
Some(hook) => hook(self)
None => ()
}
}
///|
/// 结束仿真:调用 on_finish 钩子并设置状态(保证仅一次)
fn SimulationEnv::_finish(self : SimulationEnv) -> Unit {
if !(self.status is Finished) {
self._fire_on_finish()
self.status = Finished
}
}
///|
/// 主仿真循环:按时间顺序处理所有事件直到队列为空或到达终止时间
///
/// # Example
/// ```mbt check
/// test {
/// let env = @core.new_env(until=10.0)
/// let log : Array[String] = []
/// ignore(env.schedule(time=2.0, callback=fn() { log.push("A") }))
/// ignore(env.schedule(time=1.0, callback=fn() { log.push("B") }))
/// env.run()
/// assert_eq(log[0], "B")
/// assert_eq(log[1], "A")
/// }
/// ```
pub fn SimulationEnv::run(self : SimulationEnv) -> Unit {
self.status = Running
while !self.queue.is_empty() {
match self.queue.pop() {
Some(event) =>
match event.status {
Pending => {
if event.time > self.until {
self.now = self.until
break
}
self.now = event.time
self._fire_on_step()
event.trigger()
self._fire_on_event(event)
}
_ => continue
}
None => break
}
}
if self.now != self.until {
self.now = self.until
}
self._finish()
}
///|
/// 单步推进:处理下一个事件(用于调试和插件控制)
pub fn SimulationEnv::step(self : SimulationEnv) -> Bool {
while !self.queue.is_empty() {
match self.queue.pop() {
Some(event) =>
match event.status {
Pending => {
if event.time > self.until {
self.now = self.until
self._finish()
return false
}
self.now = event.time
self._fire_on_step()
event.trigger()
self._fire_on_event(event)
return true
}
_ => continue
}
None => {
self._finish()
return false
}
}
}
self._finish()
false
}
///|
/// 环境状态快照(用于断点回滚)
///
/// 捕获仿真环境的可变状态,可通过 `restore` 恢复。
/// 注意:仅恢复时钟、状态、ID 计数器,不恢复事件队列与回调。
pub(all) struct EnvSnapshot {
now : Double
status : EnvStatus
next_event_id : EventId
next_process_id : ProcessId
} derive(Debug, Eq, ToJson)
///|
/// 从 JSON 反序列化 EnvSnapshot
pub impl FromJson for EnvSnapshot with fn from_json(json, path) {
match json {
Json::Object(map) =>
{
now: @json.from_json(map["now"], path=path.add_key("now")),
status: @json.from_json(map["status"], path=path.add_key("status")),
next_event_id: @json.from_json(
map["next_event_id"],
path=path.add_key("next_event_id"),
),
next_process_id: @json.from_json(
map["next_process_id"],
path=path.add_key("next_process_id"),
),
}
_ => raise @json.JsonDecodeError::JsonDecodeError((path, "expected object"))
}
}
///|
/// 获取已注册的事件总数
pub fn SimulationEnv::event_count(self : SimulationEnv) -> Int {
self.events.length()
}
///|
/// 捕获环境当前状态快照
pub fn SimulationEnv::snapshot(self : SimulationEnv) -> EnvSnapshot {
{
now: self.now,
status: self.status,
next_event_id: self.next_event_id,
next_process_id: self.next_process_id,
}
}
///|
/// 从快照恢复环境状态
///
/// 恢复时钟、状态、ID 计数器。事件队列与回调不恢复。
pub fn SimulationEnv::restore(self : SimulationEnv, snap : EnvSnapshot) -> Unit {
self.now = snap.now
self.status = snap.status
self.next_event_id = snap.next_event_id
self.next_process_id = snap.next_process_id
}