Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TemplateManager.cpp
Go to the documentation of this file.
1 //
2 // C++ Implementation: Audio::TemplateManager
3 //
4 #include "TemplateManager.h"
5 #include "config.h"
6 
7 #include <utility>
8 #include <assert.h>
9 
10 #include "XMLDocument.h"
11 #include "VSFileXMLSerializer.h"
12 
13 #include "utils.h"
14 #include "xml_support.h"
15 
16 #include "SourceTemplate.h"
17 
18 #include "vs_math.h"
19 
20 using std::string;
21 using std::min;
22 using std::map;
23 
25 
26 namespace Audio {
27 
28  namespace __impl {
29 
33  SharedPtr<XMLDOM::XMLDocument> parsed;
34 
37 
42 
43  void computeExpirationTime() throw()
44  {
45  assert(parsed.get());
46  expirationTime = 10 + min(600UL, 2UL * parsed->root.numChildren());
47  }
48 
49  void load(const string &path) throw(Exception)
50  {
51  XMLDOM::VSFileXMLSerializer serializer;
52  serializer.initialise();
53  serializer.importXML(path, VSFileSystem::SoundFile);
54  parsed.reset(serializer.close());
55  touch();
56  }
57 
58  void touch() const throw()
59  {
61  }
62  };
63 
64  // The many required indices
65  typedef map<string, WeakPtr<SourceTemplate> > TemplateMap;
66  typedef map<string, SharedPtr<SourceTemplate> > PermTemplateMap;
67  typedef map<string, DefinitionFileInfo> DefinitionMap;
68 
72 
74 
75  SharedPtr<XMLDOM::XMLDocument> getDefinitionFile(const std::string &path)
76  throw(Exception)
77  {
78  DefinitionMap::iterator it = loadedDefinitions.find(path);
79  if (it != loadedDefinitions.end()) {
80  if (it->second.parsed.get() == 0)
81  it->second.load(path); else
82  it->second.touch();
83  return it->second.parsed;
84  } else {
85  throw NotFoundException(path);
86  }
87  }
88 
89  SharedPtr<XMLDOM::XMLDocument> getDefinitionFile(const std::string &path) const
90  throw(Exception)
91  {
92  DefinitionMap::const_iterator it = loadedDefinitions.find(path);
93  if (it != loadedDefinitions.end()) {
94  if (it->second.parsed.get() == 0)
95  throw ResourceNotLoadedException(); else
96  it->second.touch();
97  return it->second.parsed;
98  } else {
99  throw NotFoundException(path);
100  }
101  }
102  };
103 
105  {
106  static map<string, VSFileSystem::VSFileType> enumMap;
107  if (enumMap.empty()) {
108 
109  enumMap["universe"] = VSFileSystem::UniverseFile;
110  enumMap["system"] = VSFileSystem::SystemFile;
111  enumMap["cockpit"] = VSFileSystem::CockpitFile;
112  enumMap["unit"] = VSFileSystem::UnitFile;
113  enumMap["unitSave"] = VSFileSystem::UnitSaveFile;
114  enumMap["texture"] = VSFileSystem::TextureFile;
115  enumMap["sound"] = VSFileSystem::SoundFile;
116  enumMap["python"] = VSFileSystem::PythonFile;
117  enumMap["mesh"] = VSFileSystem::MeshFile;
118  enumMap["comm"] = VSFileSystem::CommFile;
119  enumMap["ai"] = VSFileSystem::AiFile;
120  enumMap["save"] = VSFileSystem::SaveFile;
121  enumMap["anim"] = VSFileSystem::AnimFile;
122  enumMap["video"] = VSFileSystem::VideoFile;
123  enumMap["sprite"] = VSFileSystem::VSSpriteFile;
124  enumMap["mission"] = VSFileSystem::MissionFile;
125  enumMap["music"] = VSFileSystem::MusicFile;
126  enumMap["account"] = VSFileSystem::AccountFile;
127  enumMap["zoneBuffer"] = VSFileSystem::ZoneBuffer;
128  enumMap["jpegBuffer"] = VSFileSystem::JPEGBuffer;
129  enumMap["unknown"] = VSFileSystem::UnknownFile;
130  }
131  return parseEnum(s, enumMap);
132  }
133 
134  static bool parseBool(const std::string &s)
135  {
136  if (s.empty())
137  throw InvalidParametersException("Missing required attribute");
138  else
139  return XMLSupport::parse_bool(s);
140  }
141 
142  static float parseFloat(const std::string &s)
143  {
144  if (s.empty())
145  throw InvalidParametersException("Invalid float attribute");
146  else
147  return XMLSupport::parse_floatf(s);
148  }
149 
150  };
151 
152  using namespace __impl;
153 
155  data(new TemplateManagerData)
156  {
157  }
158 
160  {
161  }
162 
163  void TemplateManager::addDefinitionFile(const string &path, bool persistent) throw(Exception)
164  {
165  // Add an unparsed definition, for lazy loading.
166  if (data->loadedDefinitions.count(path) == 0) {
167  TemplateManagerData::DefinitionFileInfo &info = data->loadedDefinitions[path];
168  info.expirationTime = persistent?-1:0;
169  }
170  }
171 
172  void TemplateManager::addDefinitionFile(const string &path, SharedPtr<XMLDOM::XMLDocument> definition) throw(Exception)
173  {
174  if (data->loadedDefinitions.count(path) == 0) {
175  TemplateManagerData::DefinitionFileInfo &info = data->loadedDefinitions[path];
176  info.expirationTime = 0;
177  info.lastUsageTime = 0;
178  info.parsed = definition;
179  }
180  }
181 
182  SharedPtr<XMLDOM::XMLDocument> TemplateManager::getDefinitionFile(const std::string &path) const
184  {
185  return ((const TemplateManagerData &)*data).getDefinitionFile(path);
186  }
187 
188  SharedPtr<XMLDOM::XMLDocument> TemplateManager::getDefinitionFile(const std::string &path)
189  throw(Exception)
190  {
191  try {
192  return data->getDefinitionFile(path);
193  } catch(NotFoundException e) {
194  addDefinitionFile(path, false);
195  return data->getDefinitionFile(path);
196  }
197  }
198 
200  throw()
201  {
202  data->defaultDefinitionFile = x;
203  }
204 
205  const std::string& TemplateManager::getDefaultDefinitionFile() const
206  throw()
207  {
208  return data->defaultDefinitionFile;
209  }
210 
211  SharedPtr<SourceTemplate> TemplateManager::getSourceTemplate(const std::string &name)
212  throw(Exception)
213  {
214  SharedPtr<SourceTemplate> rv;
215 
216  TemplateManagerData::TemplateMap::const_iterator it = data->loadedTemplates.find(name);
217  if (it != data->loadedTemplates.end())
218  rv = it->second.lock();
219 
220  if (!rv.get()) {
221  rv = loadSourceTemplate(name);
222  data->loadedTemplates[name] = rv;
223  }
224 
225  return rv;
226  }
227 
228  SharedPtr<SourceTemplate> TemplateManager::loadSourceTemplate(const std::string &name)
229  throw(Exception)
230  {
231  string::size_type sep = name.find_first_of(':');
232  SharedPtr<XMLDOM::XMLDocument> def;
233 
234  if (sep != string::npos)
235  def = getDefinitionFile(name.substr(0,sep)); else
236  def = getDefinitionFile(getDefaultDefinitionFile());
237 
238  const XMLDOM::XMLElement *tdef = 0;
239  if (sep != string::npos)
240  tdef = def->getElementByName(name.substr(sep+1, string::npos)); else
241  tdef = def->getElementByName(name);
242 
243  if (!tdef)
244  throw NotFoundException(name);
245 
246  string src =
247  tdef->getAttributeValue("src","");
248 
249  if ( src.empty() )
250  throw InvalidParametersException("Invalid source template: no sound specified");
251 
253  parseVSFileType( tdef->getAttributeValue("type", "unknown") );
254  bool looping =
255  parseBool( tdef->getAttributeValue("looping", "false") );
256 
257  SharedPtr<SourceTemplate> rv(
258  new SourceTemplate(src, type, looping) );
259 
260  rv->setAngleRange( Range<Scalar>(
261  parseFloat( tdef->getAttributeValue("minAngle", "180") ) * M_PI / 180.f,
262  parseFloat( tdef->getAttributeValue("maxAngle", "180") ) * M_PI / 180.f
263  ) );
264 
265  rv->setPerFrequencyRadiusRatios( PerFrequency<Scalar>(
266  parseFloat( tdef->getAttributeValue("lfRadiusRatio", "1") ),
267  parseFloat( tdef->getAttributeValue("hfRadiusRatio", "1") )
268  ) );
269 
270  rv->setPerFrequencyRadiusRatios( PerFrequency<Scalar>(
271  parseFloat( tdef->getAttributeValue("lfReferenceFreq", "250") ),
272  parseFloat( tdef->getAttributeValue("hfReferenceFreq", "5000") )
273  ) );
274 
275  rv->setGain(
276  parseFloat( tdef->getAttributeValue("gain", "1") )
277  );
278 
279  rv->setStreaming(
280  parseBool( tdef->getAttributeValue("streaming", "false") )
281  );
282 
283  return rv;
284  }
285 
286 
287  void TemplateManager::addSourceTemplate(const string &name, SharedPtr<SourceTemplate> tpl, bool perm)
289  {
290  static string empty;
291  addSourceTemplate(empty, name, tpl, perm);
292  }
293 
294  void TemplateManager::addSourceTemplate(const string &path, const string &name, SharedPtr<SourceTemplate> tpl, bool perm)
295  throw(ResourceAlreadyLoadedException)
296  {
297  string key(path + ":" + name);
298  SharedPtr<SourceTemplate> rv;
299 
300  TemplateManagerData::TemplateMap::const_iterator it = data->loadedTemplates.find(key);
301  if (it != data->loadedTemplates.end())
302  rv = it->second.lock();
303 
304  if (!rv.get()) {
305  rv = tpl;
306  data->loadedTemplates[key] = rv;
307  if (perm)
308  data->permLoadedTemplates[key] = rv;
309  } else {
310  throw ResourceAlreadyLoadedException(key);
311  }
312  }
313 
314 };