Panda3D
movieTypeRegistry.cxx
1 // Filename: movieTypeRegistry.cxx
2 // Created by: rdb (24Aug13)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "movieTypeRegistry.h"
16 #include "string_utils.h"
17 #include "config_movies.h"
18 #include "config_util.h"
19 #include "load_dso.h"
20 
21 MovieTypeRegistry *MovieTypeRegistry::_global_ptr = NULL;
22 
23 ////////////////////////////////////////////////////////////////////
24 // Function: MovieTypeRegistry::make_audio
25 // Access: Published, Static
26 // Description: Obtains a MovieVideo that references a file.
27 ////////////////////////////////////////////////////////////////////
28 PT(MovieAudio) MovieTypeRegistry::
29 make_audio(const Filename &name) {
30  string ext = downcase(name.get_extension());
31 
32  // Make sure that the list of audio types has been read in.
34 
35  // Maybe we need to load a module?
36  if (_deferred_audio_types.count(ext)) {
37  load_movie_library(_deferred_audio_types[ext]);
38  _deferred_audio_types.erase(ext);
39  }
40 
41  // Explicit extension is preferred over catch-all.
42  if (_audio_type_registry.count(ext)) {
43  MakeAudioFunc func = _audio_type_registry[ext];
44  return (*func)(name);
45  }
46 
47  // If we didn't find it, see if there was a type registered
48  // with '*' as extension. This is a catch-all loader.
49  if (_deferred_audio_types.count("*")) {
50  load_movie_library(_deferred_audio_types["*"]);
51  _deferred_audio_types.erase("*");
52  }
53 
54  if (_audio_type_registry.count("*")) {
55  MakeAudioFunc func = _audio_type_registry["*"];
56  return (*func)(name);
57  }
58 
59  movies_cat.error()
60  << "Support for audio files with extension ." << ext << " was not enabled.\n";
61 
62  return new MovieAudio("Load-Failure Stub");
63 }
64 
65 ////////////////////////////////////////////////////////////////////
66 // Function: MovieTypeRegistry::register_audio_type
67 // Access: Published, Static
68 // Description: Registers a MovieAudio type, so that files with
69 // any of the given extensions will be loaded as this
70 // type. You may use * as a catch-all extension.
71 ////////////////////////////////////////////////////////////////////
73 register_audio_type(MakeAudioFunc func, const string &extensions) {
74  vector_string words;
75  extract_words(downcase(extensions), words);
76 
77  vector_string::const_iterator wi;
78  for (wi = words.begin(); wi != words.end(); ++wi) {
79  if (_audio_type_registry.count(*wi)) {
80  movies_cat->warning()
81  << "Attempt to register multiple audio types with extension " << (*wi) << "\n";
82  } else {
83  movies_cat->debug()
84  << "Registered audio type with extension " << (*wi) << "\n";
85  }
86  _audio_type_registry[*wi] = func;
87  }
88 }
89 
90 ////////////////////////////////////////////////////////////////////
91 // Function: MovieTypeRegistry::load_audio_types
92 // Access: Published, Static
93 // Description: Loads the list with audio types, if we haven't
94 // already.
95 ////////////////////////////////////////////////////////////////////
98  static bool audio_types_loaded = false;
99 
100  if (!audio_types_loaded) {
101  int num_unique_values = load_audio_type.get_num_unique_values();
102 
103  for (int i = 0; i < num_unique_values; i++) {
104  string param = load_audio_type.get_unique_value(i);
105 
106  vector_string words;
107  extract_words(param, words);
108 
109  if (words.size() == 1) {
110  // Exactly one word: load the named library immediately.
111  string name = words[0];
112  Filename dlname = Filename::dso_filename("lib" + name + ".so");
113  movies_cat.info()
114  << "loading audio type module: " << name << endl;
115  void *tmp = load_dso(get_plugin_path().get_value(), dlname);
116  if (tmp == (void *)NULL) {
117  movies_cat.warning()
118  << "Unable to load " << dlname.to_os_specific()
119  << ": " << load_dso_error() << endl;
120  } else if (movies_cat.is_debug()) {
121  movies_cat.debug()
122  << "done loading audio type module: " << name << endl;
123  }
124 
125  } else if (words.size() > 1) {
126  // Multiple words: the first n words are filename extensions,
127  // and the last word is the name of the library to load should
128  // any of those filename extensions be encountered.
129  size_t num_extensions = words.size() - 1;
130  string library_name = words[num_extensions];
131 
132  for (size_t i = 0; i < num_extensions; i++) {
133  string extension = downcase(words[i]);
134  if (extension[0] == '.') {
135  extension = extension.substr(1);
136  }
137 
138  _deferred_audio_types[extension] = library_name;
139  }
140  }
141  }
142 
143  audio_types_loaded = true;
144  }
145 }
146 
147 ////////////////////////////////////////////////////////////////////
148 // Function: MovieTypeRegistry::make_video
149 // Access: Published, Static
150 // Description: Obtains a MovieVideo that references a file.
151 ////////////////////////////////////////////////////////////////////
152 PT(MovieVideo) MovieTypeRegistry::
153 make_video(const Filename &name) {
154  string ext = downcase(name.get_extension());
155 
156  // Make sure that the list of video types has been read in.
158 
159  // Maybe we need to load a module?
160  if (_deferred_video_types.count(ext)) {
161  load_movie_library(_deferred_video_types[ext]);
162  _deferred_video_types.erase(ext);
163  }
164 
165  // Explicit extension is preferred over catch-all.
166  if (_video_type_registry.count(ext)) {
167  MakeVideoFunc func = _video_type_registry[ext];
168  return (*func)(name);
169  }
170 
171  // If we didn't find it, see if there was a type registered
172  // with '*' as extension. This is a catch-all loader.
173  if (_deferred_video_types.count("*")) {
174  load_movie_library(_deferred_video_types["*"]);
175  _deferred_video_types.erase("*");
176  }
177 
178  if (_video_type_registry.count("*")) {
179  MakeVideoFunc func = _video_type_registry["*"];
180  return (*func)(name);
181  }
182 
183  movies_cat.error()
184  << "Support for video files with extension ." << ext << " was not enabled.\n";
185 
186  return new MovieVideo("Load-Failure Stub");
187 }
188 
189 ////////////////////////////////////////////////////////////////////
190 // Function: MovieTypeRegistry::register_video_type
191 // Access: Published, Static
192 // Description: Registers a MovieVideo type, so that files with
193 // any of the given extensions will be loaded as this
194 // type. You may use * as a catch-all extension.
195 ////////////////////////////////////////////////////////////////////
197 register_video_type(MakeVideoFunc func, const string &extensions) {
198  vector_string words;
199  extract_words(downcase(extensions), words);
200 
201  vector_string::const_iterator wi;
202  for (wi = words.begin(); wi != words.end(); ++wi) {
203  if (_video_type_registry.count(*wi)) {
204  movies_cat->warning()
205  << "Attempt to register multiple video types with extension " << (*wi) << "\n";
206  } else {
207  movies_cat->debug()
208  << "Registered video type with extension " << (*wi) << "\n";
209  }
210  _video_type_registry[*wi] = func;
211  }
212 }
213 
214 ////////////////////////////////////////////////////////////////////
215 // Function: MovieTypeRegistry::load_video_types
216 // Access: Published, Static
217 // Description: Loads the list with video types, if we haven't
218 // already.
219 ////////////////////////////////////////////////////////////////////
222  static bool video_types_loaded = false;
223 
224  if (!video_types_loaded) {
225  int num_unique_values = load_video_type.get_num_unique_values();
226 
227  for (int i = 0; i < num_unique_values; i++) {
228  string param = load_video_type.get_unique_value(i);
229 
230  vector_string words;
231  extract_words(param, words);
232 
233  if (words.size() == 1) {
234  // Exactly one word: load the named library immediately.
235  string name = words[0];
236  Filename dlname = Filename::dso_filename("lib" + name + ".so");
237  movies_cat.info()
238  << "loading video type module: " << name << endl;
239  void *tmp = load_dso(get_plugin_path().get_value(), dlname);
240  if (tmp == (void *)NULL) {
241  movies_cat.warning()
242  << "Unable to load " << dlname.to_os_specific()
243  << ": " << load_dso_error() << endl;
244  } else if (movies_cat.is_debug()) {
245  movies_cat.debug()
246  << "done loading video type module: " << name << endl;
247  }
248 
249  } else if (words.size() > 1) {
250  // Multiple words: the first n words are filename extensions,
251  // and the last word is the name of the library to load should
252  // any of those filename extensions be encountered.
253  size_t num_extensions = words.size() - 1;
254  string library_name = words[num_extensions];
255 
256  for (size_t i = 0; i < num_extensions; i++) {
257  string extension = downcase(words[i]);
258  if (extension[0] == '.') {
259  extension = extension.substr(1);
260  }
261 
262  _deferred_video_types[extension] = library_name;
263  }
264  }
265  }
266 
267  video_types_loaded = true;
268  }
269 }
270 
271 ////////////////////////////////////////////////////////////////////
272 // Function: MovieTypeRegistry::load_library
273 // Access: Published, Static
274 // Description: Loads the module.
275 ////////////////////////////////////////////////////////////////////
277 load_movie_library(const string &name) {
278  Filename dlname = Filename::dso_filename("lib" + name + ".so");
279  movies_cat.info()
280  << "loading video type module: " << name << endl;
281  void *tmp = load_dso(get_plugin_path().get_value(), dlname);
282 
283  if (tmp == (void *)NULL) {
284  movies_cat.warning()
285  << "Unable to load " << dlname.to_os_specific()
286  << ": " << load_dso_error() << endl;
287  } else if (movies_cat.is_debug()) {
288  movies_cat.debug()
289  << "done loading video type module: " << name << endl;
290  }
291 }
void register_audio_type(MakeAudioFunc func, const string &extensions)
Registers a MovieAudio type, so that files with any of the given extensions will be loaded as this ty...
void register_video_type(MakeVideoFunc func, const string &extensions)
Registers a MovieVideo type, so that files with any of the given extensions will be loaded as this ty...
void load_audio_types()
Loads the list with audio types, if we haven&#39;t already.
This class records the different types of MovieAudio and MovieVideo that are available for loading...
void load_movie_library(const string &name)
Loads the module.
string get_extension() const
Returns the file extension.
Definition: filename.I:477
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:44
string get_unique_value(int n) const
Returns the nth unique value of the variable.
A MovieVideo is actually any source that provides a sequence of video frames.
Definition: movieVideo.h:42
int get_num_unique_values() const
Returns the number of unique values in the variable.
void load_video_types()
Loads the list with video types, if we haven&#39;t already.
A MovieAudio is actually any source that provides a sequence of audio samples.
Definition: movieAudio.h:48
string to_os_specific() const
Converts the filename from our generic Unix-like convention (forward slashes starting with the root a...
Definition: filename.cxx:1196