Load’em all : snippets to load assets into std::maps

Load’em all : snippets to load assets into std::maps

For a CODON project, I came up with two useful methods for loading .wav and .mov files into their respective std::maps. This way I could call the movie/sound by its name in the map and call the methods I want on it.

For the mentioned project I was already receiving TCP messages containing the name of the asset I needed to play from a client app. Users would have interacted with an Android app on a tablet and as the result of their interaction, the tablet would ask the main Cinder app (the server) to play a specific asset (movie and sound). Having the assets loaded in a map with asset names as keys, made playback super easy by calling something like mMovies[tcpMessageString]->play() in the TCP event.

Here are the methods:

// loads all movies from the folder and returns a map with the movies' names as keys, not recursive
std::map<std::string, ci::qtime::MovieGlRef> loadMovies(const ci::fs::path& aMoviesFolder, const std::vector<std::string>& aAllowedExtensions = {".mov"});
// loads all sounds from the folder and returns a map with the sounds' names as keys, not recursive
std::map<std::string, ci::audio::VoiceRef> loadSounds(const ci::fs::path& aSoundsFolder, const std::vector<std::string>& aAllowedExtensions = {".wav"});

The main concept behind the implementation is the use of fs::directory_iterator to iterate over all of the files in a folder. The method then checks for allowed extensions (“.mov” in the case of Quicktime movies for instance) and again using methods for fs::path detects the name of the file and use that as the key in our map. As a note, the extension() method extracts the extension such as “.txt” or “.mov” (remember the dot is there), the stem() method obtains the name of the file (“my-good-movie” in “my-good-movie.mov”) and the filename() method strips the path and shows the full name along with the extension. Here is a good reference for methods associated with the fs::path.

This implementation is not recursive but could easily become recursive if for every sub-folder (fs::is_directory() == true) we used the same method and the joined the result maps together.

map<string, qtime::MovieGlRef> loadMovies(const fs::path& aMoviesFolder, const vector<string>& aAllowedExtensions)
{
// make the empty result
map<string, qtime::MovieGlRef> result;
// check if the path is a directory
if (!fs::is_directory(aMoviesFolder)) {
CI_LOG_W("Movies folder was actually not a folder!");
return result;
}
for (auto& file : fs::directory_iterator(aMoviesFolder)) {
auto path = file.path();
if (fs::is_regular_file(path)) {
for (auto& extension : aAllowedExtensions) {
if (path.extension().string() == extension) {
auto movie = qtime::MovieGl::create(path);
movie->setVolume(1);
movie->stop();
result[path.stem().string()] = movie;
CI_LOG_V ("Movie loaded with name " + path.filename().string());
break; // if the extension was found don't bother with the other extensions
}
}
}
}
return result;
}
map<string, audio::VoiceRef> loadSounds(const fs::path& aSoundsFolder, const vector<string>& aAllowedExtensions)
{
// make the empty result
map<string, audio::VoiceRef> result;
// check if the path is a directory
if (!fs::is_directory(aSoundsFolder)) {
CI_LOG_W("Sounds folder was actually not a folder!");
return result;
}
for (auto& file : fs::directory_iterator(aSoundsFolder)) {
auto path = file.path();
if (fs::is_regular_file(path)) {
for (auto& extension : aAllowedExtensions) {
if (path.extension().string() == extension) {
auto sound = audio::Voice::create(audio::load(loadFile(path)));
sound->setVolume(1);
sound->stop();
result[path.stem().string()] = sound;
CI_LOG_V ("Sound loaded with name " + path.filename().string());
break; // if the extension was found don't bother with the other extensions
}
}
}
}
return result;
}

0 Comments

Leave a reply

Your email address will not be published. Required fields are marked *

*