1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-16 06:29:56 +00:00

Use normalized path for SoundManager::playPlaylist

This commit is contained in:
elsid 2024-03-12 00:40:03 +01:00
parent 38b005cda6
commit e11a5a4352
No known key found for this signature in database
GPG key ID: 4DE04C198CBA7625
15 changed files with 91 additions and 25 deletions

View file

@ -95,7 +95,7 @@ void readVFS(std::unique_ptr<VFS::Archive>&& archive, const std::filesystem::pat
vfs.addArchive(std::move(archive)); vfs.addArchive(std::move(archive));
vfs.buildIndex(); vfs.buildIndex();
for (const auto& name : vfs.getRecursiveDirectoryIterator("")) for (const auto& name : vfs.getRecursiveDirectoryIterator())
{ {
if (isNIF(name.value())) if (isNIF(name.value()))
{ {

View file

@ -28,7 +28,7 @@ void CSMWorld::Resources::recreate(const VFS::Manager* vfs, const char* const* e
size_t baseSize = mBaseDirectory.size(); size_t baseSize = mBaseDirectory.size();
for (const auto& filepath : vfs->getRecursiveDirectoryIterator("")) for (const auto& filepath : vfs->getRecursiveDirectoryIterator())
{ {
const std::string_view view = filepath.view(); const std::string_view view = filepath.view();
if (view.size() < baseSize + 1 || !view.starts_with(mBaseDirectory) || view[baseSize] != '/') if (view.size() < baseSize + 1 || !view.starts_with(mBaseDirectory) || view[baseSize] != '/')

View file

@ -126,7 +126,7 @@ namespace MWBase
virtual bool isMusicPlaying() = 0; virtual bool isMusicPlaying() = 0;
///< Returns true if music is playing ///< Returns true if music is playing
virtual void playPlaylist(const std::string& playlist) = 0; virtual void playPlaylist(VFS::Path::NormalizedView playlist) = 0;
///< Start playing music from the selected folder ///< Start playing music from the selected folder
/// \param name of the folder that contains the playlist /// \param name of the folder that contains the playlist
/// Title music playlist is predefined /// Title music playlist is predefined

View file

@ -67,7 +67,8 @@ namespace MWGui
!= supported_extensions.end(); != supported_extensions.end();
}; };
for (const auto& name : mResourceSystem->getVFS()->getRecursiveDirectoryIterator("Splash/")) constexpr VFS::Path::NormalizedView splash("splash/");
for (const auto& name : mResourceSystem->getVFS()->getRecursiveDirectoryIterator(splash))
{ {
if (isSupportedExtension(Misc::getFileExtension(name))) if (isSupportedExtension(Misc::getFileExtension(name)))
mSplashScreens.push_back(name); mSplashScreens.push_back(name);

View file

@ -402,7 +402,8 @@ namespace MWGui
std::vector<std::string> availableLanguages; std::vector<std::string> availableLanguages;
const VFS::Manager* vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); const VFS::Manager* vfs = MWBase::Environment::get().getResourceSystem()->getVFS();
for (const auto& path : vfs->getRecursiveDirectoryIterator("l10n/")) constexpr VFS::Path::NormalizedView l10n("l10n/");
for (const auto& path : vfs->getRecursiveDirectoryIterator(l10n))
{ {
if (Misc::getFileExtension(path) == "yaml") if (Misc::getFileExtension(path) == "yaml")
{ {

View file

@ -29,6 +29,8 @@
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwsound/constants.hpp"
#include "actor.hpp" #include "actor.hpp"
#include "actors.hpp" #include "actors.hpp"
#include "actorutil.hpp" #include "actorutil.hpp"
@ -1678,12 +1680,12 @@ namespace MWMechanics
if (mMusicType != MWSound::MusicType::Explore && !hasHostiles if (mMusicType != MWSound::MusicType::Explore && !hasHostiles
&& !(player.getClass().getCreatureStats(player).isDead() && musicPlaying)) && !(player.getClass().getCreatureStats(player).isDead() && musicPlaying))
{ {
MWBase::Environment::get().getSoundManager()->playPlaylist(std::string("Explore")); MWBase::Environment::get().getSoundManager()->playPlaylist(MWSound::explorePlaylist);
mMusicType = MWSound::MusicType::Explore; mMusicType = MWSound::MusicType::Explore;
} }
else if (mMusicType != MWSound::MusicType::Battle && hasHostiles) else if (mMusicType != MWSound::MusicType::Battle && hasHostiles)
{ {
MWBase::Environment::get().getSoundManager()->playPlaylist(std::string("Battle")); MWBase::Environment::get().getSoundManager()->playPlaylist(MWSound::battlePlaylist);
mMusicType = MWSound::MusicType::Battle; mMusicType = MWSound::MusicType::Battle;
} }
} }

View file

@ -0,0 +1,12 @@
#ifndef OPENMW_APPS_OPENMW_MWSOUND_CONSTANTS_H
#define OPENMW_APPS_OPENMW_MWSOUND_CONSTANTS_H
#include <components/vfs/pathutil.hpp>
namespace MWSound
{
constexpr VFS::Path::NormalizedView battlePlaylist("battle");
constexpr VFS::Path::NormalizedView explorePlaylist("explore");
}
#endif

View file

@ -26,14 +26,14 @@
#include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/actorutil.hpp"
#include "constants.hpp"
#include "ffmpeg_decoder.hpp"
#include "openal_output.hpp"
#include "sound.hpp" #include "sound.hpp"
#include "sound_buffer.hpp" #include "sound_buffer.hpp"
#include "sound_decoder.hpp" #include "sound_decoder.hpp"
#include "sound_output.hpp" #include "sound_output.hpp"
#include "ffmpeg_decoder.hpp"
#include "openal_output.hpp"
namespace MWSound namespace MWSound
{ {
namespace namespace
@ -352,12 +352,12 @@ namespace MWSound
mechanicsManager->setMusicType(type); mechanicsManager->setMusicType(type);
advanceMusic(normalizedName, fade); advanceMusic(normalizedName, fade);
if (type == MWSound::MusicType::Battle) if (type == MWSound::MusicType::Battle)
mCurrentPlaylist = "Battle"; mCurrentPlaylist = battlePlaylist;
else if (type == MWSound::MusicType::Explore) else if (type == MWSound::MusicType::Explore)
mCurrentPlaylist = "Explore"; mCurrentPlaylist = explorePlaylist;
} }
void SoundManager::playPlaylist(const std::string& playlist) void SoundManager::playPlaylist(VFS::Path::NormalizedView playlist)
{ {
if (mCurrentPlaylist == playlist) if (mCurrentPlaylist == playlist)
return; return;
@ -367,17 +367,18 @@ namespace MWSound
if (it == mMusicFiles.end()) if (it == mMusicFiles.end())
{ {
std::vector<VFS::Path::Normalized> filelist; std::vector<VFS::Path::Normalized> filelist;
auto playlistPath = Misc::ResourceHelpers::correctMusicPath(playlist) + '/'; constexpr VFS::Path::NormalizedView music("music");
for (const auto& name : mVFS->getRecursiveDirectoryIterator(playlistPath)) const VFS::Path::Normalized playlistPath = music / playlist / VFS::Path::NormalizedView();
for (const auto& name : mVFS->getRecursiveDirectoryIterator(VFS::Path::NormalizedView(playlistPath)))
filelist.push_back(name); filelist.push_back(name);
it = mMusicFiles.emplace_hint(it, playlist, std::move(filelist)); it = mMusicFiles.emplace_hint(it, playlist, std::move(filelist));
} }
// No Battle music? Use Explore playlist // No Battle music? Use Explore playlist
if (playlist == "Battle" && it->second.empty()) if (playlist == battlePlaylist && it->second.empty())
{ {
playPlaylist("Explore"); playPlaylist(explorePlaylist);
return; return;
} }
@ -1024,7 +1025,7 @@ namespace MWSound
mTimePassed = 0.0f; mTimePassed = 0.0f;
// Make sure music is still playing // Make sure music is still playing
if (!isMusicPlaying() && !mCurrentPlaylist.empty()) if (!isMusicPlaying() && !mCurrentPlaylist.value().empty())
startRandomTitle(); startRandomTitle();
Environment env = Env_Normal; Environment env = Env_Normal;

View file

@ -9,6 +9,7 @@
#include <components/fallback/fallback.hpp> #include <components/fallback/fallback.hpp>
#include <components/misc/objectpool.hpp> #include <components/misc/objectpool.hpp>
#include <components/misc/strings/algorithm.hpp>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
#include "../mwbase/soundmanager.hpp" #include "../mwbase/soundmanager.hpp"
@ -52,7 +53,8 @@ namespace MWSound
std::unique_ptr<Sound_Output> mOutput; std::unique_ptr<Sound_Output> mOutput;
// Caches available music tracks by <playlist name, (sound files) > // Caches available music tracks by <playlist name, (sound files) >
std::unordered_map<std::string, std::vector<VFS::Path::Normalized>> mMusicFiles; std::unordered_map<VFS::Path::Normalized, std::vector<VFS::Path::Normalized>, VFS::Path::Hash, std::equal_to<>>
mMusicFiles;
std::unordered_map<std::string, std::vector<int>> mMusicToPlay; // A list with music files not yet played std::unordered_map<std::string, std::vector<int>> mMusicToPlay; // A list with music files not yet played
std::string mLastPlayedMusic; // The music file that was last played std::string mLastPlayedMusic; // The music file that was last played
@ -90,7 +92,7 @@ namespace MWSound
TrackList mActiveTracks; TrackList mActiveTracks;
StreamPtr mMusic; StreamPtr mMusic;
std::string mCurrentPlaylist; VFS::Path::Normalized mCurrentPlaylist;
bool mListenerUnderwater; bool mListenerUnderwater;
osg::Vec3f mListenerPos; osg::Vec3f mListenerPos;
@ -183,7 +185,7 @@ namespace MWSound
bool isMusicPlaying() override; bool isMusicPlaying() override;
///< Returns true if music is playing ///< Returns true if music is playing
void playPlaylist(const std::string& playlist) override; void playPlaylist(VFS::Path::NormalizedView playlist) override;
///< Start playing music from the selected folder ///< Start playing music from the selected folder
/// \param name of the folder that contains the playlist /// \param name of the folder that contains the playlist
/// Title music playlist is predefined /// Title music playlist is predefined

View file

@ -90,6 +90,8 @@
#include "../mwphysics/object.hpp" #include "../mwphysics/object.hpp"
#include "../mwphysics/physicssystem.hpp" #include "../mwphysics/physicssystem.hpp"
#include "../mwsound/constants.hpp"
#include "actionteleport.hpp" #include "actionteleport.hpp"
#include "cellstore.hpp" #include "cellstore.hpp"
#include "containerstore.hpp" #include "containerstore.hpp"
@ -394,7 +396,7 @@ namespace MWWorld
{ {
// Make sure that we do not continue to play a Title music after a new game video. // Make sure that we do not continue to play a Title music after a new game video.
MWBase::Environment::get().getSoundManager()->stopMusic(); MWBase::Environment::get().getSoundManager()->stopMusic();
MWBase::Environment::get().getSoundManager()->playPlaylist(std::string("Explore")); MWBase::Environment::get().getSoundManager()->playPlaylist(MWSound::explorePlaylist);
MWBase::Environment::get().getWindowManager()->playVideo(video, true); MWBase::Environment::get().getWindowManager()->playVideo(video, true);
} }
} }

View file

@ -186,9 +186,11 @@ VFS::Path::Normalized Misc::ResourceHelpers::correctSoundPath(VFS::Path::Normali
return prefix / resPath; return prefix / resPath;
} }
std::string Misc::ResourceHelpers::correctMusicPath(const std::string& resPath) std::string Misc::ResourceHelpers::correctMusicPath(std::string_view resPath)
{ {
return "music\\" + resPath; std::string result("music/");
result += resPath;
return result;
} }
std::string_view Misc::ResourceHelpers::meshPathForESM3(std::string_view resPath) std::string_view Misc::ResourceHelpers::meshPathForESM3(std::string_view resPath)

View file

@ -42,7 +42,7 @@ namespace Misc
VFS::Path::Normalized correctSoundPath(VFS::Path::NormalizedView resPath); VFS::Path::Normalized correctSoundPath(VFS::Path::NormalizedView resPath);
// Adds "music\\". // Adds "music\\".
std::string correctMusicPath(const std::string& resPath); std::string correctMusicPath(std::string_view resPath);
// Removes "meshes\\". // Removes "meshes\\".
std::string_view meshPathForESM3(std::string_view resPath); std::string_view meshPathForESM3(std::string_view resPath);

View file

@ -99,4 +99,21 @@ namespace VFS
++normalized.back(); ++normalized.back();
return { it, mIndex.lower_bound(normalized) }; return { it, mIndex.lower_bound(normalized) };
} }
RecursiveDirectoryRange Manager::getRecursiveDirectoryIterator(VFS::Path::NormalizedView path) const
{
if (path.value().empty())
return { mIndex.begin(), mIndex.end() };
const auto it = mIndex.lower_bound(path);
if (it == mIndex.end() || !it->first.view().starts_with(path.value()))
return { it, it };
std::string copy(path.value());
++copy.back();
return { it, mIndex.lower_bound(copy) };
}
RecursiveDirectoryRange Manager::getRecursiveDirectoryIterator() const
{
return { mIndex.begin(), mIndex.end() };
}
} }

View file

@ -65,6 +65,10 @@ namespace VFS
/// @note May be called from any thread once the index has been built. /// @note May be called from any thread once the index has been built.
RecursiveDirectoryRange getRecursiveDirectoryIterator(std::string_view path) const; RecursiveDirectoryRange getRecursiveDirectoryIterator(std::string_view path) const;
RecursiveDirectoryRange getRecursiveDirectoryIterator(VFS::Path::NormalizedView path) const;
RecursiveDirectoryRange getRecursiveDirectoryIterator() const;
/// Retrieve the absolute path to the file /// Retrieve the absolute path to the file
/// @note Throws an exception if the file can not be found. /// @note Throws an exception if the file can not be found.
/// @note May be called from any thread once the index has been built. /// @note May be called from any thread once the index has been built.

View file

@ -179,6 +179,12 @@ namespace VFS::Path
return true; return true;
} }
Normalized& operator=(NormalizedView value)
{
mValue = value.value();
return *this;
}
Normalized& operator/=(NormalizedView value) Normalized& operator/=(NormalizedView value)
{ {
mValue.reserve(mValue.size() + value.value().size() + 1); mValue.reserve(mValue.size() + value.value().size() + 1);
@ -258,6 +264,22 @@ namespace VFS::Path
result /= rhs; result /= rhs;
return result; return result;
} }
struct Hash
{
using is_transparent = void;
[[nodiscard]] std::size_t operator()(std::string_view sv) const { return std::hash<std::string_view>{}(sv); }
[[nodiscard]] std::size_t operator()(const std::string& s) const { return std::hash<std::string>{}(s); }
[[nodiscard]] std::size_t operator()(const Normalized& s) const { return std::hash<std::string>{}(s.value()); }
[[nodiscard]] std::size_t operator()(NormalizedView s) const
{
return std::hash<std::string_view>{}(s.value());
}
};
} }
#endif #endif