環境の注入

進捗

  • glfw, alureの初期化処理を用意
  • windowを表示してmain-loopを回せる
    • 継続のおかげで、ループ中にinterruptシグナルを送ってインタプリタで処理をしてrestartで復帰できる
    • 大抵のゲームシーンが{initialize}-{main}*-{terminate}のフローを通るのでどうやって処理を記述しようか検討中(dynamic-windみたいなのでもいいのか)
  • 音の再生,streaming再生をバインディング(alure便利)

ビルドスクリプト

ビルド用のスクリプトSchemeで記述(突貫工事).
しばらくインタプリタ上での検証がメインになるので共有ライブラリとしてビルドして
インタプリタからも読み取れるようにしておく.

(define (build target objs libs)
  (system* "csc -Isrc -include-path src -library -o ~a ~a ~a" target objs libs))
(build "fw.so"
  '("src/fw")
  '("-lglfw3"
    "-lpng"
    "-framework OpenGL"
    "-lalure"
    "-framework OpenAL"
    "-framework Cocoa"
    "-framework IOKit"
    "-framework CoreVideo"))

ALURE

ALURE Homepage

OpenALのソースファイル読み込み, ストリーミング再生の補助ライブラリ.
wav, aif, ogg*1のような代表的なコーデックをサポートされるので
とりあえずこれで再生に困ることはない.

アセット管理

今後予定しているゲーム内容を考えると、アセットの管理は自動化させる予定.
パフォーマンスよりもModdableであることと編集時にアセットの寿命を考えなくて良いようにしたい.

FWOBJと名前をつけてハッシュテーブルでアセットの一覧を管理して、
利用時に暗黙的にアセットを生成, キャッシュの寿命が尽きたらアセットを処分するフローを構築.
アセットの種類も様々あるので寿命管理の仕方は後々煮詰めていく予定.

環境の注入

主に副作用を前提としたコードを書く際、
複数クロージャに同一の環境を捕捉させたい場合下記のような方法が取れる.

(define-values (count-up look-up)
  (let ((table (make-vector 4))
    (values
      (lambda (n)
        (vector-set! table n (+ (vector-ref table n) 1)))
      (lambda (n)
        (vector-ref table n)))))

これだと入れ子が深くなるし、個数が多くなるとコードの修正が大変.
行儀は良くないが、set!を用いることで少しすっきり書いてみる方法に気が付いた.

(define (count-up table)
  (lambda (n)
    (vector-set! table n (+ (vector-ref table n) 1))))

(define (look-up table)
  (lambda (n)
    (vector-ref table n)))

(let ((table (make-vector 4))
  (set! count-up (count-up table))
  (set! look-up (look-up table)))

下手に最初から環境を閉ざすように書かずに、
後から環境を渡して手続き自体を置き換えるようにしている.

*1:libogg, libvorbisは予めインストールしておきましょう