Re: 非同期ロードが終わらない ( No.1 ) |
- 名前:管理人 日時:2018/02/15 01:21
非同期読み込みをした場合は CheckHandleASyncLoad の戻り値が FALSE になるまで待つ必要があるのですが、
何時まで経っても FALSE にならないということでしょうか?
SetUseASyncLoadFlag(TRUE);
int handle = LoadGraph( FileName );
SetUseASyncLoadFlag(FALSE);
while( ProcessMessage() == 0 )
{
if( CheckHandleASyncLoad( handle ) == FALSE )
{
// 読み込みが完了したらループを抜ける
break ;
}
}
|
Re: 非同期ロードが終わらない ( No.2 ) |
- 名前:keen 日時:2018/02/15 10:14
>何時まで経っても FALSE にならないということでしょうか?
その通りです。1分2分と放置してもずっとTRUEを吐き続けています。-1にもFALSEにもなりません。
検証コードは以下の部分をWhile文で回していましたが、書くのを忘れていました。申し訳ありません。
使用時:
DX.ProcessMessage()
MsgBox(DX.CheckHandleASyncLoad(handle))
|
Re: 非同期ロードが終わらない ( No.3 ) |
- 名前:管理人 日時:2018/02/16 00:47
> 検証コードは以下の部分をWhile文で回していましたが、書くのを忘れていました。申し訳ありません。
> 使用時:
> DX.ProcessMessage()
> MsgBox(DX.CheckHandleASyncLoad(handle))
すみません、MsgBox とは、メッセージボックスを表示する機能でしょうか?
もしそうだとしますと、メッセージボックスは『OK』や『Cancel』などのボタンを押さないと消えないと思うのですが
この処理を While文でループするということでしょうか・・・?
1回のループを回すのにメッセージボックスの『OK』や『Cancel』などのボタンを押さなければならないとしますと
なかなか非同期読み込み処理が終わらないかもしれません、というのも、どうしてもメインスレッドで行わなければならない処理は
ProcessMessage の中で処理されるので、非同期読み込み処理を完了させるまでには何度か ProcessMessage を呼ばなければならないので・・・
|
Re: 非同期ロードが終わらない ( No.4 ) |
- 名前:keen 日時:2018/02/16 01:11
ええっと、説明が悪くて申し訳ありません。
>もしそうだとしますと、メッセージボックスは『OK』や『Cancel』などのボタンを押さないと消えないと思うのですが
>この処理を While文でループするということでしょうか・・・?
この部分は非同期ロードが終わらない事象を確認してから加えた部分です。
Thread.Sleepなどの後に呼び出すなど幾つか読み出しを待つ処理を加えたり、提示して頂いたようなFALSEが返らない間何もしないWhile文を加えてProcessMessageを行うような処理を行っても非同期読み出しは終了しませんでした。
もう一度書き直しましたが(VBで申し訳ありません)、以下のような処理でCheckHandleASyncLoad(handle)がFALSEになるのを待っても、ずっとTRUEしか返ってこないという状況です。
DX.SetUseASyncLoadFlag(DX.TRUE)
handle = DX.LoadGraph([ファイルパス]) 'ハンドル取得
DX.SetUseASyncLoadFlag(DX.FALSE)
While DX.CheckHandleASyncLoad(handle) <> DX.FALSE
DX.ProcessMessage()
End While
|
Re: 非同期ロードが終わらない ( No.5 ) |
- 名前:管理人 日時:2018/02/17 01:57
すみません、ProcessMessage と CheckHandleASyncLoad を使ったループは試されていたのですね
手元のバージョンでは問題なく非同期読み込みを実行することができたのですが、以前 keenさんに
お渡ししたバージョンでは非同期読み込みが正常に実行できませんでした
そして、すみません、失念していたのですが以前 keenさんに暫定最新版をお渡ししたあと
動画ファイルの非同期読み込みが正常に行えないバグが発覚して、修正したのでした
現在の暫定最新バージョンでは正常に非同期読み込みを行うことができますので、
お手数で申し訳ありませんが再度こちらをダウンロードしてください m(_ _;m
https://dxlib.xsrv.jp/temp/DxLibDotNet.zip // Windows版 .NET用
|
Re: 非同期ロードが終わらない ( No.6 ) |
- 名前:keen 日時:2018/02/17 13:07
返信ありがとうございます。
頂いたバイナリについて以下のコードで確認を行いましたが、音楽については正常に非同期ロードが行えるものの、やはり動画・画像については非同期読み込みが完了せず、ループを抜けることが出来ない状態でした。
If isAsyncLoad Then '非同期ロード待ち
While DX.CheckHandleASyncLoad(handle) <> DX.FALSE
DX.ProcessMessage()
End While
isAsyncLoad = False
End If
|
Re: 非同期ロードが終わらない ( No.7 ) |
- 名前:774 日時:2018/02/17 19:36
VB.NET、フォームなしで、動画をASyncで読み、再生し、終了する というコードを書いて見ました。
参照は DxLibDotNet.dll の方です。(Unicode版は SetUseMediaFoundationFlag が無い?ようなので)
ただし自環境では
SetUseMediaFoundationFlag(DX.FALSE) ... MP4を再生できない
SetMovieColorA8R8G8B8Flag(DX.TRUE) ... AVI(DivX), OGV以外でクラッシュする(MPEG1、MP4 など)
のため、いずれもコメントアウトしています。
※αチャネル付き動画は持っていないので未検証です。
Imports DxLibDLL
Module Module1
Sub Main()
DX.SetGraphMode(640, 480, 32)
DX.ChangeWindowMode(DX.TRUE)
' DX.SetUseMediaFoundationFlag(DX.FALSE)
If DX.DxLib_Init() < 0 Then GoTo EXIT_PROC
' DX.SetMovieColorA8R8G8B8Flag(DX.TRUE)
DX.SetDrawScreen(DX.DX_SCREEN_BACK)
Dim r, data_handle, ct
DX.SetUseASyncLoadFlag(DX.TRUE)
data_handle = DX.LoadGraph(てきとーな動画ファイル)
DX.SetUseASyncLoadFlag(DX.FALSE)
ct = 0
Do ' 読んでいる間、カウンターでも表示しよう
ct = ct + 1
r = DX.CheckHandleASyncLoad(data_handle)
DX.ClearDrawScreen()
System.Threading.Thread.Sleep(1)
DX.DrawString(8, 8, "Count = " + ct.ToString(), DX.GetColor(255, 255, 255))
DX.ScreenFlip()
If DX.ProcessMessage() = -1 Then GoTo EXIT_PROC
Loop While r = DX.TRUE
Dim bOK As Boolean
bOK = True
DX.PlayMovieToGraph(data_handle)
Do
DX.DrawExtendGraph(0, 0, 640, 480, data_handle, DX.FALSE)
DX.ScreenFlip()
DX.WaitTimer(1)
If DX.GetMovieStateToGraph(data_handle) <> 1 Then bOK = False
If DX.ProcessMessage() = -1 Then bOK = False
Loop While bOK = True
EXIT_PROC:
If DX.DxLib_IsInit() = DX.TRUE Then DX.DxLib_End()
End Sub
End Module
|
Re: 非同期ロードが終わらない ( No.8 ) |
- 名前:管理人 日時:2018/02/18 02:00
うーん謎ですね・・・
手元の環境で正常に動作することを確認した以下の C# のプログラムをビルドして作成した実行ファイルを
こちらにアップしましたので、よろしければ keenさんの環境でも正常に動作するかお試しいただけないでしょうか? m(_ _;m
https://dxlib.xsrv.jp/temp/ASyncLoadDotNetTest.zip
using System;
using DxLibDLL;
namespace DxLibDLLTest
{
static class Program
{
[STAThread]
static void Main()
{
// ウィンドウモードで起動
DX.ChangeWindowMode( DX.TRUE );
// 背景をグレーにする
DX.SetBackgroundColor( 128,128,128 );
// DXライブラリの初期化
if( DX.DxLib_Init() < 0 )
{
return;
}
// Test2.bmp を非同期読み込み
DX.SetUseASyncLoadFlag( DX.TRUE );
int GraphHandle = DX.LoadGraph( "Test2.bmp" ) ;
DX.SetUseASyncLoadFlag( DX.FALSE );
// 読み込み完了を待つ
while( DX.ProcessMessage() == 0 )
{
if( DX.CheckHandleASyncLoad( GraphHandle ) == DX.FALSE )
break;
}
// 描画先を裏画面にする
DX.SetDrawScreen( DX.DX_SCREEN_BACK );
// メインループ
while( DX.ProcessMessage() == 0 )
{
// 画面に Test2.bmp を描画する
DX.ClearDrawScreen() ;
DX.DrawGraph( 0, 0, GraphHandle, DX.TRUE ) ;
DX.ScreenFlip() ;
}
}
}
}
> 774さん
載せていただいたコードを C#言語にした書き換えて実行してみましたが、正常に動作しました
774さんの環境では正常に動作しない、ということでしょうか?
> 参照は DxLibDotNet.dll の方です。(Unicode版は SetUseMediaFoundationFlag が無い?ようなので)
Unicode版にも SetUseMediaFoundationFlag はありますが・・・
ご覧になっているバージョンの更新日時はどのようになっていますでしょうか?
|
Re: 非同期ロードが終わらない ( No.9 ) |
- 名前:774 日時:2018/02/18 03:51
> 774さんの環境では正常に動作しない、ということでしょうか?
> ...
> Unicode版にも SetUseMediaFoundationFlag はありますが・・・
すみません、前者は「これは動きました」という意味で書きました。後者は.vbprojを再確認すると
参照が旧バージョンのファイルをさしていましたので、設定し直して問題ないことを確認いたしました。
お手数をおかけしました。
|
Re: 非同期ロードが終わらない ( No.10 ) |
- 名前:keen 日時:2018/02/18 21:24
>管理人様
返信が遅れました。
提示していただいたプログラムについては正常に動作することを確認しました。
自分の作っているプログラムではメインのフォームと描画用スレッドを持ち、そこでDxLib関連の処理を行うという構造になっているので、問題はそこに有るのかもしれません。
一旦問題を再現できるプログラムを作成した後に返信を行います。
|
Re: 非同期ロードが終わらない ( No.11 ) |
- 名前:keen 日時:2018/02/18 22:05
>774様
申し訳ありません、返信を忘れていました。
こちらでも動作を確認できましたが、やはり自分のプログラムでは動作しないという状況です。
>管理人様
サンプルの作成をし、メールでプロジェクトを送信しました。
内容はメールに添付したとおりですが、こちらにもプログラムを載せます。
内容としては、ロードと同時に描画スレッドを作成し、ボタンを押すとロードが開始され、ロードが終わると再生/描画が開始されるというものです。
DrawLoopではLoadGraphを、SoundLoopではLoadSoundMem関数を利用しています。
サンプルプログラムで利用している音源に関しては、下記のサイトのものを利用させていただきました。
ttp://www.sousound.com/music_sample.html
◆Form1.vb
Public Class Form1
Private Drawer As DrawClass
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Drawer = New DrawClass
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Drawer.StartLoad = True
End Sub
End Class
◆DrawClass.vb
Imports DxLibDLL
Public Class DrawClass
'スレッド本体の制御関連
Private DrawThread As Threading.Thread
Public StartLoad As Boolean
'DxLibのオプション設定と初期化
Private Sub InitDxLib()
Dim screen As Screen = Screen.AllScreens(0) '描画先ディスプレイを取得
'解像度と色深度設定
DX.SetGraphMode(screen.Bounds.Width, screen.Bounds.Height, 32)
'描画ウィンドウの位置を設定
DX.SetWindowInitPosition(screen.Bounds.X, screen.Bounds.Y)
'ウィンドウモード(枠無し)で起動
DX.ChangeWindowMode(DX.TRUE)
DX.SetWindowStyleMode(2)
'ウィンドウがアクティブじゃない時も処理を続ける
DX.SetAlwaysRunFlag(DX.TRUE)
'DxLib_Init()を呼んだwindow以外からも操作を可能にする
DX.SetMultiThreadFlag(DX.TRUE)
'透過チャンネルを有効に設定
DX.SetMovieColorA8R8G8B8Flag(DX.TRUE)
'一度裏画面に描画を行い、Flipすると描画が行われるように設定(ダブルバッファリング)
DX.SetDrawScreen(DX.DX_SCREEN_BACK)
'2枚以上の画面にScreen.flipする場合デフォルトではVSync待ちで遅くなるのでVSyncは切る
DX.SetWaitVSyncFlag(DX.FALSE)
'多分これが無いとプログラム本体のIME関連動作がおかしくなる
DX.SetUseIMEFlag(DX.TRUE)
'開発したPCの環境ではこれを使わないとAccessViolationで落ちる、別のPCでは逆にこれを有効にしているとMP4が再生できない?
DX.SetUseMediaFoundationFlag(DX.FALSE)
If DX.DxLib_Init() = -1 Then
'起動できなかった場合はアプリケーションを終了する
MsgBox("初期化に失敗しました。", MsgBoxStyle.Critical)
End
End If
End Sub
'再生ループ
Private Sub DrawLoop()
Dim handle As Integer
Dim alpha As Byte = 255
While True
If StartLoad Then
DX.SetUseASyncLoadFlag(DX.TRUE)
handle = DX.LoadGraph("Test2.BMP", DX.TRUE)
DX.SetUseASyncLoadFlag(DX.FALSE)
StartLoad = False
ElseIf DX.CheckHandleASyncLoad(handle) <> DX.FALSE Then
DX.ProcessMessage()
Else
DX.ClearDrawScreen() '描画先初期化
'透過値をセットして描画
DX.SetDrawBlendMode(DX.DX_BLENDMODE_ALPHA, alpha)
DX.DrawExtendGraph(0, 0, 1000, 1000, handle, DX.TRUE)
DX.ScreenFlip()
End If
End While
End Sub
'音楽版
Private Sub SoundLoop()
Dim handle As Integer
Dim alpha As Byte = 255
Dim playStarted = False
While True
If StartLoad Then
DX.SetUseASyncLoadFlag(DX.TRUE)
handle = DX.LoadSoundMem("mondo_01.mp3")
DX.SetUseASyncLoadFlag(DX.FALSE)
StartLoad = False
ElseIf DX.CheckHandleASyncLoad(handle) <> DX.FALSE Then
DX.ProcessMessage()
Else
If Not playStarted Then
DX.PlaySoundMem(handle, DX.DX_PLAYTYPE_BACK)
playStarted = True
End If
End If
End While
End Sub
'初期化
Public Sub New()
InitDxLib()
StartLoad = False
DrawThread = New Threading.Thread(AddressOf DrawLoop) With {
.IsBackground = True
}
DrawThread.Start()
End Sub
End Class
|
Re: 非同期ロードが終わらない ( No.12 ) |
- 名前:keen 日時:2018/02/18 22:42
こちらでも調査を続けましたが、現在公開されている3.14a以降の全バージョンにおいてこのやり方での画像ロードは不可能のようでした……。
|
Re: 非同期ロードが終わらない ( No.13 ) |
- 名前:管理人 日時:2018/02/18 23:44
> 774さん
ご返答ありがとうございます
問題があったわけではなかったようで安心しました
> keenさん
> 自分の作っているプログラムではメインのフォームと描画用スレッドを持ち、そこでDxLib関連の処理を行うという構造になっているので、問題はそこに有るのかもしれません。
おそらく『メインのフォーム』とは別の『描画用スレッド』でDXライブラリの関数を使用していることが原因です
DXライブラリでは DxLib_Init を呼ぶスレッドとDXライブラリの関数を呼ぶスレッドが異なる場合の動作の保証はしていません
( DXライブラリは複数のスレッドから関数を呼んでも問題なく動作する『スレッドセーフ』タイプのライブラリではありません )
非同期読み込み機能も DxLib_Init が呼ばれたスレッドとは別のスレッドで行われることは想定していないので、
非同期読み込みが正常に動作しなかったとしても対応の範囲外となります
申し訳ありませんがプログラムの構造を変更して対応してください m(_ _;m
( 一応、描画スレッドで DxLib_Init を呼べば正常に読み込みが完了することは確認できました )
|
Re: 非同期ロードが終わらない ( No.14 ) |
- 名前:keen(解決) 日時:2018/02/19 00:38
解決しました!
スレッドの外側でなく、以下のようにスレッドの開始時に呼ぶことで非同期読み込みが正常に完了することを確認できました!
ライブラリの基本構造を理解しておらず、お手数おかけいたしました。
'再生ループ
Private Sub DrawLoop()
InitDxLib()
Dim handle As Integer
Dim alpha As Byte = 255
While True
If StartLoad Then
DX.SetUseASyncLoadFlag(DX.TRUE)
handle = DX.LoadGraph("Test2.BMP", DX.TRUE)
DX.SetUseASyncLoadFlag(DX.FALSE)
StartLoad = False
ElseIf DX.CheckHandleASyncLoad(handle) <> DX.FALSE Then
DX.ProcessMessage()
Else
DX.ClearDrawScreen() '描画先初期化
'透過値をセットして描画
DX.SetDrawBlendMode(DX.DX_BLENDMODE_ALPHA, alpha)
DX.DrawExtendGraph(0, 0, 1000, 1000, handle, DX.TRUE)
DX.ScreenFlip()
End If
End While
End Sub
|