/** * @brief Returns a class instance from an instanced library * @param lib - [in] dynamic library instance * @param className - [in] class name * @return pointer to class instance */ DynClass* DynLoader::GetClassInstance(DynLib& lib, const dyn_string& className) { for(auto entry : lib.instances) { if(entry->name == className) return entry->instance; } dyn_string builderName("Create" + className); // POSIX guarantees that the size of a pointer to object is equal to // the size of a pointer to a function. On Windows NT systems this is also a safe // assumption. std::function<DynClass*()> builder(std::bind( reinterpret_cast<DynClass*(*)()>(GetSymbolByName(lib, builderName.c_str())))); if(builder == nullptr) throw LoaderException("Factory builder `" + builderName + "` for Class `" + className + "` not found in " + lib.name); // Create an instance of the class auto instance = builder(); if(instance == nullptr) throw LoaderException("Unable to create instance of class `" + className + "`"); auto entry = new DynClassEntry(className, instance); lib.instances.push_back(entry); return instance; }
/** * @brief Get dynamic library * @param libName - [in] library file name * @return dynamic library * @throw LoaderException - cannot load library */ DynamicLibrary & DynamicLibraryManager::GetLibrary( const PDL_CHAR * libName ) { DynamicLibrary & library = GetLibraryInstance( libName ); if ( !library.Opened() ) { // We tried to load this library before, but we've failed throw LoaderException( pdl_string( "Cannot load library `" ) + pdl_string( libName ) + pdl_string( "`" ) ); } return library; }
/** * @brief Get symbol by name * @param symbolName - [in] symbol name * @return pointer to symbol, 0 if not found */ void * DynamicLibrary::GetSymbolByName( const PDL_CHAR * symbolName ) { if ( !library_ ) { throw LoaderException( pdl_string( "Library is not opened" ) ); } return #if PLATFORM_WIN32 static_cast< void * >( ::GetProcAddress( library_, symbolName ) ); #elif PLATFORM_POSIX dlsym( library_, symbolName ); #endif }
/** * @brief Get dynamic library instance * @param libName - [in] library file name * @return dynamic library instance */ DynamicLibrary & DynamicLibraryManager::GetLibraryInstance( const PDL_CHAR * libName ) { if ( !libName ) { throw LoaderException( pdl_string( "Library name is 0" ) ); } DynamicLibrary * library = 0; const LibraryMap::iterator libraryInstance( libraries_.find( libName ) ); if ( libraryInstance != libraries_.end() ) { library = libraryInstance -> second; } else { library = new DynamicLibrary(); libraries_[ libName ] = library; if ( ( library ) && ( !library -> Open( libName, true ) ) ) { // This is the first time we try to load this library. // We are able to specify the reason of failure. throw LoaderException( pdl_string( "Cannot load library `" ) + pdl_string( libName ) + pdl_string( "`: " ) + library -> GetLastError() ); } } if ( !library ) { // Actually, this should never happen. // If it has happened, this means serious memory damage throw LoaderException( pdl_string( "Internal error" ) ); } return ( *library ); }
template<> unique_ptr<ID3D10Effect> ResourceService::LoadResource<ID3D10Effect>(const std::tstring& filePath) { ID3D10Blob* pErrorBlob; ID3D10Effect* pEffect; HRESULT hr = D3DX10CreateEffectFromFile(filePath.c_str(), NULL, NULL, "fx_4_0", #ifndef NDEBUG D3D10_SHADER_DEBUG|D3D10_SHADER_SKIP_OPTIMIZATION|D3D10_SHADER_WARNINGS_ARE_ERRORS|D3D10_SHADER_PACK_MATRIX_ROW_MAJOR, //HLSL Flags: http://msdn.microsoft.com/en-us/library/windows/desktop/bb172416%28v=vs.85%29.aspx #else D3D10_SHADER_OPTIMIZATION_LEVEL3|D3D10_SHADER_IEEE_STRICTNESS|D3D10_SHADER_PACK_MATRIX_ROW_MAJOR, #endif 0, MyServiceLocator::GetInstance()->GetService<IGraphicsService>()->GetGraphicsDevice()->GetDevice(), NULL, NULL, &pEffect, &pErrorBlob, NULL); if(FAILED(hr)) { tstringstream ss; if(pErrorBlob!=nullptr) { char *errors = (char*)pErrorBlob->GetBufferPointer(); for(unsigned int i = 0; i < pErrorBlob->GetBufferSize(); i++) ss<<errors[i]; OutputDebugString(ss.str().c_str()); pErrorBlob->Release(); throw LoaderException(_T("effect ") + filePath, ss.str() ); } MyServiceLocator::GetInstance()->GetService<DebugService>()->LogDirectXError(hr, __LINE__, __FILE__); } return unique_ptr<ID3D10Effect>(pEffect); }
/** * @brief Get class instance * @param className - [in] class name * @return pointer to class instance */ DynamicClass * DynamicLibrary::GetInstance( const PDL_CHAR * className ) { const InstanceMap::iterator loadedInstance( instances_.find( className ) ); if ( loadedInstance != instances_.end() ) { return ( loadedInstance -> second ); } const pdl_string builderName( pdl_string( "Create" ) + pdl_string( className ) ); // Tricky code to prevent compiler error // ISO C++ forbids casting between pointer-to-function and pointer-to-object DynamicBuilder builder = 0; void * symbol = GetSymbolByName( builderName.c_str() ); ( void ) memcpy( &builder, &symbol, sizeof( void * ) ); if ( !builder ) { instances_[ className ] = 0; throw LoaderException( pdl_string( "Class `" ) + pdl_string( className ) + pdl_string( "` not found in " ) + libraryName_ ); } DynamicClass * instance = ( DynamicClass * )( *builder )(); instances_[ className ] = instance; return instance; }