2010/10/25

自前ウィンドウ上に表示した画像を更新・再描画する

Imageオブジェクトの画像をウィンドウに表示するには、Window.create()のオプションオブジェクトのgraphicsメンバにセットするというのは以前説明しましたが、今回は表示する画像の内容を更新する方法について説明します。

ウィンドウの画像を更新するには、Imageオブジェクトの各種メソッドで画像を更新した後、描画対象のWindowオブジェクトを引数にしてdrawTo()メソッドを呼び出します。

この時、複数スレッドからImageオブジェクトに同時アクセスしないように注意する必要があります。
ウィンドウを所有するスレッド上では、Imageオブジェクトを使用した再描画が不特定のタイミングで発生するので、他のスレッド上でImageオブジェクトを操作すると、更新途中の画像が表示されてしまったり、更新処理に失敗してしまったりします。
これを避けるためには、画像の更新処理もウィンドウを所有するスレッド上で実行しなければなりません。

Windowオブジェクトのイベントハンドラ内で更新・再描画を行う場合は特に気にする必要はありませんが、他のスレッドから更新を行う場合は、Windowオブジェクトのrequest()メソッドを使用してください。
request()メソッドは、指定された関数をウィンドウを所有するスレッド上で実行します。この関数内でImageオブジェクトを操作すれば、安全に画像を更新できます。

下記のスクリプトは、SystemMonitorユニットのCPUクラスを利用して取得したCPU使用率を円グラフでウィンドウ上に表示するという例です。
var img=require('Image').Image.create(100,100,"black");
var w=require('Window').PlainWindow.create({
    width:100, height:100,
    transparentColor:0x000000,topmost:true,
    graphics:img,
});

Thread.create(function(){
    var mon=new (require('SystemMonitor').CPU)(), rate=0;
    while(true){
        w.request(function(){
            img.fillEllipse(1,1,98,98,0x9999FF);
            img.fillPie(1,1,98,98,-Math.PI/2,(Math.PI*2)*rate,0x99FF99,true);
            img.strokeEllipse(1,1,98,98,0x010101,true);
            img.drawTo(w);
        });
        sleep(1000);
        rate=mon.get().usage;
    }
});
w.show();

0 件のコメント:

コメントを投稿