bool csSCF::RegisterClass (const char *iClassID, const char *iLibraryName, const char *iFactoryClass, const char *iDesc, const char *Dependencies, const char* context) { CS::Threading::RecursiveMutexScopedLock lock (mutex); size_t idx; csStringID contextID = context ? contexts.Request (context) : csInvalidStringID; if (IsVerbose(SCF_VERBOSE_CLASS_REGISTER)) csPrintfErr("SCF_NOTIFY: registering class %s in context %s (from %s)\n", iClassID, CS::Quote::Single (GetContextName(context)), iLibraryName); if ((idx = ClassRegistry->FindClass(iClassID)) != (size_t)-1) { scfFactory *cf = (scfFactory *)ClassRegistry->Get (idx); if (ContextClash (cf->classContext, contextID)) { csPrintfErr("SCF_WARNING: class %s (from %s) has already been " "registered in the same context %s (in %s)\n", iClassID, iLibraryName, CS::Quote::Single (GetContextName(context)), get_library_name(cf->LibraryName)); } else { /* The user may want to override a standard CS plugin by putting a plugin exhibiting the same class ID into the e.g. app directory. In this case a warning is probably not desired. But for debugging purposes we emit something. */ #ifdef CS_DEBUG // Don't report when the already registered class is static. if (cf->classContext != staticContextID) { // @@@ some way to have this warning in non-debug builds would be nice. csPrintfErr("SCF_NOTIFY: class %s (from %s) has already been " "registered in a different context: %s vs. %s (from %s); this " "message appears only in debug builds\n", iClassID, iLibraryName, CS::Quote::Single (GetContextName(context)), CS::Quote::Single (GetContextName(cf->classContext)), get_library_name(cf->LibraryName)); } #endif } return false; } scfFactory* factory = new scfFactory (iClassID, iLibraryName, iFactoryClass, 0, iDesc, Dependencies, contextID); ClassRegistry->Push (factory); SortClassRegistry = true; return true; }
char const* GetContextName(csStringID s) { return s != csInvalidStringID ? contexts.Request(s) : "{none}"; }
void csSCF::ScanPluginsInt (csPathsList const* pluginPaths, const char* context) { if (pluginPaths) { // Search plugins in pluginpaths csRef<iStringArray> plugins; size_t i, j; for (i = 0; i < pluginPaths->Length(); i++) { csPathsList::Entry const& pathrec = (*pluginPaths)[i]; if (IsVerbose(SCF_VERBOSE_PLUGIN_SCAN)) { char const* x = scannedDirs.Contains(pathrec.path) ? "re-" : ""; csPrintfErr("SCF_NOTIFY: %sscanning plugin directory: %s " "(context `%s'; recursive %s)\n", x, pathrec.path.GetData(), GetContextName(pathrec.type), pathrec.scanRecursive ? "yes" : "no"); } if (plugins) plugins->Empty(); csRef<iStringArray> messages = csScanPluginDir (pathrec.path, plugins, pathrec.scanRecursive); scannedDirs.Request(pathrec.path); if ((messages != 0) && (messages->GetSize () > 0)) { csPrintfErr("SCF_WARNING: the following issue(s) arose while " "scanning '%s':", pathrec.path.GetData()); for (j = 0; j < messages->GetSize (); j++) csPrintfErr(" %s\n", messages->Get (j)); } csRef<iDocument> metadata; csRef<iString> msg; for (j = 0; j < plugins->GetSize (); j++) { char const* plugin = plugins->Get(j); msg = csGetPluginMetadata (plugin, metadata); if (msg != 0) { csPrintfErr("SCF_ERROR: metadata retrieval error for %s: %s\n", plugin, msg->GetData ()); } // It is possible for an error or warning message to be generated even // when metadata is also obtained. Likewise, it is possible for no // metadata to be obtained yet also to have no error message. The // latter case is indicative of csScanPluginDir() returning "potential" // plugins which turn out to not be Crystal Space plugins after all. // For instance, on Windows, the scan might find a DLL which is not a // Crystal Space DLL; that is, which does not contain embedded // metadata. This is a valid case, which we simply ignore since it is // legal for non-CS libraries to exist alongside CS plugins in the // scanned directories. if (metadata) RegisterClasses(plugin, metadata, context ? context : pathrec.type.GetData()); } } } }
scfInterfaceID csSCF::GetInterfaceID (const char *iInterface) { CS::Threading::RecursiveMutexScopedLock lock (mutex); return (scfInterfaceID)InterfaceRegistry.Request (iInterface); }
char const* csSCF::GetInterfaceName (scfInterfaceID i) const { CS::Threading::RecursiveMutexScopedLock lock (mutex); return InterfaceRegistry.Request (i); }