rrbox / GameWidget

A simple UI layout tools for SpriteKit
MIT License
3 stars 0 forks source link

`createModels()` で UI オブジェクトを生成する #66

Closed rrbox closed 1 year ago

rrbox commented 1 year ago

現段階の GameWidget が提供している API は「レイアウト」です。この「レイアウト」はデータ(単なる情報の集まり)として機能するようにこだわっています。ところが、node() で SKNode を生成する手順は Builder パターンの仕様であり、「レイアウト」の挙動ではないように見えます。したがってプログラマはこの API を見て「レイアウト」とはわかりづらいかもしれません。

let layout = Display()
    .place {
        Button(.init("button_0"))
        Button(.init("button_1"))
            .modifiable
            .position(CGPoint(x: 0, y: -50))
    }

let node = layout.node()    // これは " レイアウト " としてわかりやすいのか?

Widget を引数として受け取って SKNode にするようなメソッドに変更した方がいいかもしれません。もちろん別の名前空間内か、別のオブジェクト(例えば SKNode に直接など)に定義するはずです。

extension SKNode {
    // 一例です。多分この命名もちょっとおかしいかもです。
    static func applying<T: Widget>(widget: T) -> SKNode {
        return widget.node()
    }
}

let layout = Display()
    .place {
        Button(.init("button_0"))
        Button(.init("button_1"))
            .modifiable
            .position(CGPoint(x: 0, y: -50))
    }

let node: SKNode = SKNode.applying(widget: layout)
rrbox commented 1 year ago

Widget protocol でカスタム Widget を作る API では node()node(context:) が必須であり、しかも public にする必要があります。つまり、廃止は難しいかもしれません。

廃止しない場合は、レイアウトとして利用する(上記のような)方法をどこかに提示しておくといいかもしれません。

もしくは、既存 Widget は applying のみで生成できるようにし、プログラマが作成する Widget は node() でも生成可能にするという選択もある。

rrbox commented 1 year ago

58 で NotificationCenter 関係の API でも SKNode.applying(widget: layout) と同様の提案が出ました。

統一のために、こちらに移行した方がいいかもしれません。

rrbox commented 1 year ago

現在、createModels() というメソッドにより、 UI を制御するモデルを生成するメソッドを模索しています。

func createModels() -> (Node, NotificationCenter)

現在は Widget に関連づけられた Node と、Node が登録された NotificationCenter が出力されるようになっています。

また、Node と NotificationCenter の登録は combine(node:, center:) メソッドで設計できる仕様になります。

func combine(node: Node, center: NotificationCenter)

現段階ではテストも不十分であり、Node と NotificationCenter の結合もチェックしていません。また、NotificationCenter は専用の型でラップし、ビルダーパターンで Observer を登録できるようにしようとも思っています。その場合は以下のようなメソッドになるかと思います。

func createModels() -> (Node, NotificationCenterWrapper)