00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef __SERVERBASE_H__
00013 #define __SERVERBASE_H__
00014
00015 #include <wx/dir.h>
00016 #include <vector>
00017 #include "modulehandle.h"
00018 #include "moddefs.h"
00019 #include "kernel.h"
00020
00021
00022 namespace VRUT
00023 {
00025 template <class T>
00026 class ServerBase
00027 {
00028 private:
00029 typedef std::vector<ModuleHandle<T> *> ModuleHandleList;
00031 ModuleHandleList moduleHandles;
00032
00033 protected:
00035 SERVER_ID serverID;
00037 MODULE_INSTANCE_ID instanceOffset;
00038
00042 std::vector<MODULE_HANDLE_ID> findModuleHandles(const wxString & name);
00044 ModuleHandle<T> * getModuleHandle(MODULE_HANDLE_ID id) const;
00046 MODULE_ID createPreferedModuleInstance();
00050 MODULE_ID createModuleInstance(const wxString libName = wxT("*"));
00052 T * getModule(const MODULE_ID & moduleID) const;
00054 void releaseModule(const MODULE_ID & id);
00056 void releaseModules();
00057
00058 public:
00060 ServerBase(SERVER_ID srvID, MODULE_INSTANCE_ID instOffset = 0);
00062 virtual ~ServerBase();
00063
00069 bool GetModules(ModuleList * moduleList, const wxString & moduleName, MODULE_INSTANCE_ID instanceID = MODULE_INSTANCE_ID_NONE);
00071 std::vector<wxFileName> GetAvailableModules();
00073 virtual size_t AddAvailableModules(const wxString & pathToModules);
00075 SERVER_ID GetID() const
00076 {
00077 return serverID;
00078 }
00079
00080 friend class Kernel;
00081 };
00082
00083
00084 template <class T>
00085 ServerBase<T>::ServerBase(SERVER_ID srvID, MODULE_INSTANCE_ID instOffset)
00086 : serverID(srvID), instanceOffset(instOffset)
00087 {
00088 }
00089
00090
00091 template <class T>
00092 ServerBase<T>::~ServerBase()
00093 {
00094 releaseModules();
00095 }
00096
00097
00098 template <class T>
00099 std::vector<MODULE_HANDLE_ID> ServerBase<T>::findModuleHandles(const wxString & name)
00100 {
00101 wxString nameU = name.Upper();
00102 #ifdef __WXDEBUG__
00103 if (!nameU.EndsWith(wxT("_D")))
00104 nameU.Append(wxT("_D"));
00105 #endif
00106 std::vector<MODULE_HANDLE_ID> foundHandles;
00107 for (MODULE_HANDLE_ID i = 0; i < moduleHandles.size(); i++)
00108 {
00109 const wxString modName = moduleHandles[i]->GetFileName().GetName().Upper();
00110 if (modName.Matches(nameU) || modName.Matches(wxT("LIB") + nameU))
00111 foundHandles.push_back(i);
00112 }
00113 return foundHandles;
00114 }
00115
00116
00117 template <class T>
00118 ModuleHandle<T> * ServerBase<T>::getModuleHandle(MODULE_HANDLE_ID index) const
00119 {
00120 return ( index >= moduleHandles.size() ? (ModuleHandle<T> *)NULL : moduleHandles[index] );
00121 }
00122
00123
00124 template <class T>
00125 MODULE_ID ServerBase<T>::createPreferedModuleInstance()
00126 {
00127 AddAvailableModules(MODULE_PATHS[serverID]);
00128 const Kernel::ModuleNamesList * preferedModules = KERNEL->GetPreferedModules();
00129 for (Kernel::ModuleNamesList::const_iterator nameIt = preferedModules->begin();
00130 nameIt != preferedModules->end(); nameIt++)
00131 {
00132 wxString lookForName = nameIt->Upper();
00133 for (typename ModuleHandleList::iterator it = moduleHandles.begin();
00134 it != moduleHandles.end(); it++)
00135 {
00136 wxString libName = (*it)->GetFileName().GetName();
00137 if (libName.Upper().Matches(wxString::Format(wxT("*%s*"), lookForName.c_str())))
00138 {
00139 MODULE_INSTANCE_ID modInstID = (*it)->InstantiateModule();
00140 if (modInstID != MODULE_INSTANCE_ID_NONE)
00141 return MODULE_ID(serverID, (*it)->GetID(), modInstID);
00142 else
00143 {
00144 LOGWARNING(wxString::Format(wxT("%sPreffered module '%s' is invalid, adding to forbidden list"),
00145 SERVER_CLASS_NAMES[serverID].c_str(), libName.c_str()));
00146 KERNEL->ForbidModule(libName);
00147 }
00148 }
00149 }
00150 }
00151
00152 return MODULE_ID_NONE;
00153 }
00154
00155
00156 template <class T>
00157 MODULE_ID ServerBase<T>::createModuleInstance(const wxString libName)
00158 {
00159 AddAvailableModules(MODULE_PATHS[serverID]);
00160 if (libName.IsSameAs(wxT("*")))
00161 {
00163 MODULE_ID modID = createPreferedModuleInstance();
00164 if (modID != MODULE_ID_NONE)
00165 return modID;
00166
00168 for (typename ModuleHandleList::iterator it = moduleHandles.begin();
00169 it != moduleHandles.end(); it++)
00170 {
00171 wxString modlibName = (*it)->GetFileName().GetName();
00172 if (!KERNEL->IsForbidden(modlibName))
00173 {
00174 MODULE_INSTANCE_ID modInstID = (*it)->InstantiateModule();
00175 if (modInstID != MODULE_INSTANCE_ID_NONE)
00176 return MODULE_ID(serverID, (*it)->GetID(), modInstID);
00177 else
00178 {
00179 LOGWARNING(wxString::Format(wxT("%Module '%s' is invalid, adding to forbidden list"),
00180 SERVER_CLASS_NAMES[serverID].c_str(), modlibName.c_str()));
00181 KERNEL->ForbidModule(modlibName);
00182 }
00183 }
00184 }
00185 }
00186 else
00187 {
00189 std::vector<MODULE_HANDLE_ID> foundHandles = findModuleHandles(libName);
00190 for (std::vector<MODULE_HANDLE_ID>::const_iterator hid = foundHandles.begin();
00191 hid != foundHandles.end(); hid++)
00192 {
00193 ModuleHandle<T> * modHandle = getModuleHandle(*hid);
00194 wxString modlibName = modHandle->GetFileName().GetName();
00195 if (!KERNEL->IsForbidden(modlibName))
00196 {
00197 MODULE_INSTANCE_ID modInstID = modHandle->InstantiateModule();
00198 if (modInstID != MODULE_INSTANCE_ID_NONE)
00199 return MODULE_ID(serverID, *hid, modInstID);
00200 else
00201 KERNEL->ForbidModule(modlibName);
00202 }
00203 }
00204 }
00205
00206 return MODULE_ID_NONE;
00207 }
00208
00209
00210 template <class T>
00211 T * ServerBase<T>::getModule(const MODULE_ID & moduleID) const
00212 {
00213 ModuleHandle<T> * moduleHandle = getModuleHandle(moduleID.GetHandleID());
00214 if (moduleHandle)
00215 return moduleHandle->GetModule(moduleID.GetInstanceID());
00216
00217 return (T *)NULL;
00218 }
00219
00220
00221 template <class T>
00222 void ServerBase<T>::releaseModule(const MODULE_ID & id)
00223 {
00224 ModuleHandle<T> * modHandle = getModuleHandle(id.GetHandleID());
00225 if (modHandle)
00226 modHandle->Release(id.GetInstanceID());
00227 }
00228
00229
00230 template <class T>
00231 bool ServerBase<T>::GetModules(ModuleList * moduleList, const wxString & moduleName, MODULE_INSTANCE_ID instanceID)
00232 {
00233 bool found = false;
00234 typename ModuleHandleList::iterator it;
00235 for (it = moduleHandles.begin(); it != moduleHandles.end(); it++)
00236 {
00237 if (*it && (*it)->IsLoaded())
00238 {
00239 wxString modFname = (*it)->GetFileName().GetName();
00240 wxString modName = (*it)->GetName();
00241 if (modFname.Matches(moduleName) ||
00242 ( !modName.IsEmpty() && modName.Matches(moduleName) ) )
00243 {
00244 if (instanceID != MODULE_INSTANCE_ID_NONE)
00245 {
00246 Module * module = (*it)->GetModule(instanceID);
00247 if (module)
00248 moduleList->push_back(ModulePair(module, instanceID));
00249 }
00250 else
00251 (*it)->GetModules(moduleList);
00252 found = true;
00253 }
00254 }
00255 }
00256 return found;
00257 }
00258
00259
00260 template <class T>
00261 std::vector<wxFileName> ServerBase<T>::GetAvailableModules()
00262 {
00263 AddAvailableModules(MODULE_PATHS[serverID]);
00264 std::vector<wxFileName> mods;
00265 typename ModuleHandleList::const_iterator it;
00266 for (it = moduleHandles.begin(); it != moduleHandles.end(); it++)
00267 mods.push_back((*it)->GetFileName());
00268
00269 return mods;
00270 }
00271
00272
00273 template <class T>
00274 size_t ServerBase<T>::AddAvailableModules(const wxString & pathToModules)
00275 {
00276 LOGVERBOSE(SERVER_CLASS_NAMES[serverID] + wxT("Searching for available modules"));
00277
00278 wxString mask = wxT("*") + wxDynamicLibrary::CanonicalizeName(wxT(""), wxDL_MODULE);
00279 unsigned modulesAdded = 0;
00280
00281 wxDir dir(pathToModules);
00282 if (dir.IsOpened())
00283 {
00284 wxString filename;
00285 bool cont = dir.GetFirst(&filename, mask, wxDIR_FILES);
00286 while (cont)
00287 {
00288 wxFileName wxfname(wxGetCwd() + wxT("/") + pathToModules + wxT("/") + filename);
00289 bool alreadyAdded = false;
00290 for (unsigned cur = 0; cur < moduleHandles.size() && !alreadyAdded; cur++)
00291 if (wxfname == moduleHandles[cur]->GetFileName())
00292 alreadyAdded = true;
00293
00294 if (!alreadyAdded)
00295 {
00296 #ifdef __WXDEBUG__
00297 if (filename.Matches(wxT("*_d.*")))
00298 {
00299 moduleHandles.push_back(new ModuleHandle<T>(MODULE_HANDLE_ID(moduleHandles.size()), serverID, wxfname, instanceOffset));
00300 #else
00301 if (!filename.Matches(wxT("*_d.*")))
00302 {
00303 moduleHandles.push_back(new ModuleHandle<T>(MODULE_HANDLE_ID(moduleHandles.size()), serverID, wxfname, instanceOffset));
00304 #endif // __WXDEBUG__
00305 LOG(pathToModules + wxT("/") + filename);
00306 modulesAdded++;
00307 }
00308 }
00309 cont = dir.GetNext(&filename);
00310 }
00311 }
00312
00313
00314 if (modulesAdded)
00315 LOG(wxString::Format(wxT("%s%i "), SERVER_CLASS_NAMES[serverID].c_str(), modulesAdded)
00316 + wxPLURAL("module", "modules", modulesAdded) + wxT(" added"));
00317
00318 return modulesAdded;
00319 }
00320
00321
00322 template <class T>
00323 void ServerBase<T>::releaseModules()
00324 {
00325 SAFE_DELETE_ARR_EACH(moduleHandles, moduleHandles.size());
00326 moduleHandles.clear();
00327 }
00328 };
00329
00330 #endif