cocos2d-x(WinRT) UWP開発で2回目のBGMの再生でエラーが起きる
原因:cocos2d-xのバグです。
BGMを再生するときにLocalStateフォルダにキャッシュファイルを作成しています。
それを読み込む機能がまだUWP(WinRT)では足りてないことが原因でした。
ファイル名+ハッシュ値+.bat
bgm01_131278991235742657131278997873415683.dat
C:\Users*****\AppData\Local\Packages\A2488D1E-A992-4F30-97A0-6C68D4046731_e8xk87pxx0yyw\LocalState
この中にBGMを再生させるだけでキャッシュファイルが作成され保存されます。
この仕組みは、たぶん再生時間の長いファイルに対して行われる仕組みに感じます。
SEなども同じ処理を通るのですが、キャッシュファイルは作成されていませんでした。
問題なのは、そこへ参照するためのPathが変でした。
キャッシュファイルを参照して読み込めずにいるからエラーが出てました。
誤り coin_getの前に//が入っている
C:/Users/****/AppData/Local/Packages/A2488D1E-A992-4F30-97A0-6C68D4046731_e8xk87pxx0yyw/LocalState//coin_get_131278900066040543131278993999933544.dat
正しい coin_getの前は/だけ
C:/Users/****/AppData/Local/Packages/A2488D1E-A992-4F30-97A0-6C68D4046731_e8xk87pxx0yyw/LocalState/coin_get_131278900066040543131278993999933544.dat
std::string computeHashForFile(const std::string& filePath)
{
std::string ret = filePath;
size_t pos = ret.find_last_of('/') + 1; //← +1してあげて / が入らないようにしてください。これがあると//になってエラーが起きます
if (pos != std::string::npos) {
ret = ret.substr(pos);
}
pos = ret.find_last_of('.');
if (pos != std::string::npos) {
ret = ret.substr(0, pos);
}
CREATEFILE2_EXTENDED_PARAMETERS extParams = { 0 };
extParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
extParams.dwFileFlags = FILE_FLAG_RANDOM_ACCESS;
extParams.dwSecurityQosFlags = SECURITY_ANONYMOUS;
extParams.dwSize = sizeof(extParams);
extParams.hTemplateFile = nullptr;
extParams.lpSecurityAttributes = nullptr;
Microsoft::WRL::Wrappers::FileHandle file(CreateFile2(std::wstring(filePath.begin(), filePath.end()).c_str(), GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, &extParams));
if (file.Get() != INVALID_HANDLE_VALUE) {
FILE_BASIC_INFO fInfo = { 0 };
if (GetFileInformationByHandleEx(file.Get(), FileBasicInfo, &fInfo, sizeof(FILE_BASIC_INFO))) {
std::stringstream ss;
ss << ret << "_";
ss << fInfo.CreationTime.QuadPart;
ss << fInfo.ChangeTime.QuadPart;
ret = ss.str();
}
}
return ret;
}
上記の修正だけではエラーが起きます。
ファイルサイズを取得する部分が記述されていないためエラーが起きます。
一時的に回避するためにキャッシュファイルを読み込む部分をコメントアウトして対応します。
//349行目付近をコメントアウトしておく
//getFileSizeでエラーが起きる
/*
if (createMappedCacheFile(_filePath, _mappedWavFile, ".dat")) {
_isStreaming = _largeFileSupport;
_audioSize = FileUtils::getInstance()->getFileSize(_mappedWavFile);
if (!_largeFileSupport) {
buffer.resize(_audioSize);
readFromMappedWavFile(buffer.data(), 0, _audioSize, nullptr);
chunkify(buffer);
}
break;
}
*/
ここにもhttps://github.com/cocos2d/cocos2d-x/pull/15097/files
修正方法がありましたがキャッシュを強制的に削除する方法です。