top of page

4. Self-update System

 プログラマブルブロックには、1つのプログラムに書き込める命令数に制限があるため、無限ループを作ることができません。このため、常に施設の状態や宇宙船の姿勢などを監視・制御したい場合には、周期的にプログラムを実行する必要があります。タイマーブロックを使って周期的にプログラムを実行する方法もありますが、ここではプログラム中で周期を指定して繰り返し Main() を呼び出すことができる "Self-update System" の使い方について紹介します。

 

4-1. UpdateFrequency

 Self-update System は、Runtime.UpdateFrequency プロパティに実行周期を設定するだけで利用できます。通常は以下の例のようにコンストラクタ Program() 中に記述しますが、プログラム中のどこでもこのプロパティを設定・変更することが可能です。

public Program()

{

    Runtime.UpdateFrequency = UpdateFrequency.Update1 | UpdateFrequency.Update10;

}

 このコードを実行すると、1 tick と 10 ticks 毎に Main() が繰り返し呼び出されます。1 tick が最小周期で、10 tick はその 10 倍長い間隔で呼び出しが発生します。つまり、Update10 で 1 回 Main() が呼ばれる間に、Update1 からの Main() の呼び出しが 10 回発生します。

 UpdateFrequency プロパティは以下のような演算子も使えます。これらはそれぞれ Update100 の追加と Update10 の削除を意味します。

Runtime.UpdateFrequency |= UpdateFrequency.Update100;

Runtime.UpdateFrequency &= ~UpdateFrequency.Update10;

 Self-update System を停止したい場合は以下のように設定します。

Runtime.UpdateFrequency = UpdateFrequency.None;

 また、次の tick で Main() を呼び出した後、フラグが削除されることで一度だけ Main() が呼び出される以下のフラグも存在します。

Runtime.UpdateFrequency = UpdateFrequency.Once;

 Update10 と Update100 に関して、その呼び出し周期が正確に 10 または 100 tick となることは設計上保証されていないそうです。

4-2. UpdateType

 Main メソッドには UpdateType 型の updateSource という引数があり、この引数はこのプログラムがどのように実行が開始されたかを以下のように表します。

Terminal = 1 << 0        //ターミナルからユーザーにより実行

Trigger = 1 << 1           //タイマーやセンサーなどのブロックにより実行

Antenna = 1 << 2        //メッセージを受信したアンテナにより実行

Mod = 1 << 3               //mod により実行

Script = 1 << 4             //他のプログラマブルブロックにより実行

Update1 = 1 << 5        //Self-update System の Update1 設定により実行

Update10 = 1 << 6      //Self-update System の Update10 設定により実行

Update100 = 1 << 7    //Self-update System の Update100 設定により実行

Once = 1 << 8              //Self-update System の Once 設定により実行

None = 0

 この updateSource は上に示した 10 個のフラグのどれかひとつを表すのではなく、すべてのフラグの状態を表すビットフラグであり、ひとつの値に複数のフラグ情報を持ちます。例えば Main の呼び出しが、Update1, Update10, Update100 によって同一タイミングで発生した場合、Main の呼び出しは 3 回発生するのではなく、これら3つのフラグが ON となっているupdateSource を引数に 1 回だけ Main の呼び出しが発生するようです。

 このように updateSource はビットフラグであるため、単純な == による比較は行えませんので、以下に示すようにビット演算を使って各フラグの状態を判定します。

if((updateSource & UpdateType.Update100) != 0){

   //Update100 により実行される

}

 

if((updateSource & (UpdateType.Update1 | UpdateType.Update10)) != 0){

   //Update1 または Update10 により実行される

}

 また、次のように HasFlag メソッドを使ってもフラグの判定はできますが、上のビット演算による判定のほうが桁違いに速いのでおすすめだそうです。

if(updateSource.HasFlag(UpdateType.Update1)){

   //Update1 により実行される

}

bottom of page