RGSS2を知る(4)

次はdispose。

bitmap1 = Bitmap.new(100,100)
bitmap1.fill_rect(bitmap1.rect, Color.new(0,0,255,255))
bitmap2 = Bitmap.new(100,100)
bitmap2.fill_rect(bitmap2.rect, Color.new(0,255,0,255))
bitmap3 = Bitmap.new(100,100)
bitmap3.fill_rect(bitmap3.rect, Color.new(255,0,0,255))

viewport = Viewport.new(0,0,640,480)

s1 = Sprite.new(viewport)
s1.bitmap = bitmap1

s2 = Sprite.new
s2.bitmap = bitmap2
s2.x = 200

loop do
  Input.update
  Graphics.update
  s1.dispose if Input.trigger?(Input::C)
  s2.dispose if Input.trigger?(Input::B)
  viewport.dispose if Input.trigger?(Input::A)
end

ボタンを押すとそれぞれのSprite、Viewportをdisposeする。
きちんと確認するには何度か実行しないといけない。
Spriteをdisposeすると、四角がそれぞれ消える。
Viewportをdisposeすると関連付けされたSpriteが消える。
内部的にdispose状態を保持していて、描画時にそれで描画するかどうかを判定しているのだろう。
別にdisposeしたからといってオブジェクトが解放されるわけではない。
Spriteはnewしただけで描画が開始されるから、もう永遠に描画しない、すなわちシステム保持のポインタ配列から削除するという表現は必要だ。
GCに回収してもらっても描画されなくなるが、そっちはGC.startすると遅いし、ほっとくといつ回収されるかわからないから、そういう手段が無いと困る。
一時的に描画しないのはvisibleプロパティがあり、dispose状態から復帰させる手段が無いところを見ると、やっぱりそういう用途なのだろう。
あとはGCに回収されるだけ〜って感じ。
visible=falseしたままGCの回収を待っても問題はなさそうだけど。


関連付け無しSpriteと同列に位置する(と思われる)Viewportも、同じようにdisposeすると描画時に無視されるようになる。
Viewportが無視されるから、その下にぶらさがるSprite達も結果として無視されるようになる。
マニュアルに、「Viewportのdisposeで関連付けされたオブジェクトが解放されなくなりました(RGSS2)」、と書いてあった。
XPの動作がわからないが、そもそもオブジェクトを束縛していないのだから(viewportに関連付けしてあってもRubyコードから参照されていなければGCで回収される)、解放というのはdisposeのことだろう。
Viewport#disposeの実行で関連付けされたSpriteまでdisposeされてしまっては、他のViewportに移して描画することもできなくなってしまうから、これは妥当だ。
内部実装はともかく、SpriteのプロパティとしてViewportを指定するのであって、Viewportが占有して保持するものではないからだ。