diff --git a/doomsday/engine/api/dd_plugin.h b/doomsday/engine/api/dd_plugin.h index c1419a31b6..1891b25609 100644 --- a/doomsday/engine/api/dd_plugin.h +++ b/doomsday/engine/api/dd_plugin.h @@ -40,12 +40,6 @@ */ #define DENG_PLUGIN_GLOBAL(name) __DengPlugin_##name -#if defined(UNIX) && !defined(MACOSX) -# define DENG_AUDIO_PLUGIN_NAME_PREFIX "libaudio_" -#else -# define DENG_AUDIO_PLUGIN_NAME_PREFIX "audio_" -#endif - #define MAX_HOOKS 16 #define HOOKF_EXCLUSIVE 0x01000000 diff --git a/doomsday/engine/portable/include/library.h b/doomsday/engine/portable/include/library.h index 2c5add07eb..aced500b18 100644 --- a/doomsday/engine/portable/include/library.h +++ b/doomsday/engine/portable/include/library.h @@ -82,6 +82,16 @@ Library* Library_New(const char* filePath); void Library_Delete(Library* lib); +/** + * Returns the type identifier of the library. + * @see de::Library + * + * @param lib Library instance. + * + * @return Type identifier string, e.g., "deng-plugin/game". + */ +const char* Library_Type(const Library* lib); + /** * Looks up a symbol from the library. * diff --git a/doomsday/engine/portable/src/audiodriver.c b/doomsday/engine/portable/src/audiodriver.c index aa517f33df..51d94b04df 100644 --- a/doomsday/engine/portable/src/audiodriver.c +++ b/doomsday/engine/portable/src/audiodriver.c @@ -124,20 +124,29 @@ static void importInterfaces(driver_t* d) static int audioPluginFinder(const char* fileName, const char* absPath, void* ptr) { + int i; Str* path = (Str*) ptr; - if(!strncmp(fileName, Str_Text(path), Str_Length(path)) /* matching name? */ && - (strlen(fileName) == Str_Length(path) /* no extension? */ - || fileName[Str_Length(path)] == '.' /* extension follows right away? */)) + + // Check if the filename matches: [*]audio_name[.ext] + // (a regex or pattern match routine wouldn't hurt...) + + for(i = 0; i <= strlen(fileName) - Str_Size(path); ++i) { - Str_Set(path, absPath); - return true; // Found it! + const char* fn = fileName + i; + if(!strncmp(fn, Str_Text(path), Str_Length(path)) /* matching name? */ && + (strlen(fn) == Str_Length(path) /* no extension? */ + || fn[Str_Length(path)] == '.' /* extension follows right away? */)) + { + Str_Set(path, absPath); + return true; // Found it! + } } return false; // Keep looking... } static AutoStr* findAudioPluginPath(const char* name) { - AutoStr* path = Str_Appendf(AutoStr_New(), "%s%s", DENG_AUDIO_PLUGIN_NAME_PREFIX, name); + AutoStr* path = Str_Appendf(AutoStr_New(), "audio_%s", name); if(Library_IterateAvailableLibraries(audioPluginFinder, path)) { // The full path of the library was returned in @a path. diff --git a/doomsday/engine/portable/src/dd_plugin.c b/doomsday/engine/portable/src/dd_plugin.c index 771c06169b..88726cc4bc 100644 --- a/doomsday/engine/portable/src/dd_plugin.c +++ b/doomsday/engine/portable/src/dd_plugin.c @@ -69,13 +69,6 @@ static int loadPlugin(const char* fileName, const char* pluginPath, void* param) DENG_ASSERT(fileName && fileName[0]); DENG_ASSERT(pluginPath && pluginPath[0]); - if(!strncmp(fileName, DENG_AUDIO_PLUGIN_NAME_PREFIX, - strlen(DENG_AUDIO_PLUGIN_NAME_PREFIX))) - { - // The audio plugins are loaded later on demand by AudioDriver. - return false; - } - plugin = Library_New(pluginPath); if(!plugin) { @@ -83,6 +76,13 @@ static int loadPlugin(const char* fileName, const char* pluginPath, void* param) return 0; // Continue iteration. } + if(!strcmp(Library_Type(plugin), "deng-plugin/audio")) + { + // Audio plugins will be loaded later, on demand. + Library_Delete(plugin); + return 0; + } + initializer = Library_Symbol(plugin, "DP_Initialize"); if(!initializer) { diff --git a/doomsday/engine/portable/src/library.cpp b/doomsday/engine/portable/src/library.cpp index e0708cea6c..1703c63407 100644 --- a/doomsday/engine/portable/src/library.cpp +++ b/doomsday/engine/portable/src/library.cpp @@ -32,6 +32,7 @@ struct library_s { // typedef Library Str* path; de::LibraryFile* libFile; bool isGamePlugin; + std::string typeId; library_s() : path(0), libFile(0), isGamePlugin(false) {} }; @@ -109,6 +110,7 @@ Library* Library_New(const char* filePath) Library* lib = new Library; lib->libFile = &libFile; lib->path = Str_Set(Str_NewStd(), filePath); + lib->typeId = libFile.library().type().toStdString(); loadedLibs.append(lib); // Symbols from game plugins conflict with each other, so we have to @@ -131,12 +133,21 @@ Library* Library_New(const char* filePath) void Library_Delete(Library *lib) { DENG_ASSERT(lib); + + // Unload the library from memory. lib->libFile->clear(); + Str_Delete(lib->path); loadedLibs.removeOne(lib); delete lib; } +const char* Library_Type(const Library* lib) +{ + DENG_ASSERT(lib); + return &lib->typeId[0]; +} + void* Library_Symbol(Library* lib, const char* symbolName) { try diff --git a/doomsday/libdeng2/include/de/core/library.h b/doomsday/libdeng2/include/de/core/library.h index db210dab80..58067344ea 100644 --- a/doomsday/libdeng2/include/de/core/library.h +++ b/doomsday/libdeng2/include/de/core/library.h @@ -133,8 +133,10 @@ namespace de virtual ~Library(); /** - * Returns the type identifier of the library. This affects how libdeng2 - * will treat the library. + * Returns the type identifier of the library. This affects how + * libdeng2 will treat the library. The type is determined + * automatically when the library is first loaded, and can then be + * queried at any time even after the library has been unloaded. */ const String& type() const { return _type; }