PageRenderTime 22ms CodeModel.GetById 2ms app.highlight 17ms RepoModel.GetById 1ms app.codeStats 0ms

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