| Browser Concept | This Module |
|---|---|
| Event Loop | Scheduler |
| Task Queue | TaskQueue |
| Task Source | TaskSource |
| Microtask | (未実装、必要に応じて追加) |
| parser-blocking | TaskConstraint::Blocking |
scheduler/
├── README.md # このファイル
├── moon.pkg.json # パッケージ設定
├── pkg.generated.mbti # 生成された型定義
├── task.mbt # Task型定義
├── queue.mbt # TaskQueue管理
├── scheduler.mbt # Scheduler本体
├── html_integration.mbt # HTML Parser統合
├── css_integration.mbt # CSS Cascade統合
├── layout_integration.mbt # LayoutTree統合
└── task_wbtest.mbt # テスト (48テスト)pub(all) enum TaskSource {
DOM // DOM操作(パース、ツリー構築)
Styling // スタイル計算
Layout // レイアウト計算
Networking // リソースフェッチ(外部委譲)
Scripting // スクリプト実行(外部委譲)
ImageDecode // 画像デコード(外部委譲)
}pub(all) enum TaskConstraint {
MainThreadOnly // メインスレッド必須
Parallel // 並列実行可能
Blocking // 他タスクをブロック
}pub(all) enum TaskAction {
// 内部実行可能
ParseHTMLChunk(html~ : String)
ParseCSS(source~ : String)
ComputeStyle(node_ids~ : Array[String])
ComputeLayout
// 外部委譲
FetchResource(url~ : String, resource_type~ : ResourceType)
DecodeImage(resource_id~ : Int)
ExecuteScript(source~ : String)
}// スケジューラ作成
let scheduler = Scheduler::new()
// HTMLパースタスクを追加
let parse_task = scheduler.enqueue(
ParseHTMLChunk(html="<div>...</div>"),
MainThreadOnly,
)
// 発見したリソースのフェッチタスクを追加(パース完了後)
let fetch_task = scheduler.enqueue_after(
FetchResource(url="image.png", resource_type=Image),
[parse_task],
)
// 外部ランタイムがポーリング
loop {
// 並列実行可能なタスクを取得
let parallel_tasks = scheduler.poll_parallel()
// → 外部で並列実行
// メインスレッド専用タスクを取得
let main_tasks = scheduler.poll_ready()
// → 順次実行
// 完了通知
scheduler.complete(task_id, Ok(result))
}┌─────────────────────────────────────────────────────────┐
│ External Runtime │
│ (async runtime, network, script engine, image decoder) │
└─────────────────────────────┬───────────────────────────┘
│
poll_ready() │ complete()
poll_parallel() │
▼
┌─────────────────────────────────────────────────────────┐
│ Scheduler │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ DOM │ │ Styling │ │ Network │ │ Script │ │
│ │ Queue │ │ Queue │ │ Queue │ │ Queue │ │
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
│ │ │
│ ┌───────────────┴───────────────┐ │
│ │ Dependency Graph │ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Internal Modules (sync execution) │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ HTML │ │ CSS │ │ Cascade │ │ Layout │ │
│ │ Parser │ │ Parser │ │ │ │ Tree │ │
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
└─────────────────────────────────────────────────────────┘// ドキュメントパーサ
let parser = DocumentParser::new(scheduler)
let result = parser.on_parse_complete(html)
// result.fetch_tasks - 外部リソースのフェッチタスク
// result.style_tasks - インラインスタイルのパースタスク
// result.script_tasks - スクリプト実行タスク// スタイルマネージャ
let style_manager = StyleManager::new(scheduler)
style_manager.add_stylesheet_source(".foo { color: red; }")
style_manager.add_inline_style("elem1", "margin: 10px")
// スタイル計算
let cascaded = style_manager.compute_style(selector_elem)// レイアウトマネージャ
let layout_manager = LayoutManager::new(scheduler)
layout_manager.build_tree_from_html(doc, 800.0, 600.0)
// レイアウトスケジューリング
let task_id = layout_manager.schedule_layout()
let result = layout_manager.execute_layout()
// 画像リソース管理
let reg = layout_manager.register_and_decode_image(node_uid)
layout_manager.on_image_decoded(reg.resource_id, 640.0, 480.0)HTML Parser → CSS Parser → Style Cascade → Layout Tree
↓ ↓ ↓ ↓
タスク生成 タスク生成 スタイル計算 レイアウト計算
↓ ↓ ↓ ↓
Scheduler が全てのタスクを管理・依存解決・実行順序決定let coordinator = DocumentRenderCoordinator::new(scheduler)
let result = coordinator.process_html(
parse_result, discovered, viewport_width, viewport_height
)
// result.style_ready - スタイル計算準備完了か
// result.layout_task - スケジュールされたレイアウトタスク
// result.image_decode_tasks - 画像デコードタスクpub(all) struct DiscoveredResource {
url : String
resource_type : ResourceType
blocking : Bool
is_defer : Bool
is_async : Bool
}pub struct DocumentParser {
scheduler : Scheduler
parsed_root : Element?
discovered : ResourceDiscoveryResult?
base_url : String
}pub struct DocumentRenderCoordinator {
scheduler : Scheduler
style_coordinator : DocumentStyleCoordinator
layout_manager : LayoutManager
ready_for_render : Bool
}fn DocumentRenderCoordinator::get_style_coordinator(self : DocumentRenderCoordinator) -> DocumentStyleCoordinatorfn DocumentRenderCoordinator::on_stylesheet_fetched(self : DocumentRenderCoordinator, css_source : String) -> CSSParseResultfn DocumentRenderCoordinator::process_html(self : DocumentRenderCoordinator, parse_result : ParseCompleteResult, discovered : ResourceDiscoveryResult, viewport_width : Double, viewport_height : Double) -> RenderPipelineResultpub struct DocumentStyleCoordinator {
scheduler : Scheduler
style_manager : StyleManager
parsed_stylesheets : Int
expected_stylesheets : Int
ready_for_style : Bool
}fn DocumentStyleCoordinator::on_stylesheet_fetched(self : DocumentStyleCoordinator, css_source : String) -> CSSParseResultfn DocumentStyleCoordinator::register_stylesheets(self : DocumentStyleCoordinator, parse_result : ParseCompleteResult, discovered : ResourceDiscoveryResult) -> Unitfn DocumentStyleCoordinator::schedule_style_computation(self : DocumentStyleCoordinator, node_ids : Array[String]) -> TaskIdpub(all) enum FetchResult {
Success(response~ : NetworkResponse)
Redirect(location~ : String, status~ : Int)
Failure(error~ : String)
} derive(Debug)impl Show for FetchResultimpl Show for HttpMethodpub(all) struct ImageRegistration {
resource_id : ResourceId
decode_task : TaskId
registered : Bool
}impl Show for KeyEventTypepub(all) struct KeyboardEvent {
event_type : KeyEventType
key : String
code : String
modifiers : Int
text : String?
timestamp : Double
} derive(Debug)impl Show for KeyboardEventpub struct LayoutManager {
scheduler : Scheduler
layout_tree : LayoutTree?
last_layout : Layout?
full_layout_count : Int
incremental_layout_count : Int
image_tasks : Map[Int, TaskId]
}fn LayoutManager::batch_update_styles(self : LayoutManager, updates : Array[(String, CascadedValues)]) -> Intfn LayoutManager::build_tree(self : LayoutManager, root : Node, viewport_width : Double, viewport_height : Double) -> Unitfn LayoutManager::build_tree_from_html(self : LayoutManager, doc : Document, viewport_width : Double, viewport_height : Double) -> Unitfn LayoutManager::on_image_decoded(self : LayoutManager, resource_id : ResourceId, width : Double, height : Double) -> TaskId?fn LayoutManager::register_and_decode_image(self : LayoutManager, node_uid : Int, placeholder_width? : Double, placeholder_height? : Double) -> ImageRegistrationfn LayoutManager::schedule_layout_after(self : LayoutManager, dependencies : Array[TaskId]) -> TaskIdfn LayoutManager::schedule_resize(self : LayoutManager, width : Double, height : Double) -> ResizeResultfn LayoutManager::update_node_style(self : LayoutManager, node_id : String, values : CascadedValues) -> Boolpub(all) struct LayoutStats {
full_layout_count : Int
incremental_layout_count : Int
pending_images : Int
}impl Show for MouseButtonpub(all) struct MouseEvent {
event_type : MouseEventType
x : Double
y : Double
button : MouseButton
buttons : Int
click_count : Int
modifiers : Int
timestamp : Double
} derive(Debug)impl Show for MouseEventimpl Show for MouseEventTypepub(all) enum NetworkEvent {
RequestWillBeSent(NetworkRequest)
ResponseReceived(NetworkResponse)
LoadingFinished(request_id~ : RequestId, encoded_data_length~ : Int)
LoadingFailed(request_id~ : RequestId, error~ : String)
} derive(Debug)impl Show for NetworkEventpub struct NetworkManager {
pending_requests : Map[Int, NetworkRequest]
pending_events : Array[NetworkEvent]
enabled : Bool
}fn NetworkManager::fail_loading(self : NetworkManager, request_id : RequestId, error : String) -> Unitfn NetworkManager::finish_loading(self : NetworkManager, request_id : RequestId, encoded_data_length : Int) -> Unitpub(all) struct NetworkRequest {
id : RequestId
url : String
http_method : HttpMethod
resource_type : ResourceType
headers : Map[String, String]
document_url : String
frame_id : String
loader_id : String
timestamp : Double
} derive(Debug)impl Show for NetworkRequestfn NetworkRequest::new(url : String, resource_type : ResourceType, document_url? : String, frame_id? : String, http_method? : HttpMethod) -> NetworkRequestfn NetworkRequest::with_headers(self : NetworkRequest, headers : Map[String, String]) -> NetworkRequestimpl Show for NetworkResponsefn NetworkResponse::with_headers(self : NetworkResponse, headers : Map[String, String]) -> NetworkResponsepub(all) struct ResourceDiscoveryResult {
resources : Array[DiscoveredResource]
inline_styles : Array[String]
inline_scripts : Array[InlineScript]
}fn ResourceDiscoveryResult::filter_by_type(self : ResourceDiscoveryResult, resource_type : ResourceType) -> Array[DiscoveredResource]fn ResourceDiscoveryResult::get_blocking(self : ResourceDiscoveryResult) -> Array[DiscoveredResource]impl Show for ResourceTypepub struct Scheduler {
tasks : Map[Int, Task]
ready_queue : TaskQueue
source_queues : SourceQueueManager
blocked : BlockedSources
completed_ids : HashSet[Int]
}fn Scheduler::enqueue_after(self : Scheduler, action : TaskAction, constraint : TaskConstraint, dependencies : Array[TaskId]) -> TaskIdfn Scheduler::enqueue_with_priority(self : Scheduler, action : TaskAction, constraint : TaskConstraint, priority : Int) -> TaskIdfn SourceQueueManager::get_ready_by_source(self : SourceQueueManager, source : TaskSource) -> Array[Task]pub struct StyleManager {
scheduler : Scheduler
stylesheets : Array[Stylesheet]
inline_styles : Map[String, Array[Declaration]]
computed_styles : Map[String, CascadedValues]
source_order : Int
}fn StyleManager::add_inline_style(self : StyleManager, element_id : String, style_text : String) -> Unitpub(all) struct Task {
id : TaskId
source : TaskSource
constraint : TaskConstraint
dependencies : Array[TaskId]
action : TaskAction
state : TaskState
priority : Int
}fn Task::new(action : TaskAction, constraint : TaskConstraint, dependencies? : Array[TaskId], priority? : Int) -> Taskpub(all) enum TaskAction {
ParseHTMLChunk(html~ : String)
ParseCSS(source~ : String)
ComputeStyle(node_ids~ : Array[String])
ComputeLayout
FetchResource(url~ : String, resource_type~ : ResourceType)
DecodeImage(resource_id~ : Int)
ExecuteScript(source~ : String)
} derive(Debug)impl Show for TaskActionimpl Show for TaskConstraintpub(all) enum TaskResult {
Success(new_tasks~ : Array[TaskAction])
Failure(error~ : String)
Cancelled
} derive(Debug)impl Show for TaskResultfn parse_and_schedule(scheduler : Scheduler, html : String, base_url? : String) -> ParseCompleteResultfn reset_request_id_counter() -> UnitDOM, HTML, AOM, and scheduling packages for crater
Dependencies