/xbmc/visualizations/XBMCProjectM/libprojectM/PresetLoader.cpp

http://github.com/xbmc/xbmc · C++ · 246 lines · 166 code · 54 blank · 26 comment · 31 complexity · 9a6a548257efd426ac547ecb68933b5b MD5 · raw file

  1. //
  2. // C++ Implementation: PresetLoader
  3. //
  4. // Description:
  5. //
  6. //
  7. // Author: Carmelo Piccione <carmelo.piccione@gmail.com>, (C) 2007
  8. //
  9. // Copyright: See COPYING file that comes with this distribution
  10. //
  11. //
  12. #include "PresetLoader.hpp"
  13. #include "Preset.hpp"
  14. #include <iostream>
  15. #include <sstream>
  16. #include <set>
  17. #ifdef LINUX
  18. extern "C"
  19. {
  20. #include <errno.h>
  21. }
  22. #endif
  23. #ifdef MACOS
  24. extern "C"
  25. {
  26. #include <errno.h>
  27. }
  28. #endif
  29. #include <cassert>
  30. #include "fatal.h"
  31. const std::string PresetLoader::PROJECTM_FILE_EXTENSION(".prjm");
  32. const std::string PresetLoader::MILKDROP_FILE_EXTENSION(".milk");
  33. PresetLoader::PresetLoader(std::string dirname) :m_dirname(dirname), m_dir(0), m_ratingsSum(0)
  34. {
  35. // Do one scan
  36. if (m_dirname != std::string())
  37. rescan();
  38. }
  39. PresetLoader::~PresetLoader()
  40. {
  41. if (m_dir)
  42. closedir(m_dir);
  43. }
  44. void PresetLoader::setScanDirectory(std::string dirname)
  45. {
  46. m_dirname = dirname;
  47. }
  48. void PresetLoader::rescan()
  49. {
  50. // std::cerr << "Rescanning..." << std::endl;
  51. // Clear the directory entry collection
  52. m_entries.clear();
  53. m_presetNames.clear();
  54. m_ratings.clear();
  55. m_ratingsSum = 0;
  56. // If directory already opened, close it first
  57. if (m_dir)
  58. {
  59. closedir(m_dir);
  60. m_dir = 0;
  61. }
  62. // Allocate a new a stream given the current directory name
  63. if ((m_dir = opendir(m_dirname.c_str())) == NULL)
  64. {
  65. handleDirectoryError();
  66. return; // no files loaded. m_entries is empty
  67. }
  68. struct dirent * dir_entry;
  69. std::set<std::string> alphaSortedFileSet;
  70. std::set<std::string> alphaSortedPresetNameSet;
  71. while ((dir_entry = readdir(m_dir)) != NULL)
  72. {
  73. std::ostringstream out;
  74. // Convert char * to friendly string
  75. std::string filename(dir_entry->d_name);
  76. // Verify extension is projectm or milkdrop
  77. if ((filename.rfind(PROJECTM_FILE_EXTENSION) != (filename.length() - PROJECTM_FILE_EXTENSION.length()))
  78. && (filename.rfind(MILKDROP_FILE_EXTENSION) != (filename.length() - MILKDROP_FILE_EXTENSION.length())))
  79. continue;
  80. if (filename.length() <= MILKDROP_FILE_EXTENSION.length())
  81. continue;
  82. if (filename.length() > 0 && filename[0] == '.')
  83. continue;
  84. // Create full path name
  85. out << m_dirname << PATH_SEPARATOR << filename;
  86. // Add to our directory entry collection
  87. alphaSortedFileSet.insert(out.str());
  88. alphaSortedPresetNameSet.insert(filename);
  89. // the directory entry struct is freed elsewhere
  90. }
  91. // Push all entries in order from the file set to the file entries member (which is an indexed vector)
  92. for (std::set<std::string>::iterator pos = alphaSortedFileSet.begin();
  93. pos != alphaSortedFileSet.end();++pos)
  94. m_entries.push_back(*pos);
  95. // Push all preset names in similar fashion
  96. for (std::set<std::string>::iterator pos = alphaSortedPresetNameSet.begin();
  97. pos != alphaSortedPresetNameSet.end();++pos)
  98. m_presetNames.push_back(*pos);
  99. // Give all presets equal rating of 3 - why 3? I don't know
  100. m_ratings = std::vector<int>(m_presetNames.size(), 3);
  101. m_ratingsSum = 3 * m_ratings.size();
  102. assert(m_entries.size() == m_presetNames.size());
  103. assert(m_ratings.size() == m_entries.size());
  104. }
  105. std::auto_ptr<Preset> PresetLoader::loadPreset(unsigned int index, PresetInputs & presetInputs, PresetOutputs & presetOutputs) const
  106. {
  107. // Check that index isn't insane
  108. assert(index >= 0);
  109. assert(index < m_entries.size());
  110. // Return a new autopointer to a preset
  111. return std::auto_ptr<Preset>(new Preset(m_entries[index], m_presetNames[index], presetInputs, presetOutputs));
  112. }
  113. void PresetLoader::handleDirectoryError()
  114. {
  115. #ifdef WIN32
  116. std::cerr << "[PresetLoader] warning: errno unsupported on win32 platforms. fix me" << std::endl;
  117. #else
  118. switch (errno)
  119. {
  120. case ENOENT:
  121. std::cerr << "[PresetLoader] ENOENT error. The path \"" << this->m_dirname << "\" probably does not exist. \"man open\" for more info." << std::endl;
  122. break;
  123. case ENOMEM:
  124. std::cerr << "[PresetLoader] out of memory! Are you running Windows?" << std::endl;
  125. abort();
  126. case ENOTDIR:
  127. std::cerr << "[PresetLoader] directory specified is not a preset directory! Trying to continue..." << std::endl;
  128. break;
  129. case ENFILE:
  130. std::cerr << "[PresetLoader] Your system has reached its open file limit. Trying to continue..." << std::endl;
  131. break;
  132. case EMFILE:
  133. std::cerr << "[PresetLoader] too many files in use by projectM! Bailing!" << std::endl;
  134. break;
  135. case EACCES:
  136. std::cerr << "[PresetLoader] permissions issue reading the specified preset directory." << std::endl;
  137. break;
  138. default:
  139. break;
  140. }
  141. #endif
  142. }
  143. void PresetLoader::setRating(unsigned int index, int rating) {
  144. assert(index >=0);
  145. assert(index < m_ratings.size());
  146. m_ratingsSum -= m_ratings[index];
  147. m_ratings[index] = rating;
  148. m_ratingsSum += rating;
  149. assert(m_entries.size() == m_presetNames.size());
  150. assert(m_ratings.size() == m_entries.size());
  151. }
  152. unsigned int PresetLoader::addPresetURL(const std::string & url, const std::string & presetName, int rating) {
  153. m_entries.push_back(url);
  154. m_presetNames.push_back(presetName);
  155. m_ratings.push_back(rating);
  156. m_ratingsSum += rating;
  157. assert(m_entries.size() == m_presetNames.size());
  158. assert(m_ratings.size() == m_entries.size());
  159. return m_entries.size()-1;
  160. }
  161. void PresetLoader::removePreset(unsigned int index) {
  162. m_entries.erase(m_entries.begin()+index);
  163. m_presetNames.erase(m_presetNames.begin()+index);
  164. m_ratingsSum -= m_ratings[index];
  165. m_ratings.erase(m_ratings.begin()+index);
  166. assert(m_entries.size() == m_presetNames.size());
  167. assert(m_ratings.size() == m_entries.size());
  168. }
  169. const std::string & PresetLoader::getPresetURL ( unsigned int index) const {
  170. return m_entries[index];
  171. }
  172. const std::string & PresetLoader::getPresetName ( unsigned int index) const {
  173. return m_presetNames[index];
  174. }
  175. int PresetLoader::getPresetRating ( unsigned int index) const {
  176. return m_ratings[index];
  177. }
  178. const std::vector<int> & PresetLoader::getPresetRatings () const {
  179. return m_ratings;
  180. }
  181. int PresetLoader::getPresetRatingsSum () const {
  182. return m_ratingsSum;
  183. }
  184. void PresetLoader::insertPresetURL(unsigned int index, const std::string & url, const std::string & presetName, int rating)
  185. {
  186. m_entries.insert(m_entries.begin()+index, url);
  187. m_presetNames.insert(m_presetNames.begin() + index, presetName);
  188. m_ratings.insert(m_ratings.begin()+index, rating);
  189. m_ratingsSum += rating;
  190. assert(m_entries.size() == m_presetNames.size());
  191. assert(m_ratings.size() == m_entries.size());
  192. }