|
- #ifndef LIB_SHADER_FILE_HPP
- #define LIB_SHADER_FILE_HPP
-
- #include <string>
- #include <sstream>
- #include <vector>
- #include <stdint.h>
-
- #if WIN32 || WIN64 || _WIN32 || _WIN64
- # include <windows.h>
- #elif LINUX || __linux__
- # include <dlfcn.h>
- #else
- # error "unknown operation system"
- #endif
-
- #if __MINGW32__
- # define WINAPI __stdcall
- #else
- # define WINAPI
- #endif
-
- /**********************************************************************************************************************************/
- /* public interface */
- /**********************************************************************************************************************************/
- namespace lsf
- {
- enum LogLevel
- {
- llDebug = 0,
- llInfo = 1,
- llWarning = 2,
- llError = 3,
- };
-
- enum ErrorCode
- {
- errNone = 0x00000000,
- errNotInit = 0x00000001,
- errInvalidHandleShaderFile = 0x00000010,
- errInvalidHandleShaderGenerator = 0x00000011,
- errInvalidGeneratorName = 0x00000020,
- errInvalidPropertyIndex = 0x00000021,
- errInvalidPropertyName = 0x00000022,
- errGeneratorNotAssignedToFile = 0x00000023,
- errUnknownIdentfifier = 0x00001000,
- errDuplicateIdentifier = 0x00001001,
- errOutOfRange = 0x00001002,
- errInvalidIdentifier = 0x00001003,
- errInvalidParamterCount = 0x00001004,
- errInvalidParamter = 0x00001005,
- errUnexpectedToken = 0x00001006,
- errInvalidToken = 0x00001007,
- errExpressionInternal = 0x00001008,
- errExpression = 0x00001009,
- errShaderPartInternal = 0x0000100a,
- errShaderPart = 0x0000100b,
- errInvalidLibraryName = 0x00002000,
- errInvalidLibraryHandle = 0x00002001,
- errInvalidMethodName = 0x00002002,
- errUnknown = 0xffffffff,
- };
-
- /** class to load and manage shared library */
- class Library
- {
- friend class ShaderFile;
- friend class Generator;
-
- public:
- #if WIN32 || WIN64 || _WIN32 || _WIN64
- typedef HMODULE Handle; //!< shader file handle
- #elif LINUX || __linux__
- typedef void* Handle; //!< shader file handle
- #else
- #error "unknown operation system"
- #endif
-
- private:
- struct Impl; //!< struct that implements the libraries methods
- Impl* _impl; //!< struct that implements the libraries methods
- Handle _handle; //!< handle of shared library
-
- public:
- /** get last error code
- * @return error code of last failed operation */
- ErrorCode getLastErrorCode() const;
-
- /** get last error message
- * @return error message of last failed operation */
- std::string getLastErrorMsg() const;
-
- /** get last error trace
- * @return error trace of last failed operation */
- std::string getLastErrorTrace() const;
-
- /** constructor
- * @param libName name of shared library file */
- Library(std::string libName);
-
- /** destructor */
- virtual ~Library();
-
- private:
- /** deleted copy constructor */
- Library(const Library& that) { };
- };
-
- /** class to manage a shader file */
- class ShaderFile
- {
- public:
- typedef void* Handle; //!< shader file handle
-
- private:
- const Library::Impl& _impl; //!< struct that implements the libraries methods
- Handle _handle; //!< handle of this shader file
-
- protected:
- /** method to log messages from shader file and code generation
- * @param logLevel level of the log message
- * @param msg message to write log log */
- virtual void logMsg(LogLevel logLevel, const std::string& msg);
-
- public:
- /** get shader file handle
- * @return handle of this shader file */
- Handle getHandle() const;
-
- /** get library
- * @return library object this shader file is attached to */
- const Library& getLibrary() const;
-
- /** load shader file from a given file
- * @param filename file to load shader code from */
- void loadFromFile(std::string filename);
-
- /** save shader file to a given file
- * @param filename file to save shader code to */
- void saveToFile(std::string filename) const;
-
- /** constructor
- * @param library library this shader file is attached to */
- ShaderFile(const Library& library);
-
- /** destructor */
- virtual ~ShaderFile();
-
- private:
- /** deleted copy constructor */
- ShaderFile(const ShaderFile& that);
-
- public:
- /** callback method for log messages
- * @param logLevel log level of the log message
- * @param msg log message
- * @param userargs user defined arguments */
- static void WINAPI logCallback(const LogLevel loglevel, const char* msg, void* userargs);
- };
-
- /** class to manage a shader code generator */
- class Generator
- {
- public:
- typedef void* Handle; //!< shader generator handle
- typedef std::vector<std::string> StringVec; //!< vector of strings
-
- private:
- const Library::Impl& _impl; //!< struct that implements the libraries methods
- const ShaderFile& _shaderFile; //!< shader file the generator is attached to
- std::string _name; //!< name of this generator
- Handle _handle; //!< handle of this generator
- StringVec _propertyNames; //!< vector with all known properties
-
- public:
- /** get generator name
- * @return name of this generator */
- std::string getName() const;
-
- /** get generator handle
- * @return handle of this generator */
- Handle getHandle() const;
-
- /** get shader file this generator is attached to
- * @return shader file this genrator is attached to */
- const ShaderFile& getShaderFile() const;
-
- /** get a vector of all known properties
- * @return vecotr with all known properties */
- const StringVec& getPropertyNames() const;
-
- /** get the value of a single property by its name
- * @param name name of the property
- * @return value of the property */
- std::string getProperty(const std::string& name) const;
-
- /** get the value of a single property by its index
- * @param index index of the property (see getPropertyNames() to get the index of a property)
- * @return value of the property */
- std::string getProperty(int index) const;
-
- /** set the value of a single property by its name
- * @param name name of the property
- * @param value value of the property */
- void setProperty(const std::string& name, const std::string& value);
-
- /** set the value of a single property by its index
- * @param index index of the property (see getPropertyNames() to get the index of a property)
- * @param value value of the property */
- void setProperty(int index, const std::string& value);
-
- /** generate the shader code with the current property setup
- * @return generated shader code */
- std::string generateCode() const;
-
- /** constructor
- * @param shaderFile shader file this generator is attached to
- * @param name name of a valid generator inside the shaderFile */
- Generator(const ShaderFile& shaderFile, std::string name);
-
- /** destructor */
- virtual ~Generator();
-
- private:
- /** deleted copy constructor */
- Generator(const Generator& that);
- };
-
- /** object to handle error inside this library */
- class Exception : public std::exception
- {
- private:
- std::string _message; //!< error message
- ErrorCode _errorCode; //!< suitable error code to the error message
-
- public:
- /** get error code
- * @return error code of this exception */
- ErrorCode getErrorCode() const;
-
- /** get error message
- * @return error message of this exception */
- std::string getMessage() const;
-
- /** @return error message of this exception */
- virtual const char* what() const throw();
-
- /** constructor */
- Exception(std::string message, ErrorCode errorCode = errUnknown);
-
- /** destructor */
- ~Exception() throw();
- };
- }
-
-
-
-
- /**********************************************************************************************************************************/
- /* private implementation */
- /**********************************************************************************************************************************/
- #if WIN32 || WIN64 || _WIN32 || _WIN64
- lsf::Library::Handle libOpen(const char* name)
- { return LoadLibrary(name); };
-
- template <typename T>
- T getAddr(lsf::Library::Handle handle, const char* name)
- { return reinterpret_cast<T>(GetProcAddress(handle, name)); };
-
- int libClose(lsf::Library::Handle handle)
- { return FreeLibrary(handle); };
-
- #elif LINUX || __linux__
- lsf::Library::Handle libOpen(const char* name)
- { return dlopen(name, RTLD_LAZY); };
-
- template <typename T>
- T getAddr(lsf::Library::Handle handle, const char* name)
- { return reinterpret_cast<T>(dlsym(handle, name)); };
-
- int libClose(lsf::Library::Handle handle)
- { return !dlclose(handle); };
-
- #else
- # error "unknown operation system"
- #endif
-
- /* Library::Impl ******************************************************************************************************************/
- struct lsf::Library::Impl
- {
- typedef ShaderFile::Handle (WINAPI *lsf_shader_file_create_t) ();
- typedef void (WINAPI *lsf_shader_file_log_callback_t) (const LogLevel loglevel, const char* msg, void* userargs);
- typedef ErrorCode (WINAPI *lsf_shader_file_set_log_callback_t) (const ShaderFile::Handle handle, const lsf_shader_file_log_callback_t callback, void* userargs);
- typedef ErrorCode (WINAPI *lsf_shader_file_load_from_file_t) (const ShaderFile::Handle handle, const char* filename);
- typedef ErrorCode (WINAPI *lsf_shader_file_save_to_file_t) (const ShaderFile::Handle handle, const char* filename);
- typedef const char* (WINAPI *lsf_shader_file_get_generator_names_t) (const ShaderFile::Handle handle);
- typedef ErrorCode (WINAPI *lsf_shader_file_destroy_t) (const ShaderFile::Handle handle);
-
- typedef Generator::Handle (WINAPI *lsf_generator_create_t) (const ShaderFile::Handle handle, const char* name);
- typedef const char* (WINAPI *lsf_generator_get_property_names_t) (const Generator::Handle handle);
- typedef const char* (WINAPI *lsf_generator_get_property_t) (const Generator::Handle handle, const int index);
- typedef const char* (WINAPI *lsf_generator_get_property_by_name_t) (const Generator::Handle handle, const char* name);
- typedef ErrorCode (WINAPI *lsf_generator_set_property_t) (const Generator::Handle handle, const int index, const char* value);
- typedef ErrorCode (WINAPI *lsf_generator_set_property_by_name_t) (const Generator::Handle handle, const char* name, const char* value);
- typedef const char* (WINAPI *lsf_generator_generate_code_t) (const Generator::Handle handle);
- typedef ErrorCode (WINAPI *lsf_generator_destroy_t) (const Generator::Handle handle);
-
- typedef ErrorCode (WINAPI *lsf_init_t) ();
- typedef ErrorCode (WINAPI *lsf_get_last_error_code_t) ();
- typedef const char* (WINAPI *lsf_get_last_error_msg_t) ();
- typedef const char* (WINAPI *lsf_get_last_error_trace_t) ();
- typedef ErrorCode (WINAPI *lsf_finish_t) ();
-
- const Library& library;
-
- lsf_shader_file_create_t lsf_shader_file_create;
- lsf_shader_file_set_log_callback_t lsf_shader_file_set_log_callback;
- lsf_shader_file_load_from_file_t lsf_shader_file_load_from_file;
- lsf_shader_file_save_to_file_t lsf_shader_file_save_to_file;
- lsf_shader_file_get_generator_names_t lsf_shader_file_get_generator_names;
- lsf_shader_file_destroy_t lsf_shader_file_destroy;
-
- lsf_generator_create_t lsf_generator_create;
- lsf_generator_get_property_names_t lsf_generator_get_property_names;
- lsf_generator_get_property_t lsf_generator_get_property;
- lsf_generator_get_property_by_name_t lsf_generator_get_property_by_name;
- lsf_generator_set_property_t lsf_generator_set_property;
- lsf_generator_set_property_by_name_t lsf_generator_set_property_by_name;
- lsf_generator_generate_code_t lsf_generator_generate_code;
- lsf_generator_destroy_t lsf_generator_destroy;
-
- lsf_init_t lsf_init;
- lsf_get_last_error_code_t lsf_get_last_error_code;
- lsf_get_last_error_msg_t lsf_get_last_error_msg;
- lsf_get_last_error_trace_t lsf_get_last_error_trace;
- lsf_finish_t lsf_finish;
-
- Impl(const Library& library) :
- library (library),
-
- lsf_shader_file_create (NULL),
- lsf_shader_file_set_log_callback (NULL),
- lsf_shader_file_load_from_file (NULL),
- lsf_shader_file_save_to_file (NULL),
- lsf_shader_file_get_generator_names (NULL),
- lsf_shader_file_destroy (NULL),
-
- lsf_generator_create (NULL),
- lsf_generator_get_property_names (NULL),
- lsf_generator_get_property (NULL),
- lsf_generator_get_property_by_name (NULL),
- lsf_generator_set_property (NULL),
- lsf_generator_set_property_by_name (NULL),
- lsf_generator_generate_code (NULL),
- lsf_generator_destroy (NULL),
-
- lsf_init (NULL),
- lsf_get_last_error_code (NULL),
- lsf_get_last_error_msg (NULL),
- lsf_get_last_error_trace (NULL),
- lsf_finish (NULL)
- { };
- };
-
- /* Library ************************************************************************************************************************/
- template <typename T>
- inline void loadProc(lsf::Library::Handle handle, T& proc, const char* name)
- {
- proc = getAddr<T>(handle, name);
- if (!proc)
- throw lsf::Exception(std::string("unable to load method from library: ") + name, lsf::errInvalidMethodName);
- }
-
- lsf::ErrorCode lsf::Library::getLastErrorCode() const
- { return _impl->lsf_get_last_error_code(); }
-
- std::string lsf::Library::getLastErrorMsg() const
- { return std::string(_impl->lsf_get_last_error_msg()); }
-
- std::string lsf::Library::getLastErrorTrace() const
- { return std::string(_impl->lsf_get_last_error_trace()); }
-
- lsf::Library::Library(std::string libName) :
- _impl(new Impl(*this))
- {
- _handle = libOpen(libName.c_str());
- if (!_handle)
- throw Exception("unable to open shared library: " + libName, lsf::errInvalidLibraryName);
-
- loadProc(_handle, _impl->lsf_shader_file_create, "lsf_ShaderFile_create");
- loadProc(_handle, _impl->lsf_shader_file_set_log_callback, "lsf_ShaderFile_setLogCallback");
- loadProc(_handle, _impl->lsf_shader_file_load_from_file, "lsf_ShaderFile_loadFromFile");
- loadProc(_handle, _impl->lsf_shader_file_save_to_file, "lsf_ShaderFile_saveToFile");
- loadProc(_handle, _impl->lsf_shader_file_get_generator_names, "lsf_ShaderFile_getGeneratorNames");
- loadProc(_handle, _impl->lsf_shader_file_destroy, "lsf_ShaderFile_destroy");
-
- loadProc(_handle, _impl->lsf_generator_create, "lsf_Generator_create");
- loadProc(_handle, _impl->lsf_generator_get_property_names, "lsf_Generator_getPropertyNames");
- loadProc(_handle, _impl->lsf_generator_get_property, "lsf_Generator_getProperty");
- loadProc(_handle, _impl->lsf_generator_get_property_by_name, "lsf_Generator_getPropertyByName");
- loadProc(_handle, _impl->lsf_generator_set_property, "lsf_Generator_setProperty");
- loadProc(_handle, _impl->lsf_generator_set_property_by_name, "lsf_Generator_setPropertyByName");
- loadProc(_handle, _impl->lsf_generator_generate_code, "lsf_Generator_generateCode");
- loadProc(_handle, _impl->lsf_generator_destroy, "lsf_Generator_destroy");
-
- loadProc(_handle, _impl->lsf_init, "lsf_init");
- loadProc(_handle, _impl->lsf_get_last_error_code, "lsf_getLastErrorCode");
- loadProc(_handle, _impl->lsf_get_last_error_msg, "lsf_getLastErrorMsg");
- loadProc(_handle, _impl->lsf_get_last_error_trace, "lsf_getLastErrorTrace");
- loadProc(_handle, _impl->lsf_finish, "lsf_finish");
-
- ErrorCode err = _impl->lsf_init();
- if (err != lsf::errNone)
- throw Exception("unable to initialize library", err);
- }
-
- lsf::Library::~Library()
- {
- if (_impl)
- {
- _impl->lsf_finish();
- delete _impl;
- _impl = NULL;
- }
- if (_handle)
- {
- libClose(_handle);
- _handle = NULL;
- }
- }
-
- /* ShaderFile *********************************************************************************************************************/
- void lsf::ShaderFile::logMsg(LogLevel logLevel, const std::string& msg)
- { /* DUMMY */ }
-
- inline lsf::ShaderFile::Handle lsf::ShaderFile::getHandle() const
- { return _handle; }
-
- inline const lsf::Library& lsf::ShaderFile::getLibrary() const
- { return _impl.library; }
-
- void lsf::ShaderFile::loadFromFile(std::string filename)
- {
- ErrorCode err = _impl.lsf_shader_file_load_from_file(_handle, filename.c_str());
- if (err != errNone)
- throw Exception("unable to load file", err);
- }
-
- void lsf::ShaderFile::saveToFile(std::string filename) const
- {
- ErrorCode err = _impl.lsf_shader_file_load_from_file(_handle, filename.c_str());
- if (err != errNone)
- throw Exception("unable to load file", err);
- }
-
- lsf::ShaderFile::ShaderFile(const Library& library) :
- _impl(*library._impl)
- {
- _handle = _impl.lsf_shader_file_create();
- if (!_handle)
- throw Exception(_impl.lsf_get_last_error_msg(), _impl.lsf_get_last_error_code());
- ErrorCode err = _impl.lsf_shader_file_set_log_callback(_handle, &ShaderFile::logCallback, this);
- if (err != errNone)
- logMsg(llWarning, "unable to register log callback");
- }
-
- lsf::ShaderFile::~ShaderFile()
- {
- _impl.lsf_shader_file_destroy(_handle);
- _handle = NULL;
- }
-
- void lsf::ShaderFile::logCallback(const lsf::LogLevel loglevel, const char* msg, void* userargs)
- {
- static_cast<ShaderFile*>(userargs)->logMsg(loglevel, std::string(msg));
- }
-
- /* Generator **********************************************************************************************************************/
- inline std::string lsf::Generator::getName() const
- { return _name; };
-
- inline lsf::Generator::Handle lsf::Generator::getHandle() const
- { return _handle; };
-
- inline const lsf::ShaderFile& lsf::Generator::getShaderFile() const
- { return _shaderFile; };
-
- inline const lsf::Generator::StringVec& lsf::Generator::getPropertyNames() const
- { return _propertyNames; };
-
- std::string lsf::Generator::getProperty(const std::string& name) const
- {
- const char* ret = _impl.lsf_generator_get_property_by_name(_handle, name.c_str());
- if (!ret)
- throw Exception(_impl.lsf_get_last_error_msg(), _impl.lsf_get_last_error_code());
- return std::string(ret);
- }
-
- std::string lsf::Generator::getProperty(int index) const
- {
- const char* ret = _impl.lsf_generator_get_property(_handle, index);
- if (!ret)
- throw Exception(_impl.lsf_get_last_error_msg(), _impl.lsf_get_last_error_code());
- return std::string(ret);
- }
-
- void lsf::Generator::setProperty(const std::string& name, const std::string& value)
- {
- ErrorCode err = _impl.lsf_generator_set_property_by_name(_handle, name.c_str(), value.c_str());
- if (err != errNone)
- throw Exception(_impl.lsf_get_last_error_msg(), err);
- }
-
- void lsf::Generator::setProperty(int index, const std::string& value)
- {
- ErrorCode err = _impl.lsf_generator_set_property(_handle, index, value.c_str());
- if (err != errNone)
- throw Exception(_impl.lsf_get_last_error_msg(), err);
- }
-
- std::string lsf::Generator::generateCode() const
- {
- const char* ret = _impl.lsf_generator_generate_code(_handle);
- if (!ret)
- throw Exception(_impl.lsf_get_last_error_msg(), _impl.lsf_get_last_error_code());
- return std::string(ret);
- }
-
- lsf::Generator::Generator(const ShaderFile& shaderFile, std::string name) :
- _shaderFile (shaderFile),
- _impl (*shaderFile.getLibrary()._impl),
- _name (name)
- {
- _handle = _impl.lsf_generator_create(_shaderFile.getHandle(), _name.c_str());
- if (!_handle)
- throw Exception(_impl.lsf_get_last_error_msg(), _impl.lsf_get_last_error_code());
- const char* propertyNames = _impl.lsf_generator_get_property_names(_handle);
- if (propertyNames)
- {
- std::stringstream ss(propertyNames);
- std::string item;
- while (std::getline(ss, item, '\x10'))
- _propertyNames.push_back(item);
- }
- }
-
- lsf::Generator::~Generator()
- {
- _impl.lsf_generator_destroy(_handle);
- _handle = NULL;
- }
-
- /* Exception **********************************************************************************************************************/
- inline lsf::ErrorCode lsf::Exception::getErrorCode() const
- { return _errorCode; }
-
- inline std::string lsf::Exception::getMessage() const
- { return _message; }
-
- const char* lsf::Exception::what() const throw()
- { return _message.c_str(); };
-
- lsf::Exception::Exception(std::string message, ErrorCode errorCode) :
- _message (message),
- _errorCode (errorCode)
- { }
-
- lsf::Exception::~Exception() throw()
- { }
-
- #endif /* LIB_SHADER_FILE_HPP */
-
-
|