HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2009
0809
tip_reqボタンの割り込み一時的にやめさせたい6解決


tip_req

リンク

2009/8/9(Sun) 23:03:12|NO.26970

 今、数独を解くソフトを作成中なのですが、解くのを途中で中断させたり、再開させたりしたいと考えています。
 そこで、ボタン命令で中断・再開の操作ができるようにしたいのですが、下のような不具合が出るのが思考実験でわかりました。
>>>
button gosub "STOP",*HATA_1
button goto "RESTART",*HATA_2

repeat
 処理A
 処理B
 処理C
loop

*HATA_1
stop
*HATA_2
return
<<<
 とすると、たとえば、処理Aを実行している最中に*HATA_1に飛んでしまうこともありますよね。
 ここで、たとえば処理Cがそれまでの結果を画面に反映する処理だったとします。

 私としては、処理Cが終了したら*HATA_1に飛ぶようにしたいのですが、一体どうしたらいいのでしょうか。
 ボタンの無効化も考えましたが、たぶんボタンが異常なほどにチカチカすることも考えられます。
 処理A、B、Cそれぞれに対応する変数を定義して、たとえば今処理Aならimadoko=1でBならimadoko=2といった調子で定義して、*HATA_1の後の処理で、処理Aの途中と、処理B、Cを完了してからSTOP命令を実行することも考えましたが、煩雑になりそうです。

 苦肉の策でこんなもの考えましたが・・・
>>>
button gosub "STOP",*とまれ
button goto "RESTART",*またうごけ

repeat
 処理A
 処理B
 処理C
if order = "止まれ" : gosub *一時停止中
loop

*とまれ
order = "止まれ"
return

*一時停止中
stop
*またうごけ
order = "うごいてよし"
return
<<<
 なんか、もっと簡単にする方法はないですか?



この記事に返信する


Sucret

リンク

2009/8/9(Sun) 23:25:07|NO.26971

button命令はawaitやwaitなどが実行されたタイミングで飛ばされますので
飛ばされては困るタイミングに入れなければいいのではないでしょうか?

それで無限ループになったりwaitが実行されるまでにある程度の処理を必要とする場合は
何か別の変数を用意して
それが0なら処理を行い、
それが1なら処理を無視するようにすればいいと思います。
buttonのジャンプ先でその値を変更すればいかがでしょうか?
その際は全てのボタンにgosubを指定する必要がありますが。



ANTARES

リンク

2009/8/10(Mon) 07:56:11|NO.26975

 button gosubの使えないHSP2でどうやるか考えてみました。
HSP2での動作確認はしていませんが……。

nloop=10 button "stop",*l_stop button "do",*l_loop yy=48 ii=0 *l_loop repeat i=0: k=0 gosub *l_proc wait 1 ii++ if ii>23: ii=0: color 255,255,255: boxf: color: pos 0,yy loop stop *l_stop mes " stop. i="+i+" k="+k gosub *l_proc stop *l_proc repeat nloop-i,i i++: wait 1 loop repeat nloop-k,k k++: wait 1 loop mes "i="+i+" k="+k return



M

リンク

2009/8/10(Mon) 12:56:53|NO.26977

フラグを用意して、フラグが立っていないときは、ボタン内の処理をせずにもどるようにしたらどうでしょうか。
下の場合だと、処理Aの時はボタンを受け付け、処理Bと処理Cの最中では、ボタンを押しても何もしない。はず〜。


button gosub "STOP",*とまれ button gosub "RESTART",*またうごけ repeat ; 処理A flg=0 ;ボタンを無視したい処理の手前で、フラグを0にする ; 処理B ; 処理C flg=1 ; await 0 loop *とまれ if flg!1:return ;フラグが1になっていなければ、なにもせずに戻る mes "止まれ" return *またうごけ if flg!1:return mes "うごいてよし" return



SYAM

リンク

2009/8/10(Mon) 14:40:20|NO.26979

私がやるとしたらその“苦肉の策”と同じ方法をとると思います。
処理A, B, C が必ず 最初から最後まで 実行されることをハッキリさせるような仕組みをスクリプトのレベルで作っておくことで、探しにくいバグを発生させることを防ぐというのが理由です。
処理の流れとしては煩雑なようですが、ちょっと整理して書いておけば後はさほど意識せずに処理を記述していけます。常に割り込まれることを意識しながらスクリプトを書いていくよりは、割り込まれても大丈夫なように最初から書いておく方がラクかなと思います。


sdim dummy,32 button gosub "PAUSE", *ONBUTTON_PAUSE input dummy,128 pause=0 *MAIN_LOOP repeat if(pause){ gosub *PAUSE_ROUTINE }else{ gosub *MAIN_ROUTINE } wait 1 loop *MAIN_ROUTINE // 処理A. // 処理B. // 処理C. x+=1 : buf=str(x) objprm 1,buf : wait 10 y+=1 : buf += "+"+y objprm 1,buf : wait 10 buf += "="+(x+y) objprm 1,buf : wait 10 return *PAUSE_ROUTINE // 停止中に何かするならここ. l=(l+1)&0xf bar="" repeat l : bar+="-" : loop objprm 1,bar return *ONBUTTON_PAUSE if(pause) { objprm 0,"PAUSE" pause=0 }else{ objprm 0,"RESUME" pause=1 } return



tip_req

リンク

2009/8/10(Mon) 15:14:27|NO.26980

みなさん、ご回答ありがとうございました。



shinkun

リンク

2009/8/10(Mon) 19:09:06|NO.26982

既に解決済みのようですが…。
停止時に何もしないのであれば、私はこんな感じで書きますネ。たぶん。


button gosub "stop", *halt button goto "resume", *resume *main ; 処理A ; 処理B ; 処理C ; ここで停止するかどうか判定 if (f) { stop } else { await 20 } goto *main *halt f = 1 return *resume f = 0 goto *main

repeat - loop による無限ループも使うけれど、ラベルによる無限ループも好き。
作業量自体はそんなに変わらないけれど、制御構造は素直になったんじゃないかなと。



ONION software Copyright 1997-2023(c) All rights reserved.