|
|
2008/10/29(Wed) 12:21:10|NO.20480
以下のプログラムは二つのプログラムを簡略化したものですが、プログラムAのwait100で1秒
待っている間にブログラムBを実行したいのですがどのようにすれば良いか教えて下さい。
但しプログラムBの1ループは200ms〜2000msまで変化するものとします。
screen 1
title "プログラムB"
screen 0
title "プログラムA"
////// プログラムA
repeat 2
repeat 5
color 255,255,255:boxf
pos 250,200
color:mes "処理1 実行中"+(5-cnt)
wait 100;ここでプログラムBを実行したい
loop
repeat 3
color 255,255,255:boxf
pos 250,200
color:mes "処理2 実行中"+(3-cnt)
wait 100;ここでプログラムBを実行したい
loop
loop
color 255,255,255:boxf
pos 250,200
color:mes "終わり"
stop
/////// プログラムB
gsel 1
repeat
color 255,255,255:boxf
pos 250,200
color:mes "処理3 実行中"+cnt
await 200;〜2000
loop
|
|
2008/10/29(Wed) 13:01:28|NO.20481
1秒待つ間に2秒かかる処理はできませんよね。
そのように遅れた場合には、Aの次の処理と並行してBの残りも処理したい ということでしょうか?
|
|
2008/10/29(Wed) 15:06:13|NO.20483
>そのように遅れた場合には、Aの次の処理と並行してBの残りも処理したい ということでしょうか?
そういうことです。
|
|
2008/10/29(Wed) 16:56:28|NO.20484
HSPでスレッドが作れん以上、全部自分で管理するしか無かろうよ。
*lp
gosub *seq_a
gosub *seq_b
await 0
goto *lp
*seq_a
return
*seq_b
return
こんな感じかね?
|
|
2008/10/29(Wed) 17:12:43|NO.20486
・・・というか・・・
Aの1回目の5回のループ中、1000ms毎に1回づつ、
2回のめ3回のループ中に1000ms毎に1回づつ、
そのセットを2回だと?
1000ms毎に16回Bの処理を呼び出して、しかもBの処理は1回の処理に200から2000msかかるってか。
Bの処理が常に2000msかかった時はどうするんだ?
全部個別に処理するのか?
それとも必要回数処理できれば、Bの処理が自分の処理で送れる遅延は許されるのか?
|
|
2008/10/29(Wed) 22:54:22|NO.20492
このページは参考になりますか?
ttp://fs-cgi-basic01.freespace.jp/~hsp/ver3/hsp3.cgi?print+200707/07100036.txt
(h 抜きです。)
|
|
2008/10/30(Thu) 10:01:23|NO.20494
ちょっと説明不足でした。実はBの処理は所々にwaitやawaitが入っていて一度に1loopを実行するもの
ではなく休み休みに1周する時間が条件によって約200ms〜2000msくらいかかるというものです。更に言うと
休み〜休みまでの最長処理時間(割り込みの効かない時間)は300ms以内です。
紹介いただいたURLはマルチスレッドのことですよね、一応マルチスレッドは調べたのですがWM_TIMERを使う
として2ヶ所のwait100の対処方法がわかりません。
|
|
2008/10/30(Thu) 10:58:08|NO.20495
await1でloop回すと無駄に時間かかるので、こっちに修正して貼り直し。
こうすりゃ1loopで処理できるべ。
#uselib "winmm.dll"
#cfunc timeGetTime "timeGetTime"
seq_a_ctl = 0
*lp
stick st
// シーケンスが待機状態で、スペースが押されたら実行開始
if ( st & 16 ) != 0 && seq_a_ctl = 0 : seq_a_ctl = 1
gosub *seq_a
await 0
goto *lp
*seq_a
switch seq_a_ctl
case 0
// 待機
swbreak
case 1
// 処理1を行う
mes "処理1実行"
seq_a_ctl = 2
seq_a_tic = timegettime() + 1000
swbreak
case 2
// wait1
if timegettime() >= seq_a_tic : seq_a_ctl = 3
swbreak
case 3
// 処理2を行う
mes "処理2実行"
seq_a_ctl = 4
seq_a_tic = timegettime() + 2000
swbreak
case 4
// wait2
if timegettime() >= seq_a_tic : seq_a_ctl = 5
swbreak
case 5
// 作業終了、待機へ
mes "作業終了"
seq_a_ctl = 0
swend
return
|
|
2008/10/30(Thu) 17:27:58|NO.20503
f(浮気中)さんすみません、よく分らないのですが・・・
*lp〜goto *lpをプログラムBに組み込んで*seq_aの中にプログラムAを組み込むということですか?
Aのプログラムは待っている時間のほうが長いのでその間にBが走れば平行処理ができるのではないかと・・
|
|
2008/10/30(Thu) 22:30:38|NO.20512
いや、
*lp - goto *lpのループの中に、
gosub *seq_aを参考にして、gosub *seq_bとか作ればいいでそ。
で、seq_aの方でb側のシーケンスの開始を入れるようにすればいい。
ただし、b側が処理終わってるかどうかの判定も、その場合はどうするのかも考えなきゃいかん。
その辺は前に聞いたが、返答聞いて無いのでアドバイスのしようも無い。
|
|
2008/11/1(Sat) 09:48:28|NO.20543
>b側が処理終わってるかどうかの判定も、
B側はプログラム起動から終了までloopしっぱなしなので終了するという考えはありません。
むしろBが実行している間にAを実行すると言った方が良いかもしれません。
Window上ではAもBもそれぞれ単独ならば同時実行できますがデーター(変数)を共有したいのでAとBを
統合して1つのプログラムにしたいのですが・・・
|
|
2008/11/1(Sat) 11:51:30|NO.20547
>B側はプログラム起動から終了までloopしっぱなしなので終了するという考えはありません。
むしろBが実行している間にAを実行すると言った方が良いかもしれません。
同じ事だと思うがなあ。
20495で書いたサンプルは理解できている?
Bがループしてるのなら、Bでループしながら、必要に応じてAの開始を入れれば良いだけだと思うんだが。
Bの側もSeq_aみたいな構造にしておかないといけないが。
まず、簡単な動作で、実験スクリプト書いてみ?
そんな難しい事じゃないぞ。どちらかと言うと面倒くさいだけで。
|
|
2008/11/1(Sat) 11:51:40|NO.20548
>データー(変数)を共有したいのでAとBを統合して1つのプログラムにしたい
逆に、共有ができれば1つのプログラムにしなくてもいいってーのであれば、共有はできます。
#include "hspext.as"
#include "hsp3util.as"
aplsel "TESTPROGRAM",0
if (stat){
;初回
x=rnd(ginfo_dispx)
y=rnd(ginfo_dispy)
vx=2 : vy=2
sdim infobuf
screen 0,240,240,0,,,240,240 : title "おや"
screen 2,64,32,2 : title "TESTPROGRAM"
statictext infobuf,64,32
gsel 0
repeat
x+=vx : y+=vy
if ((x>=ginfo_dispx-1)|(x<=0)) : vx=vx*-1
if ((y>=ginfo_dispy-1)|(y<=0)) : vy=vy*-1
infobuf=""+x+"\n"+y
gsel 2 : statictext_set 0,infobuf : gsel 0
title "おや - "+x+","+y
gosub *DRAW
wait 1
loop
}else{
screen 0,240,240,0,,,240,240 : title "こ"
sdim infobuf,64
notesel infobuf
aplobj "Static",0 : if stat : dialog "情報取得失敗",1:end
repeat
aplget infobuf
if infobuf="" : end
noteget xstr,0
noteget ystr,1
x=int(xstr) : y=int(ystr)
gosub *DRAW
wait 1
loop
}
*DRAW
redraw 0
color 0,0,0 : boxf
if((ginfo_wx1<x)&(ginfo_wy1<y)&(ginfo_wx2>x)&(ginfo_wy2>y)){
pos x-ginfo_wx1,y-ginfo_wy1
color 255,255,255 : mes "●"
redraw 1
}
redraw 1
return
2つ以上起動してみてください。
1つめが親として座標を管理しています。
2つめ以降は、その座標を読み取って動作します。
| |
|
2008/11/1(Sat) 11:59:39|NO.20549
よく見たら肝心な所の返答が抜けてるな。
AとBが入れ替わっただけで。
もう一度聞くが、
「じゃあ、BのループからAを実行しようとした時、Aが実行中だったらどうするのよ?」
呼び出した回数だけ、同時に並行処理するAが必要なのか?
呼び出した回数だけ、Aが実行されれば、並行処理しなくても良いのか?
呼び出した時にAが実行中なら、Aは処理しなくて良いのか?
それによっちゃやり方が変るぞ。
|
|
2008/11/1(Sat) 17:46:14|NO.20554
f(浮気中)さんありがとうございます。
>同じ事だと思うがなあ。
そうですよね。
>20495で書いたサンプルは理解できている?
提示頂いたサンプルは処理1を実行して1秒たったら処理2を実行し更に2秒たったら終了しますよね。
こちらの希望は処理1を5回繰り返した後処理2を3回繰り返したいのですが、その場合case 1を5回
繰り返したらcase 2を3回繰り返せば良いということですか?だとすると
>seq_a_tic = timegettime() + 2000
の意味がわかりません。
>「じゃあ、BのループからAを実行しようとした時、Aが実行中だったらどうするのよ?」
この認識がちがうのかな、Bが実行中ということはAがwait100かstopしているときだけです。
>呼び出した回数だけ、同時に並行処理するAが必要なのか?
>呼び出した回数だけ、Aが実行されれば、並行処理しなくても良いのか?
>呼び出した時にAが実行中なら、Aは処理しなくて良いのか?
頭が混乱して何をどう答えれば良いのか分けが分らなくなってきた。並行処理はしたいのですが
処理はAが優先します。いやこう答えるとまた誤解を招くかな?
SYAMさんありがとうございます。
>逆に、共有ができれば1つのプログラムにしなくてもいいってーのであれば、共有はできます。
そうなんですか。aplselは使ったこと無いのでサンプル研究してデーターの受け渡し方を勉強してみます。
あっ、Aの処理1も処理2もカウントダウンとコマンド1発なので瞬時の動作です。だから殆んどwait100で
待っているだけです。
|
|
2008/11/1(Sat) 23:23:56|NO.20563
APIのタイマーでも使えば?
#include "user32.as"
//タイマー設定
oncmd gosub *Timer, 0x113 //WM_TIMER
input a
input b
input c
SetTimer hwnd, 1, 100, 0
SetTimer hwnd, 2, 200, 0
SetTimer hwnd, 3, 500, 0
stop
*Timer
switch wParam
case 1 //100msで1回
objprm 0, a+1
swbreak
case 2 //200msで1回
objprm 1, b+1
swbreak
case 3 //500msで1回
objprm 2, c+1
swbreak
swend
return
|
|
2008/11/2(Sun) 03:00:11|NO.20567
>提示頂いたサンプルは処理1を実行して1秒たったら処理2を実行し更に2秒たったら終了しますよね。
そうね。
>こちらの希望は処理1を5回繰り返した後処理2を3回繰り返したいのですが、その場合case 1を5回
繰り返したらcase 2を3回繰り返せば良いということですか?だとすると
その辺は考えて組みなおしてくれないか。
俺は余程じゃない限り「まんま答え」なサンプルは出さん。
十分参考になるだろ。考えて作ってくれ。
>seq_a_tic = timegettime() + 2000
の意味がわかりません。
仮処理として、「処理1実行と表示」処理をして1000ms待機、「処理2実行と表示」処理をして2000ms待機しているだけだが。
timegettimeが意味不明と言うならググれ。次の処理へ移るまでのwait終了時間を、現在の時間から2000ms後と指定しているだけだ。
あくまで仮に提示しただけで、そちらが要望している「まんま」ではない。
>この認識がちがうのかな、Bが実行中ということはAがwait100かstopしているときだけです。
>頭が混乱して何をどう答えれば良いのか分けが分らなくなってきた。並行処理はしたいのですが
処理はAが優先します。いやこう答えるとまた誤解を招くかな?
OK,整理しよう。
・A処理とB処理がある。
・常時B処理ループが起動している。
・B処理ループは、A処理がwait中か、停止している間動作する。
・処理はA処理が優先する。
これで良いのか?
これだけなら、出したサンプルの機能だけで実現しそうにしか思えないのだが、
(むしろそのままの処理をしているようにしか見えないが)何が不足しているのか?
|
|
2008/11/2(Sun) 22:34:16|NO.20581
皆さんありがとうございます。
>・A処理とB処理がある。
>・常時B処理ループが起動している。
>・B処理ループは、A処理がwait中か、停止している間動作する。
>・処理はA処理が優先する。
>これで良いのか?
その通りです。
皆さんのサンプルを参考に改造してみみました。(無駄が多いかと思いますが)
やりたいことは↓こんな感じです。だいぶ目的にかなってきたのですがプログラムAの1秒待ちは
プログラムBのif timegettime() >= seq_a_tic の問い合わせ位置によって1秒+Xmsオーバーし
ますよね。Aの処理回数が多くなると誤差が蓄積されるのでこれをなるべく正確にしたいのですが・・・
#uselib "winmm.dll"
#cfunc timeGetTime "timeGetTime"
////// プログラムB
screen 0,200,200
title "プログラムB"
button gosub "start",*progA
repeat
color 255,255,255:boxf
pos 50,100
color:mes "処理3 実行中"+cnt
await 200;〜2000
if st & timegettime() >= seq_a_tic :gosub *seq1
if st2 & timegettime() >= seq_a_tic :gosub *seq2
loop
////// プログラムA
*progA
screen 1,200,200
title "プログラムA"
st=1:count=5
*seq1
gsel 1
color 255,255,255:boxf
pos 50,100
color:mes "処理1 実行中"+count
if count=0:st=0:st2=1:count=3:gsel 0:return
count--
seq_a_tic = timegettime() + 1000
gsel 0
return
*seq2
gsel 1
color 255,255,255:boxf
pos 50,100
color 255:mes "処理2 実行中"+count
if count=0:goto *seq3
count--
seq_a_tic = timegettime() + 1000
gsel 0
return
*seq3
color 255,255,255:boxf
pos 50,100
color :mes "終わり"
st=0:st2=0
gsel 0
return
| |
|
2008/11/3(Mon) 00:55:37|NO.20589
これではっきりした。
処理A側が「実行中」にBからAの開始がかかった場合、
Aは現在の処理を破棄して最初から実行すればいいんだな。
というか、なんでswitch使ってるか理解はしてもらってなかったようだな。
#uselib "winmm.dll"
#cfunc timeGetTime "timeGetTime"
screen 0,200,200 : title "プログラムB"
button gosub "start",*seq_a_trg
screen 1,200,200 : title "プログラムA"
now = timegettime()
repeat
gsel 0
color 255 , 255 , 255 : boxf
color : pos 50,100 : mes "処理3 実行中" + cnt
// 200ms(〜2000ms)待機
b_tic = now + 200 // 〜2000
while b_tic >= now
now = timegettime()
gosub *seq_a
await 0
wend
loop
*seq_a_trg
seq_a_ctl = 1
return
*seq_a
switch seq_a_ctl
case 0
// 待機
swbreak
case 1
// 初期化
seq_a_ctl = 2
seq_a_tic = now + 1000
seq_a_cnt = 5
swbreak
case 2
// 処理1
gsel 1: color 255 , 255 , 255 : boxf
color : pos 50 , 100 : mes "処理1 実行中" + seq_a_cnt
seq_a_ctl = 3
swbreak
case 3
// 処理1 時間待ち
if seq_a_tic <= now : seq_a_ctl = 4
swbreak
case 4
// 処理1 ループ
seq_a_cnt--
if seq_a_cnt >= 0 {
seq_a_tic = now + 1000
seq_a_ctl = 2
}
else { seq_a_ctl = 5 }
swbreak
case 5
// 処理2 初期化
seq_a_tic = now + 1000
seq_a_cnt = 5
seq_a_ctl = 6
swbreak
case 6
// 処理2
gsel 1: color 255 , 255 , 255 : boxf
color 255: pos 50 , 100 : mes "処理2 実行中" + seq_a_cnt
seq_a_ctl = 7
swbreak
case 7
// 処理2 時間待ち
if seq_a_tic <= now : seq_a_ctl = 8
swbreak
case 8
// 処理2 ループ
seq_a_cnt--
if seq_a_cnt >= 0 {
seq_a_tic = now + 1000
seq_a_ctl = 6
}
else { seq_a_ctl = 9 }
swbreak
case 9
// 終了
gsel 1 : color 255 , 255 , 255 : boxf
color : pos 50 , 100 : mes "終わり"
seq_a_ctl = 0
swend
return
こうやって、B処理の待機中にA処理を呼び出し続ければ良い事じゃないか?
| |
|
2008/11/3(Mon) 18:22:54|NO.20597
f(浮気中)さん何回もすみません。
>Aは現在の処理を破棄して最初から実行すればいいんだな。
これは良いわけではありませんがボタンを押せないようにすれば良いのであまり気にしていません。
>なんでswitch使ってるか理解はしてもらってなかったようだな。
最初はWM_TIMERの割り込みで時間管理しようと思っていたのですが途中からtimegettimeに変更した
ら気が付いたらif・・・になっていた、後からこんな時こそswitch使うべきだったと・・・
とりあえずおかげさまで方向性は見えてきました。後はサンプルを元に2つのプログラムを結合すれば
良いだけです。
皆さんありがとうございました。
またよろしくお願いします。
|
|