####プログラム概要#####
#このサンプルプログラムは、登録されている座標へ順次にステージ移動を行いビデオキャプチャに
#より画像を追加登録します。
#自動処理実行中に、コマンド処理で失敗すると内部から自動処理を停止するようになっております。
#このプログラムは、顕微鏡に依存しない内部コマンドのみを使用しております。
#このプログラムは、別途「SL−ビデオキャプチャ」が必要です。
#図形一覧ウィンドウを表示したまま実行すると図形ファイルの読み込みと表示処理で時間がかかります。
#実行時は、図形一覧ウィンドウを閉じて行ってください。
#スクリプトウィンドウをアクティブ(入力受け付け状態)にすると非アクティブに比べ処理速度が格段
#に上がります。自動処理実行中は、スクリプトウィンドウをアクティブにしておいてください。

VERSION 3    #要求するスクリプトバージョン

#####大域変数定義#####

VARIABLE SL仮身:S  #ステージリンク仮身セグメントへの参照
VARIABLE SL返答:C[512]  #受信メッセージを格納するエリア

#####サブルーチン#####
#ステージリンクに要求メッセージを送信して応答メッセージを受信するサブルーチンです。
#これから作成されるスクリプトプログラムで共通のサブルーチンとしてご利用いただけます。
#ステージリンクは、タイプ0のメッセージを送受信しますのでMSENDおよびMRECVには、
#タイプ0のパラメータを与えています。また、本プロセスが受信するメッセージもタイプ0に限定
#しています。
#ステージリンクからの応答待ち時間を最大3分にしています。
#ただし、この値は、ご使用になるステージ装置や顕微鏡装置によって異なります。適切な値を決めるには、
#ステージの移動から停止までにかかる時間や顕微鏡装置の動作開始から完了までにかかる時間の2倍以上の
#時間を与えてください。

FUNC SLコマンド(SL要求メッセージ,SL応答メッセージ)

 LOCAL PID #受信したメッセージの送り元のプロセスID
 LOCAL TYPE #受信したメッセージのタイプ
 LOCAL SIZE #受信したメッセージの長さ

 MSEND SL仮身.PID,0,slen(SL要求メッセージ)*2,SL要求メッセージ
 MRECV 0x01,PID,TYPE,SIZE,SL応答メッセージ:180
END

#####前処理#####
#このルーチンは、スクリプトを起動したとき初めて呼ばれます。
#このサンプルプログラムでは、画面サイズを背景セグメントのサイズにして各項目を表示しています。
#つぎに、ステージリンクを起動させてユーザーからの操作待ちになります。

PROLOGUE

 SET SL仮身=サンプル台紙 #ステージリンクの仮身セグメントです。
 SET $MMASK=0x01 #本プロセスが受信するメッセージをタイプ0に限定

 WSIZE @背景.W,@背景.H

 #画面項目の表示
 APPEAR @背景
 APPEAR @自動処理の開始
 APPEAR @経過時間
 APPEAR @ステータス
 APPEAR @SL要求

 VOPEN ”SL−ビデオキャプチャ”

 EXECUTE ステージリンク起動処理
END

#####後処理#####
#このルーチンは、終了操作を行ったときに呼ばれます。
#このサンプルプログラムでは、ステージリンクの強制終了と画面の位置を保存して次回起動時に再現するようにして
#います。
#注意:このルーチンが呼び出されると自動処理の2つのスレッドが強制終了させられます。
#   自動処理中は、先に自動処理を停止させてから終了操作を行ってください。

EPILOGUE

 VCLOSE SL仮身

 WSAVE
END

#####ステージリンク起動処理#####
#ステージリンクの起動と疎通を確認する内部コマンドを発行して正常起動を確認しています。

ACTION ステージリンク起動処理

 VOPEN SL仮身

 CALL SLコマンド(”疎通の確認”,SL返答)
 IF (scmp(SL返答,0,”成功¥0”,0,2) == 0)
  TEXT @ステータス,”正常に起動されました。¥0”
 ELSE
  TEXT @ステータス,”起動されませんでした。¥0”
  BEEP
 ENDIF
END  

#####自動処理の開始#####
#画面項目の「自動処理の開始」がクリックされた時に呼ばれるルーチンです。
#このサンプルプログラムでは、通信の接続と「自動処理」スレッドを並列起動しています。

ACTION 自動処理の開始 CLICK @自動処理の開始

 IF @自動処理の開始.S
  CALL SLコマンド(”通信の接続”,SL返答)
  IF (scmp(SL返答,0,”成功¥0”,0,2) == 0)
   DISAPPEAR @自動処理の開始
   APPEAR @自動処理の停止

   EXECUTE 自動処理
  ELSE
   TEXT @ステータス,”通信の接続に失敗しました¥0”
   BEEP
  ENDIF
 ENDIF
END

#####自動処理の停止#####
#画面項目の「自動処理の停止」がクリックされた時に呼ばれるルーチンです。
#このサンプルプログラムでは、並列動作している「自動処理」スレッドを停止させて通信の切断を実行しています。

ACTION 自動処理の停止 CLICK @自動処理の停止

 IF @自動処理の停止.S

  IF @自動処理中.S
   DISAPPEAR @自動処理中
   WAIT (自動処理.S==0)
  ENDIF

  CALL SLコマンド(”通信の切断”,SL返答)
  IF (scmp(SL返答,0,”成功¥0”,0,2) == 0)
   TEXT @ステータス,”正常に切断しました。¥0”
   DISAPPEAR @自動処理の停止
   APPEAR @自動処理の開始
  ELSE
   TEXT @ステータス,”通信の切断に失敗しました¥0”
   BEEP
  ENDIF
 ENDIF
END

#####自動処理中の表示スレッド#####
#このスレッドは、「自動処理」スレッドの中から並列起動されます。
#「自動処理」スレッドが実行されている間、経過時間と右から左へ動く”処理中”メッセージを1秒間隔で表示更新
#しています。「自動処理」スレッドが停止すると表示更新を中止して本スレッドも停止するようになっています。

ACTION 自動処理中の表示

 LOCAL メッセージ:C[28]
 LOCAL CNT
 LOCAL ST

               #0−−−−+−−−−1−−−−+−−−−2−−−−+−−27
 SET メッセージ[:] = ”                  ・・・処理中・・・¥0”
 SET CNT = 0
 SET ST=$SYSTM

 WHILE (自動処理.S > 0)

  TEXT @経過時間,”経過時間%4d分¥0”,($SYSTM−ST)/60

  TEXT @ステータス,”%s¥0”,メッセージ[CNT:18]
  SET CNT = CNT + 1
  IF CNT >= slen(メッセージ)
   SET CNT = 0
  ENDIF

  WAIT (自動処理.S == 0):1

 ENDWHILE

END

#####自動処理スレッド#####
#このルーチンの中に自動処理スクリプトを記述できます。
#このサンプルプログラムでは、登録されている座標へ順次にステージ移動を行いビデオキャプチャにより画像を追加登録します。
#コマンドの処理で失敗すると内部から自動処理を停止するようになっております。
#また、本スレッドのの開始と同時に「自動処理中の表示」スレッドが並列動作しており経過時間と動くメッセージが表示
#され続けます。本スレッドが終了すると「自動処理中の表示」スレッドも終了するようになっています。

ACTION 自動処理

 LOCAL 座標数
 LOCAL 座標番号
 LOCAL 処理結果:C[32]
 LOCAL wXpos
 LOCAL wYpos

 APPEAR @自動処理中
 EXECUTE 自動処理中の表示

 CALL SLコマンド(”座標数の取得”,SL返答)
 IF (scmp(SL返答,0,”成功¥0”,0,2) != 0)
  DISAPPEAR @自動処理中
  CALL 自動処理の停止
  TEXT @ステータス,”座標数の取得で失敗しました。”
  EXIT
 ENDIF

 SET 座標数  = strnum(SL返答,3,’d’)
 SET 座標番号 = 0
 SET 処理結果[:] = ”正常に終了しました。”

 WHILE (@自動処理中.S && 座標番号<座標数)

  TEXT @SL要求,”登録位置の取得 %d”,座標番号
  CALL SLコマンド(@SL要求.TX,SL返答)
  IF (scmp(SL返答,0,”成功¥0”,0,2) != 0)
   SET 処理結果[:] = ”登録位置の取得で失敗しました。”
   BREAK
  ENDIF

  wXpos = strnum(SL返答,3,’f’,wYpos)
  wYpos = strnum(SL返答,wYpos+1,’f’)
  TEXT @SL要求,”指定位置の移動 %.3f,%.3f”, wXpos, wYpos
  CALL SLコマンド(@SL要求.TX,SL返答)
  IF (scmp(SL返答,0,”成功¥0”,0,2) != 0)
   SET 処理結果[:] = ”指定位置の移動で失敗しました。”
   BREAK
  ENDIF

  TEXT @SL要求,”指定位置へステージ移動”
  #または#TEXT @SL要求,”登録位置へステージ移動 %d”,座標番号
  CALL SLコマンド(@SL要求.TX,SL返答)
  IF (scmp(SL返答,0,”成功¥0”,0,2) != 0)
   SET 処理結果[:] = ”ステージ移動で失敗しました。”
   BREAK
  ENDIF

  TEXT @SL要求,”座標の選択 %d”,座標番号
  CALL SLコマンド(@SL要求.TX,SL返答)
  IF (scmp(SL返答,0,”成功¥0”,0,2) != 0)
   SET 処理結果[:] = ”座標の選択で失敗しました。”
   BREAK
  ENDIF

  TEXT @SL要求,”図形の登録”
  CALL SLコマンド(@SL要求.TX,SL返答)
  IF (scmp(SL返答,0,”成功¥0”,0,2) != 0)
   SET 処理結果[:] = ”図形の登録で失敗しました。”
   BREAK
  ENDIF

  IF (@自動処理中.S)
  
   SET 座標番号 = 座標番号 + 1

   #以下のコメント(#)を外すと無限に繰り返します。(テスト用)
   #IF 座標番号 >= 座標数
   # SET 座標番号 = 0
   #ENDIF
  ENDIF

 ENDWHILE

 DISAPPEAR @自動処理中
 CALL 自動処理の停止
 TEXT @ステータス,処理結果


END