00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #pragma once
00013
00015 #include <map>
00016
00017 #include "nvsgcommon.h"
00018
00019 #if defined(LINUX)
00020 #include <dlfcn.h>
00021 #endif
00022 #include "nvutil/PlugInCallback.h"
00023
00024 namespace nvutil {
00025
00026 #if defined(_WIN32)
00027 # define HLIB HMODULE
00028 # define MapLibrary(name) LoadLibrary(name)
00029 # define UnMapLibrary FreeLibrary
00030 # define GetFuncAddress GetProcAddress
00031 # define LibExtStr "*.dll"
00032 #elif defined(LINUX)
00033 # define HLIB void*
00034 # define MapLibrary(name) dlopen(name, RTLD_LAZY)
00035 # define UnMapLibrary(handle) dlclose(handle)
00036 # define GetFuncAddress dlsym
00037 # define LibExtStr "*.so"
00038 #else
00039 # error Undefined Operating System!
00040 #endif
00041
00043
00050 class UPITID
00051 {
00052 public:
00054
00056 UPITID() {}
00058
00060 NVSG_API UPITID( unsigned short pit
00061 , const char verStr[16]
00062 );
00064
00066 NVSG_API UPITID(const UPITID& rhs);
00068
00072 friend bool operator<( const UPITID& lhs
00073 , const UPITID& rhs
00074 );
00076
00079 friend bool operator==( const UPITID& lhs
00080 , const UPITID& rhs
00081 );
00083
00086 friend bool operator!=( const UPITID& lhs
00087 , const UPITID& rhs
00088 );
00089
00090 private:
00091 unsigned short data0;
00092 char data1[16];
00093 };
00094
00096
00101 class UPIID
00102 {
00103 public:
00105
00107 UPIID() {};
00109
00112 NVSG_API UPIID( const char idstr[8]
00113 , UPITID pitid
00114 );
00116
00119 NVSG_API UPIID& operator=(const UPIID& rhs);
00120
00122
00134 const char * getPlugSpecificIDString() const;
00136
00140 const UPITID& getPlugInterfaceType() const;
00141
00143
00147 friend bool operator<( const UPIID& lhs
00148 , const UPIID& rhs
00149 );
00151
00154 friend bool operator==( const UPIID& lhs
00155 , const UPIID& rhs
00156 );
00158
00161 friend bool operator!=( const UPIID& lhs
00162 , const UPIID& rhs
00163 );
00164
00165 private:
00166 char data0[8];
00167 UPITID data1;
00168 };
00169
00170 inline const char * UPIID::getPlugSpecificIDString() const
00171 {
00172 return data0;
00173 }
00174
00175 inline const UPITID& UPIID::getPlugInterfaceType() const
00176 {
00177 return data1;
00178 }
00179
00180
00181 inline bool operator<(const UPITID& lhs, const UPITID& rhs)
00182 {
00183 return (lhs.data0==rhs.data0) ? stricmp(lhs.data1, rhs.data1)<0 : lhs.data0<rhs.data0;
00184 }
00185
00186
00187 inline bool operator==(const UPITID& lhs, const UPITID& rhs)
00188 {
00189 return lhs.data0==rhs.data0 && !stricmp(lhs.data1, rhs.data1);
00190 }
00191
00192
00193 inline bool operator!=(const UPITID& lhs, const UPITID& rhs)
00194 {
00195 return !(lhs==rhs);
00196 }
00197
00198
00199 inline bool operator<(const UPIID& lhs, const UPIID& rhs)
00200 {
00201 return (lhs.data1==rhs.data1) ? stricmp(lhs.data0, rhs.data0)<0 : lhs.data1<rhs.data1;
00202 }
00203
00204
00205 inline bool operator==(const UPIID& lhs, const UPIID& rhs)
00206 {
00207 return !stricmp(lhs.data0, rhs.data0) && lhs.data1==rhs.data1;
00208 }
00209
00210
00211 inline bool operator!=(const UPIID& lhs, const UPIID& rhs)
00212 {
00213 return !(lhs==rhs);
00214 }
00215
00216
00217 class PlugIn;
00218
00220 typedef bool (*PFNGETPLUGINTERFACE)(const UPIID& piid, PlugIn *& plugIn);
00222 typedef bool (*PFNQUERYPLUGINTERFACETYPE)(const UPITID& pitid, std::vector<UPIID>& piids);
00223
00225
00227 class PlugIn
00228 {
00230
00233 friend class PlugInServer;
00234
00235 public:
00236 PlugIn();
00237
00239
00240 void setCallback( PlugInCallback *cb
00241 , bool throwExceptionOnError = true
00242 );
00243
00244 protected:
00245 virtual ~PlugIn();
00247
00254 virtual void deleteThis(void) = 0;
00255
00257 const PlugInCallback * callback( void ) const;
00258
00259 private:
00260 PlugInCallback * m_cb;
00261 };
00262
00263 inline PlugIn::PlugIn()
00264 : m_cb(NULL)
00265 {
00266 }
00267
00268 inline void PlugIn::setCallback( PlugInCallback *cb, bool throwExceptionOnError )
00269 {
00270 if ( m_cb )
00271 {
00272 m_cb->removeRef();
00273 }
00274 m_cb = cb;
00275 if ( m_cb )
00276 {
00277 m_cb->addRef();
00278 m_cb->setThrowExceptionOnError( throwExceptionOnError );
00279 }
00280 }
00281
00282 inline const PlugInCallback * PlugIn::callback( void ) const
00283 {
00284 return( m_cb );
00285 }
00286
00287 inline PlugIn::~PlugIn()
00288 {
00289 if ( m_cb )
00290 {
00291 m_cb->removeRef();
00292 }
00293 }
00294
00296
00303 class PlugInServer
00304 {
00305 public:
00306
00308
00337 friend NVSG_API bool getInterface(
00338 const std::vector<std::string>& searchPath
00339 , const UPIID& piid
00340 , PlugIn *& plugIn
00341 );
00342
00344
00355 friend NVSG_API bool queryInterfaceType(
00356 const std::vector<std::string>& searchPath
00357 , const UPITID& pitid
00358 , std::vector<UPIID>& piids
00359 );
00360
00362
00364 friend NVSG_API void releaseInterface(
00365 const UPIID& piid
00366 );
00367
00369
00372 friend NVSG_API void setPlugInFileFilter(
00373 const std::string& filter
00374 );
00375
00376 PlugInServer();
00377 ~PlugInServer();
00378
00379 private:
00380
00381 bool getInterfaceImpl(const std::vector<std::string>& searchPath, const UPIID& piid, PlugIn *& plugIn);
00382 bool queryInterfaceTypeImpl(const std::vector<std::string>& searchPath, const UPITID& pitid, std::vector<UPIID>& piids);
00383 void releaseInterfaceImpl(const UPIID& piid);
00384 void setFileFilterImpl(const std::string& filter);
00385
00386 private:
00387
00388 class PlugInHolder
00389 {
00390 public:
00391 PlugInHolder(PlugIn * plugIn) : m_plugIn(plugIn), m_refCnt(1) {}
00392 void addRef() { ++m_refCnt; }
00393 size_t removeRef() { __ASSERT(m_refCnt>0); return --m_refCnt; }
00394 PlugIn * getPlugIn() const { return m_plugIn; }
00395 private:
00396 PlugIn * m_plugIn;
00397 size_t m_refCnt;
00398 };
00399 bool findPlugIns(const std::vector<std::string>& searchPath, std::vector<std::string>& plugIns);
00400 bool registerPlugIn(const std::string& fileName, const UPIID& piid, PlugIn *& plugIn);
00401 typedef std::map< UPIID, PlugInHolder*> PlugInMap;
00402 PlugInMap m_plugIns;
00403 std::string m_filter;
00404 };
00405
00407 typedef Singleton<PlugInServer> PIS;
00408
00409 }