イネマルのプログラミング備忘録

趣味プログラマのメモ

WSH JScript CScript プログレスバー

はじめに

軽く検索しても手軽なサンプルが見つからなかったので、
CScript と JScript を使ったコマンドライン環境向けに、プログレスバーを用意します。

↓ のように動きます。
f:id:inemaru:20200321072912g:plain

実装

最低限の機能があれば良いので、設定できるオプションは下記だけ。

画面更新の仕組みとしては、C++等と同様で、
制御文字CR(\r)を使っています。(行頭に戻して書き直しするだけ。)

var ProgressBar = (function(){
    function ProgressBar() {
        this.MaxValue = 100;
        this.BarWidth = 30;
        this.Label = "progress";
    };
    ProgressBar.prototype.Update = function(value){
        var rate = value/this.MaxValue;
        var val = Math.ceil(Math.min(Math.max(1,rate*this.BarWidth),this.BarWidth));
        var barComplete = Array(val+1).join("=");
        var barIncomplete = Array(this.BarWidth-val+1).join("-");
        var isProcessing = 1>rate;
        WSH.StdOut.Write("\r"+this.Label+" ["+barComplete+barIncomplete+"] "
            +(isProcessing?(rate*100).toFixed(2)+"%":"complete\n"));
        return isProcessing;
    };
    ProgressBar.prototype.Complete = function(){this.Update(this.MaxValue)};
    return ProgressBar;
}());

使い方

進捗状態を更新するときは、Update
強制的に完了にしたければ、Completeメソッドを呼びます。

WSH.Quit(function()
{
    try{
        var prog = new ProgressBar();
        {
            prog.Label = "サンプルA:整数\t\t";
            for (i=0; prog.Update(i); i+=2) {
                WSH.Sleep(100);
            }
        }
        {
            prog.Label = "サンプルB:浮動小数\t";
            prog.MaxValue = Math.PI;
            for (i=0; prog.Update(i); i+=0.1) {
                WSH.Sleep(100);
            }
        }
        {
            prog.Label = "サンプルC:バーの幅変更\t";
            prog.BarWidth = 50;
            for (i=0; i < prog.MaxValue; i+=0.1) {
                prog.Update(i);
                WSH.Sleep(100);
            }
            // 強制する場合
            prog.Complete();
        }
    }
    catch(e){
        WSH.Echo(e.name + ":" + e.message);
        return -1;
    }
    finally{
        // 3秒待機
        WSH.Sleep(3000);
    }
    return 0;
}());

おわりに

時間のかかる処理ではプログレスバーを出す方が親切ですが、
コンソール画面(CUI, CLI)では、ログを出していればとりあえず処理が進んでいるのが目視できるのでプログレスバーは必須では無いと思います。