// Copyright (c) 2025-2026 GeWuYou
// SPDX-License-Identifier: Apache-2.0
using System;
using System.Collections.Generic;
using GFramework.Core.Abstractions.Coroutine;
using GFramework.Core.Coroutine;
namespace GFramework.Godot.Coroutine;
public partial class Timing
{
///
/// 使用可控时间源初始化当前 实例,供纯托管测试验证宿主阶段语义。
///
/// `Process` 段的增量提供器。
/// `PhysicsProcess` 段的增量提供器。
/// `DeferredProcess` 段的增量提供器。
///
/// 该入口只用于测试宿主驱动顺序,不会挂接真实场景树,也不会暴露给运行时调用方。
/// 由于协程句柄包含实例槽位前缀,这里仍会注册实例槽位,便于沿用生产代码的查询与控制路径。
///
internal void InitializeForTests(
Func? processDeltaProvider = null,
Func? physicsDeltaProvider = null,
Func? deferredDeltaProvider = null)
{
_instanceId = 1;
_ownedCoroutineRegistrations ??= new Dictionary();
_ownedCoroutinesByNode ??= new Dictionary>();
RegisterInstance();
_processTimeSource = new GodotTimeSource(processDeltaProvider ?? DefaultDeltaProvider);
_processRealtimeTimeSource = new GodotTimeSource(processDeltaProvider ?? DefaultDeltaProvider);
_processIgnorePauseTimeSource = new GodotTimeSource(processDeltaProvider ?? DefaultDeltaProvider);
_processIgnorePauseRealtimeTimeSource = new GodotTimeSource(processDeltaProvider ?? DefaultDeltaProvider);
_physicsTimeSource = new GodotTimeSource(physicsDeltaProvider ?? DefaultDeltaProvider);
_physicsRealtimeTimeSource = new GodotTimeSource(physicsDeltaProvider ?? DefaultDeltaProvider);
_deferredTimeSource = new GodotTimeSource(deferredDeltaProvider ?? processDeltaProvider ?? DefaultDeltaProvider);
_deferredRealtimeTimeSource =
new GodotTimeSource(deferredDeltaProvider ?? processDeltaProvider ?? DefaultDeltaProvider);
_processScheduler = new CoroutineScheduler(
_processTimeSource,
_instanceId,
256,
false,
_processRealtimeTimeSource,
CoroutineExecutionStage.Update);
_processIgnorePauseScheduler = new CoroutineScheduler(
_processIgnorePauseTimeSource,
_instanceId,
256,
false,
_processIgnorePauseRealtimeTimeSource,
CoroutineExecutionStage.Update);
_physicsScheduler = new CoroutineScheduler(
_physicsTimeSource,
_instanceId,
128,
false,
_physicsRealtimeTimeSource,
CoroutineExecutionStage.FixedUpdate);
_deferredScheduler = new CoroutineScheduler(
_deferredTimeSource,
_instanceId,
64,
false,
_deferredRealtimeTimeSource,
CoroutineExecutionStage.EndOfFrame);
AttachSchedulerLifecycleHandlers(ProcessScheduler);
AttachSchedulerLifecycleHandlers(ProcessIgnorePauseScheduler);
AttachSchedulerLifecycleHandlers(PhysicsScheduler);
AttachSchedulerLifecycleHandlers(DeferredScheduler);
}
///
/// 以测试宿主的方式推进一次 Process 帧。
///
///
/// 指示当前帧是否视为场景暂停。
/// 暂停时仅推进 `ProcessIgnorePause` 段,并跳过 `DeferredProcess`,以匹配生产宿主逻辑。
///
internal void AdvanceProcessFrameForTests(bool paused)
{
if (!paused)
{
_processScheduler?.Update();
}
_processIgnorePauseScheduler?.Update();
_frameCounter++;
if (!paused)
{
_deferredScheduler?.Update();
}
}
///
/// 以测试宿主的方式推进一次 Physics 帧。
///
internal void AdvancePhysicsFrameForTests()
{
_physicsScheduler?.Update();
}
///
/// 获取指定分段对应的调度器,供测试读取完成状态与快照。
///
/// 目标分段。
/// 对应分段的调度器实例。
internal CoroutineScheduler GetSchedulerForTests(Segment segment)
{
return GetScheduler(segment);
}
///
/// 清理测试初始化留下的实例槽位与调度器状态,避免跨测试污染静态单例表。
/// 仅当当前测试宿主仍持有共享单例引用时才会清理 `_instance`,以免误伤同进程内的其他宿主。
///
internal void DisposeForTests()
{
DetachAllOwnedRegistrations();
ClearOnInstance();
if (_instanceId < ActiveInstances.Length)
{
ActiveInstances[_instanceId] = null;
}
CleanupInstanceIfNecessary(this);
_processScheduler = null;
_processIgnorePauseScheduler = null;
_physicsScheduler = null;
_deferredScheduler = null;
_processTimeSource = null;
_processRealtimeTimeSource = null;
_processIgnorePauseTimeSource = null;
_processIgnorePauseRealtimeTimeSource = null;
_physicsTimeSource = null;
_physicsRealtimeTimeSource = null;
_deferredTimeSource = null;
_deferredRealtimeTimeSource = null;
_frameCounter = 0;
_instanceId = 1;
}
///
/// 提供测试默认使用的稳定帧增量。
///
/// 固定的 60 FPS 增量。
private static double DefaultDeltaProvider()
{
return 1.0 / 60.0;
}
}