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


HSPTV!掲示板


未解決 解決 停止 削除要請

2019
0707
Y_repeatbuttonと無限ループの関係16解決


Y_repeat

リンク

2019/7/7(Sun) 17:34:52|NO.87830

以前。ツールでbuttonと無限ループを併用していたのですが
併用しないツールはすんなり作成出来るのですが
併用するとやたら意図通り動きません

例えばキッチンタイマーのようなものを作成した時は
時間代入ボタン。押したら動作して止まる。
ボタン割り込みにより無限ループ止まる。
STARTボタン。押したら動作して無限ループへ
ボタン割り込みにより無限ループ止まった後、
もう一回無限ループへ。
STOPボタン。押したら止まる。
ボタン割り込みにより無限ループ止まる。
RESTARTボタン。STOPボタンで止まってた動作再開。
ボタン割り込みにより無限ループ止まった後、
もう一回無限ループへ。
RESETボタン。STOPボタンで止まってたタイマーが、
0になる。
ボタン割り込みにより無限ループ止まる。

ってかんじでしたが、やたら意図通り動きませんでした。
ボタンと無限ループの関係はこんなんがベターなのでしょうか。
それとももっとスマートな併用の仕方があるんでしょうか。



この記事に返信する


沢渡

リンク

2019/7/7(Sun) 18:16:33|NO.87831

私だったらこんな感じで、ストップ中も無限ループは止めず、稼働中に行う処理を行わない形にすると思います。

#include "winmm.as" #define boxf2(%1,%2,%3,%4) boxf %1,%2,(%1)+(%3)-1,(%2)+(%4)-1 #const fps1 10 //停止中のfps #const fps2 30 //稼働中のfps dim w_msec,2 : w_msec=1000/fps1,1000/fps2 //停止中は負荷削減のためにウェイト時間を長めにとる carry_time=0 //繰り越し時間 c_flag=0 //タイマー稼働中フラグ start_time=0 //スタートタイム objsize 100,30 pos 0,20 : button gosub "START",*start s_id=stat pos 100,20 : button gosub "RESET",*reset r_id=stat repeat gosub *view_time await w_msec(c_flag) loop *view_time redraw 0 if c_flag : timeGettime : time=stat-start_time+carry_time : else : time=carry_time color 255,255,255 : boxf2 0,0,200,20 color 0,0,0 : pos 0,0 ms=time\1000 : time=time/1000 //ms:ミリ秒 s=time\60 : time=time/60 //s:秒 m=time\60 : h=time/60 //m:分 h:時 mes strf("%02d:%02d:%02d.%03d",h,m,s,ms) redraw 1,0,0,200,20 return *start //start・stop・restart if c_flag { timeGettime carry_time=stat-start_time+carry_time c_flag=0 objprm s_id,"RESTART" } else { timeGettime start_time=stat c_flag=1 objprm s_id,"STOP" } return *reset if c_flag { timeGettime start_time=stat carry_time=0 } else { carry_time=0 objprm s_id,"START" } return



沢渡

リンク

2019/7/7(Sun) 19:04:00|NO.87832

すみません、少し改良です。

#include "winmm.as" #define boxf2(%1,%2,%3,%4) boxf %1,%2,(%1)+(%3)-1,(%2)+(%4)-1 #const fps1 1 //停止中のfps(awaitは割り込みがあると即終了するから相当ウェイトを長めにとっていい?) //参考:http://hsp.tv/play/pforum.php?mode=pastwch&num=37673 #const fps2 30 //稼働中のfps dim w_msec,2 : w_msec=1000/fps1,1000/fps2 //停止中は負荷削減のためにウェイト時間を長めにとる carry_time=0 //繰り越し時間 c_flag=0 //タイマー稼働中フラグ sd_flag=0 //ストップ中に描画したフラグ start_time=0 //スタートタイム objsize 100,30 pos 0,20 : button gosub "START",*start s_id=stat pos 100,20 : button gosub "RESET",*reset r_id=stat repeat gosub *view_time await w_msec(c_flag) loop *view_time if c_flag { timeGettime : time=stat-start_time+carry_time } else { if sd_flag : return time=carry_time sd_flag=1 } redraw 0 color 255,255,255 : boxf2 0,0,200,20 color 0,0,0 : pos 0,0 ms=time\1000 : time=time/1000 //ms:ミリ秒 s=time\60 : time=time/60 //s:秒 m=time\60 : h=time/60 //m:分 h:時 mes strf("%02d:%02d:%02d.%03d",h,m,s,ms) redraw 1,0,0,200,20 return *start //start・stop・restart if c_flag { timeGettime carry_time=stat-start_time+carry_time c_flag=0 sd_flag=0 objprm s_id,"RESTART" } else { timeGettime start_time=stat c_flag=1 objprm s_id,"STOP" } return *reset if c_flag { timeGettime start_time=stat carry_time=0 } else { carry_time=0 sd_flag=0 objprm s_id,"START" } return



Y_repeat

リンク

2019/7/7(Sun) 19:34:54|NO.87833

なるほど、やはりbutton gosub使用ですか
イマイチbutton gosubの動き方がわかってないので
解説サイトとかないっすかね



Y_repeat

リンク

2019/7/7(Sun) 19:40:27|NO.87834

すいません。ググったら HSPTVの書き込みにHITしました。
button gosubは無限ループの処理を行いたいという要望により
実装されたとかで
無限ループ処理を行いたいなら
button gotoではなく
button gosubが適しているのですね



科学太郎

リンク

2019/7/7(Sun) 20:06:29|NO.87835

もう解決してますが、ストップウォッチならばタイマー処理の方が簡単な気がします。
無限ループよりもね。



Y_repeat

リンク

2019/7/8(Mon) 02:28:03|NO.87836

タイマー処理はやったことなくてですね

無限ループも
awaitした時間足せば(引けば)いいだけなんで
簡単です

もちろんタイマー処理にした方が
完成度高そうではあります

await中他処理行っちゃってラグるとか
タイマー起動しっぱなしの時にPCがスリープしちゃうとか



科学太郎

リンク

2019/7/8(Mon) 13:40:00|NO.87837

> タイマー処理はやったことなくてですね

・[HSP]デジタル時計のソース(2)
https://blog.goo.ne.jp/masaki_goo_2006/e/8cfca5cd2fc045504157844f94a78b53

タイマー処理のサンプルをどうぞ。

> もちろんタイマー処理にした方が
> 完成度高そうではあります
下記にストップウォッチのサンプル、
さらにストップウォッチからキッチンタイマーに改良する方法を載せておきます。

なお、サンプルではマウスの
左クリックでスタート/ストップ
右クリックでストップ/リセット
になります。

プッシュボタンのスタート、ストップ、リセットは動作確認のためです。
同様に

*PushStart *PushStop *PushReset
の3つのラベルも動作確認用にあるため完成したら削除する事になるでしょう。

//------------------------------------------------------------------------------ // ストップウォッチ by 科学太郎 //============================================================================== // 新規作成日:2019-07-08 (月) 11:38:00 // 最終更新日:2019-07-08 (月) 12:56:00 //------------------------------------------------------------------------------ // @URL(http://hsp.tv/play/pforum.php?mode=all&num=87830)→「buttonと無限ループの関係」 //------------------------------------------------------------------------------ #cmpopt varinit 1 #packopt hide 1 #packopt name __FILE__ # #include "User32.as" #include "Kernel32.as" //-------------------------------------- // 記号定数(API定数) //-------------------------------------- #const global NULL 0 #const global WM_TIMER $00000113 #const global WM_LBUTTONUP $00000202 #const global WM_RBUTTONUP $00000205 //-------------------------------------- // 記号定数 //-------------------------------------- #const WID_MAIN (0) ;ウインドウID #const TID_STOPWATCH (1) ;タイマーID #const TMS_STOPWATCH (10) ;タイマー間隔(ms) //-------------------------------------- // メイン部 //-------------------------------------- *Init dim nStart ;開始時間(ms) dim nCount ;経過時間(ms) dim nMode ;モード状態(0=中止,1=計測中) *Main screen WID_MAIN,700,75,SCREEN_NORMAL|SCREEN_FIXEDSIZE|SCREEN_HIDE syscolor 15:boxf:color:title "ストップウォッチ by 科学太郎" font MSGOTHIC,75:SetTimer hWnd,TID_STOPWATCH,TMS_STOPWATCH,NULL ;設定 oncmd gosub *OnLButtonUp, WM_LBUTTONUP oncmd gosub *OnRButtonUp, WM_RBUTTONUP oncmd gosub *OnTimer, WM_TIMER onexit gosub *OnQuit ;配置 objsize 100,25 button gosub "Start", *PushStart button gosub "Stop", *PushStop button gosub "Reset", *PushReset ;表示 DrawStopwatch gsel WID_MAIN,1 stop //-------------------------------------- // スタートの処理 //-------------------------------------- #deffunc CmdStart *PushStart if(nMode==0){ nMode=1:nStart=GetTickCount() } return //-------------------------------------- // ストップの処理 //-------------------------------------- #deffunc CmdStop *PushStop if(nMode){ nMode=0:nCount+=(GetTickCount()-nStart) } return //-------------------------------------- // リセットの処理 //-------------------------------------- #deffunc CmdReset *PushReset nStart=0 nCount=0 nMode=0 return //-------------------------------------- // スタート/ストップの処理 //-------------------------------------- *OnLButtonUp if(nMode):CmdStop:else:CmdStart return 0 //-------------------------------------- // ストップ/リセットの処理 //-------------------------------------- *OnRButtonUp if(nMode):CmdStop:else:CmdReset return 0 //-------------------------------------- // タイマーの処理 //-------------------------------------- *OnTimer if(wParam==TID_STOPWATCH){ redraw 0 DrawStopwatch DrawDebug redraw 1 } return 0 //-------------------------------------- // ストップウォッチの描画 //-------------------------------------- #deffunc DrawStopwatch ;分離 if(nMode):n=(nCount+(GetTickCount()-nStart)):else:n=nCount t=(n\1000) :n/=1000 s=(n\60) :n/=60 m=(n\60) :n/=60 h=(n\24) :n/=24 d=(n\100) :n/=100 ;座標 x=100+18 y=0 msg=strf("%02d\"%02d:%02d:%02d.%03d",d,h,m,s,t) ;描画 color $80,$00,$00:boxf color $66,$00,$00:pos(x+2),(y+2):mes msg color $FF,$00,$00:pos(x+0),(y+0):mes msg return //-------------------------------------- // デバッグ用の描画 //-------------------------------------- #deffunc DrawDebug ;取得 y=gettime(0) m=gettime(1) w=gettime(2) d=gettime(3) h=gettime(4) n=gettime(5) s=gettime(6) t=gettime(7) ;作成 sdim msg msg+=strf(" %04d/%02d/%02d %02d:%02d:%02d.%03d",y,m,d,h,n,s,t) msg+=strf(" [GetTickCount=%9d,nStart=%9d,nCount=%d,nMode=%d]",GetTickCount(),nStart,nCount,nMode) title msg return //-------------------------------------- // 終了時の割り込み処理 //-------------------------------------- *OnQuit KillTimer hWnd,TID_STOPWATCH end return //------------------------------------------------------------------------------ // End of sample352.hsp //------------------------------------------------------------------------------
上記はストップウォッチのサンプルでしたが、
このソースからキッチンタイマーに改良します。
なお、タイマー時間は3分間と決めてサンプルを載せます。

//-------------------------------------- // タイマーの処理 //-------------------------------------- *OnTimer if(wParam==TID_STOPWATCH){ redraw 0 DrawStopwatch(3*60*1000) DrawDebug redraw 1 } return 0 //-------------------------------------- // ストップウォッチの描画 //-------------------------------------- #deffunc DrawStopwatch int _timer_ ;分離 if(nMode):n=(nCount+(GetTickCount()-nStart)):else:n=nCount ;タイマー if(_timer_){ n=(_timer_)-n if(n<0):CmdReset:dialog "時間ですよ〜。",0,"確認":return } t=(n\1000) :n/=1000 s=(n\60) :n/=60 m=(n\60) :n/=60 h=(n\24) :n/=24 d=(n\100) :n/=100 ;座標 x=100+18 y=0 msg=strf("%02d\"%02d:%02d:%02d.%03d",d,h,m,s,t) ;描画 color $80,$00,$00:boxf color $66,$00,$00:pos(x+2),(y+2):mes msg color $FF,$00,$00:pos(x+0),(y+0):mes msg return
改良するとキッチンタイマーのサンプルになります。
なお、この時、リセットボタンは「00:03:00.00」というプリセット機能になります。



Y_repeat

リンク

2019/7/8(Mon) 23:14:46|NO.87843

こんばんわ。
気合の入ったサンプルスクリプトありがとうございます
すぐコードに落とせるのすごいです
→科学太郎さん。沢渡さん

やっぱりタイマー処理入るとややこしそうですね
ストップウォッチとしては完成しているので
そのまま使えばいいのかも



Y_repeat

リンク

2019/7/10(Wed) 21:20:14|NO.87847

お手数なのでサンプルプログラムまでは望んでないよー。と
思ってたんですけど、
処理をどう使うかがわかるので、有意義なのでしょう
ツールとして形になってるBBS投稿を
まとめて欲しくはありますが
やる人いないのかな

自分タイマー処理書いてた時は、
awaitした分、時間足したり引いたりしてたんですけど
沢渡さんのサンプルプログラムでは
時間を取得して計算してるんですね
ラグったりPCがスリープしても 大丈夫そうですね

科学太郎さんのサンプルプログラムは
パッと見、長いなあと思ったんですけど
コピペしたらコメントに飾りつけて150行くらいで
割と短いんだなあ。と思いました



科学太郎

リンク

2019/7/10(Wed) 21:20:37|NO.87848

> やっぱりタイマー処理入るとややこしそうですね
そうですか。
基本的にループ処理を WM_TIMER メッセージのサブルーチンに書くだけですよ。
そして、ループ処理のウエイト時間が、タイマー間隔になります。

・[HSP]ストップウォッチのソース
http://blog.goo.ne.jp/masaki_goo_2006/e/19b9c2bf1d76247a9afd53f1d8d1e2d8

・[HSP]タイマーのソース
http://blog.goo.ne.jp/masaki_goo_2006/e/5b98576c6da417d1695b1cc9ff33527f

新たに必要最小限のソース記事を用意しました。
少しは見やすくなったかな。
どうぞ。



Y_repeat

リンク

2019/7/11(Thu) 05:36:17|NO.87853

おはようございます

>> やっぱりタイマー処理入るとややこしそうですね
>そうですか。
>基本的にループ処理を WM_TIMER メッセージのサブルーチンに書くだけですよ。
>そして、ループ処理のウエイト時間が、タイマー間隔になります。

タイマー処理というより、API処理がややこしいんだと思います
自分ちょっとしか使ったことないので

>WM_TIMER メッセージのサブルーチンに書くだけですよ。
>oncmd gosub *OnTimer, WM_TIMER
WM_TIMERって何だろ?って思い探してたらココがポイントぽいですね
例えば一定時間ごとに自動的に押される隠しボタンがあったとして
その隠しボタンが押されると*OnTimerを実行し
*OnTimerがWM_TIMERのサブルーチンってことっすかね

>参照URL
せっかく書いたツールですもの
自分のサイトに載せてURLを書くのも
いい試みだと思います



科学太郎

リンク

2019/7/11(Thu) 13:29:51|NO.87854

> タイマー処理というより、API処理がややこしいんだと思います
> 自分ちょっとしか使ったことないので
API関数よりも Windows OS のメッセージ処理でしょうね。
HSP でいう oncmd の設定や、そのサブルーチンの動きだな。

> 例えば一定時間ごとに自動的に押される隠しボタンがあったとして
> その隠しボタンが押されると*OnTimerを実行し
> *OnTimerがWM_TIMERのサブルーチンってことっすかね
そうですね。
時計ソフトで自動的に表示を更新するときは、
ループ処理だとウインドウを移動中に更新が停止します。

タイマー処理だと一定間隔で *OnTimer ラベルのサブルーチンが
自動的に呼び出されて実行されます。
この2つの動きは、私のブログで確認が取れるようになってます。

・デジタル時計のソース(1)
http://blog.goo.ne.jp/masaki_goo_2006/e/38d8e6be32447e38d13b1cdb4c2fd3ed

・デジタル時計のソース(2)
http://blog.goo.ne.jp/masaki_goo_2006/e/8cfca5cd2fc045504157844f94a78b53

> せっかく書いたツールですもの
> 自分のサイトに載せてURLを書くのも
> いい試みだと思います
前々からストップウォッチとタイマーのサンプルソース公開を
考えていたが、面倒でしたので放置状態でした。

この質問の回答は、良いキッカケと思ってます。
丁度いいのでブログで紹介しました。



Y_repeat

リンク

2019/7/30(Tue) 19:07:56|NO.87972

何週間か前に(たぶん)ググった時に
それかここのBBSでどこぞの誰か様が書いたのを読んだか
例えば
button gosub "START",*start
は、ボタンを押すと
buttonの直後に飛んでくるのではなく
ボタンの割り込みで止まってたのが再開するっていう意味らしいです
自分、念のためフラグ使って
例えばbuttonとか通らないようにしようとか思ってました
ご参考までに



科学太郎

リンク

2019/7/30(Tue) 21:15:35|NO.87974

> button gosub "START",*start
この記述は、ウインドウ・プロシージャにボタンのジャンプ先を登録する指示です。
よって、この行で一時停止して、ボタンが押されたら
次の行を実行するわけではありません。

> 自分、念のためフラグ使って
> 例えばbuttonとか通らないようにしようとか思ってました
過去に似たような質問者が居ましたね。
button 命令は screen 命令と一緒に記述した方が分かり易いでしょう。

//------------------------------------------------------------------------------ // ミニ電卓のデザイン by 科学太郎 //------------------------------------------------------------------------------ //-------------------------------------- // 列挙定数(キー番号) //-------------------------------------- #enum KEY_AC=0 #enum KEY_7 #enum KEY_4 #enum KEY_1 #enum KEY_0 # #enum KEY_CE #enum KEY_8 #enum KEY_5 #enum KEY_2 #enum KEY_DOT # #enum KEY_BS #enum KEY_9 #enum KEY_6 #enum KEY_3 #enum KEY_EQU # #enum KEY_CHG #enum KEY_DIV #enum KEY_MUL #enum KEY_SUB #enum KEY_ADD //-------------------------------------- // メイン部 //-------------------------------------- *Main x=6+(64*4)+6 y=6+(32)+6+(24*5)+6 screen 0,x,y,SCREEN_NORMAL|SCREEN_TOOL:gsel 0,2 title "ミニ電卓" ;背景 y=(y/2) gradf 0,0,x,y,1,$339900,$CCFF66 gradf 0,y,x,y,1,$CCFF66,$009900 ;配置 objmode 2:font "HG明朝E",18 x=6 y=6+32+6 pos x,y:x+=64 button gosub "AC",*Push button gosub "7",*Push button gosub "4",*Push button gosub "1",*Push button gosub "0",*Push pos x,y:x+=64 button gosub "CE",*Push button gosub "8",*Push button gosub "5",*Push button gosub "2",*Push button gosub "・",*Push pos x,y:x+=64 button gosub "→",*Push button gosub "9",*Push button gosub "6",*Push button gosub "3",*Push button gosub "=",*Push pos x,y:x+=64 button gosub "±",*Push button gosub "÷",*Push button gosub "×",*Push button gosub "−",*Push button gosub "+",*Push objmode 1 ;液晶画面 font "HG明朝E",32 repeat DrawCalc 6,6,(6+64*4-1),(6+32-1) await 100 loop stop //-------------------------------------- // 液晶画面の描画 //-------------------------------------- #deffunc DrawCalc int _cx_,int _cy_,int _ex_,int _ey_ redraw 0 color $33,$66,$33:boxf(_cx_+0),(_cy_+0),(_ex_-0),(_ey_-0) color $CC,$DD,$CC:boxf(_cx_+1),(_cy_+1),(_ex_-1),(_ey_-1) color $66,$99,$66:pos(_cx_),(_cy_) mes "E-123'456'789.=" redraw 1 return //-------------------------------------- // 電卓ボタンの分岐 //-------------------------------------- *Push switch stat case KEY_AC: case KEY_CE: case KEY_BS: case KEY_CHG: case KEY_DOT: case KEY_0: case KEY_1: case KEY_2: case KEY_3: case KEY_4: case KEY_5: case KEY_6: case KEY_7: case KEY_8: case KEY_9: case KEY_ADD: case KEY_SUB: case KEY_MUL: case KEY_DIV: case KEY_EQU: swend return //------------------------------------------------------------------------------ // End of MiniCalc.hsp //------------------------------------------------------------------------------

このソースの screen 命令から font 命令までが、ウインドウに関連付けて管理されます。
よって、button 命令は、ボタン位置、ボタン表記、ボタンのジャンプ先を登録してます。
つまり、ボタンが押されると登録されていたラベルに自動的にジャンプ移動して処理をする。
また、複数のボタンを1つのラベルにまとめて、stat 変数でボタンの id を分岐することも可能。

・[HSP]整数電卓のソース
https://blog.goo.ne.jp/masaki_goo_2006/e/9c40c36e033354ec8135ee657b32b327

電卓のサンプルはこのページです。



Y_repeat

リンク

2019/8/3(Sat) 00:07:32|NO.88002

こんばんわ。
自分、たまにHSP公式BBSのまとめページ書いてて
ここのスレ、自分の中で結構面白いので
まとめページにしていいっすか?
ま、訪問者様、全然いないサイトっす

>科学太郎様

>オブジェクトのscreenへの関連付け
そういえばscreenごとにID割り振ってましたね
どっちかというとscreenオブジェクトの子オブジェクトだと思います

>ボタンの割り込みで止まってたのが再開するっていう意味らしいです
ってのが趣旨だったんですけど伝わらなかったようで残念です。
止まってたのが再開するのは無限ループ中に割り込み入った場所って趣旨でした

>このソースの screen 命令から font 命令までが、ウインドウに関連付けて管理されます。
font命令の次に無限ループに突入するので
無限ループの中から再開したのが
>font命令の次のrepeat
を通過するかんじだと

無限ループの中にbutton入れても
動くみたいです

button gosub "PUSH",*push while 1 cls 0 await 2000 button gosub "PUSH",*push await 2000 button gosub "PUSH",*push await 2000 button gosub "PUSH",*push await 2000 wend *push mes "push" await 2000 return



Y_repeat

リンク

2019/8/3(Sat) 00:19:13|NO.88003

ご参考までに
先日、まとめページを書きまして
賛否両論あったスレッドなので
ageは控えるんですが
(まとめページのURL載せたら同じっちゃ同じなんですが)
まとめページに転載した書き込みの人で転載されるの嫌な人が
おりましたらお知らせ下さいって趣旨で書き込みます

訪問していただけると嬉しいですが
不快な思いをするかもしれないということは覚悟して訪問してくださいね
君子危うきに近寄らず。なら訪問しない方が良いですよ
「(OSもどきという呼称が)きっついんや…」
http://zuzazann.main.jp/zuzazannzann/category2/category2/OS_modoki.html

>fさんへ
Sadoさんの書き込みへコメントしてあげて欲しいなーと思ってました
もう遅いかもしれませんが せっかく意見書いてくれたので
何らかの形でコメントしてあげて欲しいですね

自分、シリウスという更新しやすいらしいソフトでサイトをリニューアル中です
HSPスクリプトを載せるにあたりインデントしてくれなかったんですが
大文字スペースはインデント扱いらしく
そんなかんじでやっていこうと思ってます
それではよろしくお願いします
http://zuzazann.main.jp/zuzazannzann/



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