メインコンテンツへスキップ

コア概念

Zylix の技術的な基盤を理解するためのコア概念を解説します。

用語
#

  • State: Zig が保持するアプリ全体の状態。
  • Event: UI から送る型付きアクション。
  • VNode: 仮想 UI ツリーのノード。
  • Diff: 旧新ツリー間の差分。

概念
#

Zylix は 4 つの主要コンポーネントで構成されています:

flowchart TB
    User["👆 ユーザー操作<br/>(タップ、クリック、入力、スクロール)"]

    subgraph Shell1["プラットフォームシェル (Swift, Kotlin, JS, C#, C)"]
        Convert["ネイティブイベントを Zylix イベントに変換"]
        Call["呼び出し: zylix_dispatch(event_type, payload)"]
    end

    subgraph Dispatcher["イベントディスパッチャ"]
        Route["イベントを適切なハンドラにルーティング"]
        Validate["イベントペイロードを検証"]
    end

    subgraph Store["状態ストア"]
        Transition["状態遷移を適用"]
        Version["バージョン番号を増加"]
        Trigger["再レンダリングをトリガー"]
    end

    subgraph Builder["Virtual DOM ビルダー"]
        Construct["状態から新しい VNode ツリーを構築"]
        Render["コンポーネントレンダー関数を使用"]
    end

    subgraph Differ["差分アルゴリズム"]
        Compare["旧ツリーと新ツリーを比較"]
        Generate["最小限のパッチセットを生成"]
    end

    subgraph Shell2["プラットフォームシェル"]
        Receive["zylix_get_patches() でパッチを受信"]
        Apply["ネイティブ UI 要素にパッチを適用"]
    end

    Updated["✨ UI 更新完了<br/>ユーザーが変更を確認"]

    User --> Shell1
    Shell1 --> Dispatcher
    Dispatcher --> Store
    Store --> Builder
    Builder --> Differ
    Differ --> Shell2
    Shell2 --> Updated

実装
#

コア概念
#

設計原則
#

1. 不変性 (Immutability)
#

状態と Virtual DOM ノードは不変です。変更は新しいバージョンの作成を意味します。

// 状態は直接変更されず、新しいバージョンが作成される
const old_version = state.getVersion();
handleIncrement();
const new_version = state.getVersion();
// new_version == old_version + 1

2. 型安全 (Type Safety)
#

Zig のコンパイル時型チェックにより、ランタイムエラーを防ぎます。

// 判別共用体による型安全なイベント
pub const Event = union(enum) {
    todo_add: []const u8,   // 文字列ペイロード
    todo_toggle: u32,        // ID ペイロード
    todo_clear_completed,    // ペイロードなし
};

3. ゼロアロケーション (Zero Allocation)
#

ホットパスではヒープアロケーションを行いません。

// アリーナアロケーションで予測可能なパフォーマンス
var arena = Arena(4096).init();
defer arena.reset();

// すべてのアロケーションはアリーナから
const nodes = arena.alloc(VNode, 100);

4. 単一責任 (Single Responsibility)
#

各モジュールは明確な責任を持ちます。

モジュール責任
vdom.zigVirtual DOM ツリーの構築と管理
diff.zig旧新ツリーの比較とパッチ生成
state.zigアプリケーション状態の管理
events.zigイベント定義と処理
abi.zigC ABI エクスポート

アーキテクチャパターン
#

Elm アーキテクチャ
#

Zylix は Elm アーキテクチャ(Model-View-Update)に基づいています:

flowchart TB
    subgraph Elm["Elm アーキテクチャ"]
        Model["Model<br/>(状態)"]
        View["View<br/>(描画)"]
        Update["Update<br/>(更新)"]
        Message["Message<br/>(イベント)"]

        Model --> View
        Model --> Update
        Message --> Update
        Update --> Model
        View --> Message
    end
  • Model: 不変のアプリケーション状態
  • View: 状態から UI を構築
  • Update: イベントに基づいて状態を更新
  • Message: ユーザーアクションや外部イベント

パフォーマンス特性
#

操作計算量説明
ノード作成O(1)バンプアロケーション
ツリー差分O(n)線形時間比較
キー付きリストO(n)ハッシュマップによる最適化
状態更新O(1)直接代入
イベント処理O(1)switch 文による分岐

メモリ使用量
#

コンポーネントサイズ
VNode64 bytes
VTree (1000 ノード)~64 KB
AppState~4 KB
Arena (デフォルト)4 KB

落とし穴
#

  • 初期化前の状態参照は無効になります。
  • ABI ポインタを保持し続けると参照が壊れます。
  • key の不安定さは diff のズレを起こします。

次のステップ
#

各コア概念の詳細については、以下のページを参照してください:

Virtual DOM

·5 分
Virtual DOM は Zylix の UI レンダリングエンジンの核心です。実際の DOM/ネイティブ UI の軽量な仮想表現を構築し、効率的な差分検出により最小限の更新を実現します。 用語 # VNode: 仮想 UI ツリーのノード。 Diff: 2つのツリー間の差分。 Patch: 実際の UI に適用する更新操作。 概念 # ┌─────────────────────────────────────────────────────────────────┐ │ Virtual DOM ワークフロー │ │ │ │ 状態変更 ──▶ 新 VTree 構築 ──▶ 差分検出 ──▶ パッチ適用 │ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ State │ │ VTree │ │ Diff │ │ Native │ │ │ │ v1 → v2 │ ──▶ │ Build │ ──▶ │ Compare │ ──▶ │ UI │ │ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │ │ └─────────────────────────────────────────────────────────────────┘ 実装 # VNode 構造体 # VNode は仮想 DOM の基本単位です。

状態管理

·5 分
Zylix は集中型のバージョン追跡付き状態管理を採用しています。すべてのアプリケーション状態は Zig で管理され、プラットフォームシェルには読み取り専用で公開されます。 用語 # State: Zig が保持するアプリ全体の状態。 Version: 変更ごとに増える単調増加カウンタ。 Diff: 変更点を示す差分マスク。 Store: 現在/過去の状態を保持するジェネリックコンテナ。 概念 # 設計原則 # 単一の信頼源: グローバルストアがすべてのアプリケーションデータを所有 不変更新: 状態遷移は新しいバージョンを作成 バージョン追跡: すべての変更にバージョン番号を割り当て 差分検出: 変更を追跡して効率的なレンダリングを実現 実装 # アプリケーション状態 # pub const AppState = struct { /// カウンター値 counter: i64 = 0, /// フォーム入力 input_text: [256]u8 = [_]u8{0} ** 256, input_len: usize = 0, /// Todo アイテム todos: [MAX_TODOS]Todo = undefined, todo_count: usize = 0, /// 現在のフィルター filter: Filter = .all, /// ビューデータポインタを取得(ABI 用) pub fn getViewData(self: *const AppState) ?*const anyopaque { return @ptrCast(self); } /// ビューデータサイズを取得(ABI 用) pub fn getViewDataSize(_: *const AppState) usize { return @sizeOf(AppState); } }; pub const Todo = struct { id: u32, text: [128]u8, text_len: usize, completed: bool, }; pub const Filter = enum(u8) { all = 0, active = 1, completed = 2, }; UI 状態 # pub const UIState = struct { /// 現在の画面 screen: Screen = .home, /// ローディング状態 loading: bool = false, pub const Screen = enum(u32) { home = 0, detail = 1, settings = 2, }; }; 統合状態 # pub const State = struct { /// 状態バージョン(単調増加) version: u64 = 0, /// アプリケーション固有の状態 app: AppState = .{}, /// UI 状態ヒント ui: UIState = .{}, /// 最後のエラーメッセージ last_error: ?[]const u8 = null, /// 状態変更後にバージョンを増加 pub fn bumpVersion(self: *State) void { self.version +%= 1; } }; ジェネリックストア # Store は型安全な状態管理を提供します。

コンポーネント

·6 分
コンポーネントは Zylix の再利用可能な UI 構成要素です。構造、スタイル、動作をカプセル化し、任意のプラットフォームにレンダリングできる合成可能なユニットです。 用語 # Component: ボタンやテキストなどの UI 要素。 Props: コンポーネントを設定するデータ。 State: hover や checked などの状態フラグ。 概念 # コンポーネントはデータとして表現され、各プラットフォームのレンダラがネイティブ UI に変換します。 実装 # コンポーネントタイプ # Zylix は一般的な UI 要素用の組み込みコンポーネントタイプを提供します。

イベントシステム

·6 分
Zylix は型安全なイベントシステムを使用してユーザーインタラクションを処理します。イベントはプラットフォームシェルからコアを通じて流れ、状態変更と UI 更新をトリガーします。 用語 # Event: UI から Zig コアに送る型付きアクション。 Dispatch: イベントをハンドラへルーティングする ABI 呼び出し。 Payload: イベントに付随するデータ。 概念 # イベントアーキテクチャ # sequenceDiagram participant User as ユーザー participant Shell as プラットフォームシェル participant Core as Zylix Core (Zig) participant Handler as イベントハンドラ participant State as 状態更新 User->>Shell: ボタンタップ Note over Shell: Zylix イベントに変換 Shell->>Core: zylix_dispatch(EVENT_TODO_ADD, "買い物", 6) Note over Core: イベントタイプを検証 Note over Core: ペイロードを解析 Note over Core: ハンドラにルーティング Core->>Handler: イベントをディスパッチ Note over Handler: switch (event) {<br/> .todo_add => addTodo(text),<br/> .todo_toggle => toggleTodo(id),<br/>} Handler->>State: 状態を更新 Note over State: state.todos[id].completed = true<br/>state.version += 1<br/>scheduleRender() State-->>Core: 結果コード Core-->>Shell: 結果を返す 実装 # イベントタイプ # 組み込みイベント # Zylix は UI インタラクション用の一般的なイベントタイプを提供します。