| 
					 
							
													 
							
						 
						
 
 | 
 | 
 
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つのプログラムを結合すれば 
良いだけです。 
 
皆さんありがとうございました。 
またよろしくお願いします。 
 
 |   
  
					 |