Croquet において、三次元物体に動きを付けたい場合、どんな方法が考えられるだろうか。動きの機能を持つ物体のサブクラスを定義するというのが単純な解。しかし、これでは後で複数の動きを組み合わせたいと言うときに困る事になる。物体に動きを「くっつける」事が出来ればよりスマート。つまり、継承ではなく委譲を使う方法 EventBehavior を使えばよい。
実はこの機能は、数年前に発表された、いわゆる Croquet 0.01 で既に実装されていた。しかし、いつの間にかぶっ壊れていたのでもう廃止になったのだと思っていたら、先月の会議の時に Mark さんがちょっとデモしてくれた。Tweak のフレームワークと統一化して、ちょっと扱いがややこしくなっている。とりあえずソース。
'From Jasmine-rc1 of 7 October 2004 [latest update: #231] on 16 June 2005 at 6:33:57 pm'! CEventBehavior subclass: #TRotationBehavior instanceVariableNames: '<?xml version="1.0"?><fields></fields>' classVariableNames: '' poolDictionaries: '' category: 'Tweak-Behaviors'! !TRotationBehavior methodsFor: 'as yet unclassified' stamp: 'tak 6/16/2005 18:14'! onStart | script | <on: start in: target> script _ self startScript: [ [target yaw: target yaw + 1. self waitTick] repeat]. target waitUntil: #stop. self stopScript: script! !
これを file in した後、以下を一行ずつ Workspace で実行すると、グルグル回るティーポットが出来る。
"Define objects" TeaTest new bounds: (10@10 extent: 320@240); openInWorld. pot _ TTeapot new scale: 2.0. teapot _ CroquetGlobals theTeapotMorph. "Attach the behavior" script _ self startScript: [TRotationBehavior attachTo: pot]. script setScheduler: teapot scriptScheduler. script resume. "Show the pot" teapot activeCamera root addChild: pot. pot signal: #start.
停止は pot signal: #stop. 特に真ん中あたりが素晴らしくややこしいが、原因は、Croquet (Tweak も同じ)の世界でのスクリプトスケジューラが Workspace の置いてある Morphic 世界には無い事にある。ここでは、theTeaPotMorph にあらかじめ設定してあるスケジューラを使っている。
スケジューラというのは普段は全く気にする事が無い物だが、複数の処理の流れを交通整理する部品だ。Croquet では Squeak に最初からあるスケジューラではなく、独自のスケジューラを使っている。違いは新しいスケジューラがノンプリエンティブだという事。Squeak では本来、優先順位の同じプロセスはノンプリエンティブに振舞うはずだとどこかで聞いた事があるのだが、現実は違うから改めて作ったのかな。何でかな。でも新しいスケジューラでは気前良く沢山スクリプト(=プロセス)を生成するので、気分的にも違う雰囲気ではありますが。