#ifndef LIB_SHADER_FILE_HPP #define LIB_SHADER_FILE_HPP #include #include #include #include #include #if WIN32 || WIN64 || _WIN32 || _WIN64 # include #elif LINUX || __linux__ # include #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 { errUnknown = -1, errNone = 0x00000000, errNotInit = 0x00000001, errInvalidHandleShaderFile = 0x00000010, errInvalidHandleShaderGenerator = 0x00000011, errInvalidHandleStream = 0x00000012, 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, }; enum SeekOrigin { soBeg = 0, soCur = 1, soEnd = 2, }; class IFileReader { public: /** request to load shader code * @param filename filename/name to identify data to be load * @param is input stream to write loaded data into * @returns TRUE on success, FALSE otherwise */ virtual bool loadStream(const std::string& filename, std::ostream& os) = 0; }; class IFileWriter { public: /** request to store shader code * @param filename filename/name to identify data to be saved * @param os output stream to read saved data from */ virtual void saveStream(const std::string& filename, std::istream& is) = 0; }; /** 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); /** load shader file from function * @param filename file to load shader code from * @param reader file reader to use for loading */ void loadFromFunc(std::string filename, IFileReader& reader); /** save shader file to a given file * @param filename file to save shader code to */ void saveToFile(std::string filename) const; /** save shader file to function * @param filename file to save shader code to * @param writer file writer to use for saving */ void saveToFunc(std::string filename, IFileWriter& writer); /** 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 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 vector 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 T getAddr(lsf::Library::Handle handle, const char* name) { return reinterpret_cast(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 T getAddr(lsf::Library::Handle handle, const char* name) { return reinterpret_cast(dlsym(handle, name)); }; int libClose(lsf::Library::Handle handle) { return !dlclose(handle); }; #else # error "unknown operation system" #endif /* Library::Impl ******************************************************************************************************************/ struct lsf::Library::Impl { public: typedef void* StreamHandle; /* pure callbacks */ typedef void (WINAPI *lsf_shader_file_log_callback_t) (const LogLevel loglevel, const char* msg, void* userargs); typedef void (WINAPI *lsf_save_data_callback_t) (const char* filename, const StreamHandle handle, const void* userargs); typedef bool (WINAPI *lsf_load_data_callback_t) (const char* filename, const StreamHandle handle, const void* userargs); /* ShaderFile */ typedef ShaderFile::Handle (WINAPI *lsf_shader_file_create_t) (); 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_load_from_func_t) (const ShaderFile::Handle handle, const char* filename, const lsf_load_data_callback_t callback, const void* userargs); typedef ErrorCode (WINAPI *lsf_shader_file_save_to_file_t) (const ShaderFile::Handle handle, const char* filename); typedef ErrorCode (WINAPI *lsf_shader_file_save_to_func_t) (const ShaderFile::Handle handle, const char* filename, const lsf_save_data_callback_t callback, const void* userargs); 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); /* Generator */ 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); /* Stream */ typedef int (WINAPI *lsf_stream_get_size_t) (const StreamHandle handle); typedef ErrorCode (WINAPI *lsf_stream_set_size_t) (const StreamHandle handle, const int size); typedef int (WINAPI *lsf_stream_seek_t) (const StreamHandle handle, const int offset, const SeekOrigin origin); typedef int (WINAPI *lsf_stream_read_t) (const StreamHandle handle, void *buffer, const int size); typedef int (WINAPI *lsf_stream_write_t) (const StreamHandle handle, const void *buffer, const int size); /* Library */ 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) (); public: class InStreamBuf : public std::streambuf { private: const Library::Impl& _impl; StreamHandle _handle; const std::streamsize _bufferSize; const std::streamsize _putBack; std::vector _buffer; void resetBuffer() { char* end = &_buffer.front() + _buffer.size(); setg(end, end, end); } protected: virtual int_type underflow() { if (gptr() < egptr()) return traits_type::to_int_type(*gptr()); char *base = &_buffer.front(); char *start = base; if (eback() == base) { std::memmove(base, egptr() - _putBack, _putBack); start += _putBack; } int n = _impl.lsf_stream_read(_handle, start, _buffer.size() - (start - base)); if (n < 0) throw Exception(_impl.lsf_get_last_error_msg(), _impl.lsf_get_last_error_code()); if (n == 0) return traits_type::eof(); setg(base, start, start + n); return traits_type::to_int_type(*gptr()); } virtual std::streamsize xsgetn(char* buffer, std::streamsize count) { std::streamsize ret = 0; char* b = buffer; std::streamsize s = std::min(static_cast(egptr() - gptr()), count); if (s > 0) { memmove(b, gptr(), s); gbump(s); b += s; ret += s; count -= s; resetBuffer(); } if (count > 0) { int n = _impl.lsf_stream_read(_handle, b, count); if (n < 0) throw Exception(_impl.lsf_get_last_error_msg(), _impl.lsf_get_last_error_code()); ret += n; } return ret; } virtual pos_type seekoff(off_type offset, std::ios_base::seekdir dir, std::ios_base::openmode mode) { if (mode & std::ios_base::out) return (std::streampos(-1)); int pos = 0; switch(dir) { case std::ios::beg: pos = _impl.lsf_stream_seek(_handle, offset, soBeg); break; case std::ios::cur: pos = _impl.lsf_stream_seek(_handle, offset, soCur); break; case std::ios::end: pos = _impl.lsf_stream_seek(_handle, offset, soEnd); break; } if (pos < 0) throw Exception(_impl.lsf_get_last_error_msg(), _impl.lsf_get_last_error_code()); resetBuffer(); return pos; } virtual pos_type seekpos(pos_type offset, std::ios_base::openmode mode) { return seekoff(offset, std::ios::beg, mode); } public: InStreamBuf(const Impl& impl, StreamHandle handle, std::streamsize bufferSize = 1024, std::streamsize putBack = 32) : _impl (impl), _handle (handle), _bufferSize (bufferSize), _putBack (putBack), _buffer (bufferSize) { resetBuffer(); }; }; class OutStreamBuf : public std::streambuf { private: const Library::Impl& _impl; StreamHandle _handle; const std::streamsize _bufferSize; std::vector _buffer; inline int doWrite(const char* buffer, int size) { int ret = _impl.lsf_stream_write(_handle, buffer, size); if (ret < 0) throw Exception(_impl.lsf_get_last_error_msg(), _impl.lsf_get_last_error_code()); } bool doFlush() { int n = pptr() - pbase(); pbump(-n); int ret = doWrite(pbase(), n); return (ret == n); } protected: virtual int_type overflow(int_type ch) { if (ch != traits_type::eof()) { if (pptr() > epptr()) throw Exception("internal error in OutStreamBuf", errUnknown); *pptr() = ch; pbump(1); if (doFlush()) return ch; } return traits_type::eof(); } virtual int sync() { return (doFlush() ? 0 : -1); } virtual std::streamsize xsputn(const char *buffer, std::streamsize count) { if (!doFlush()) return 0; return doWrite(buffer, count); } virtual pos_type seekoff(off_type offset, std::ios_base::seekdir dir, std::ios_base::openmode mode) { if (mode & std::ios_base::in) return (std::streampos(-1)); int pos = 0; switch(dir) { case std::ios::beg: pos = _impl.lsf_stream_seek(_handle, offset, soBeg); break; case std::ios::cur: pos = _impl.lsf_stream_seek(_handle, offset, soCur); break; case std::ios::end: pos = _impl.lsf_stream_seek(_handle, offset, soEnd); break; } if (pos < 0) throw Exception(_impl.lsf_get_last_error_msg(), _impl.lsf_get_last_error_code()); return pos; } virtual pos_type seekpos(pos_type offset, std::ios_base::openmode mode) { return seekoff(offset, std::ios::beg, mode); } public: OutStreamBuf(const Impl& impl, StreamHandle handle, std::streamsize bufferSize = 1024) : _impl (impl), _handle (handle), _bufferSize (bufferSize), _buffer (bufferSize) { char *base = &_buffer.front(); setp(base, base + _buffer.size() - 1); }; }; public: 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_load_from_func_t lsf_shader_file_load_from_func; lsf_shader_file_save_to_file_t lsf_shader_file_save_to_file; lsf_shader_file_save_to_func_t lsf_shader_file_save_to_func; 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_stream_get_size_t lsf_stream_get_size; lsf_stream_set_size_t lsf_stream_set_size; lsf_stream_seek_t lsf_stream_seek; lsf_stream_read_t lsf_stream_read; lsf_stream_write_t lsf_stream_write; 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_load_from_func (NULL), lsf_shader_file_save_to_file (NULL), lsf_shader_file_save_to_func (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_stream_get_size (NULL), lsf_stream_set_size (NULL), lsf_stream_seek (NULL), lsf_stream_read (NULL), lsf_stream_write (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) { }; public: struct DataCallbackArgs { const Impl* impl; IFileReader* reader; IFileWriter* writer; }; /** callback method to save data * @param filename filename to save data to * @param handle stream handle with data to save * @param userargs user defined arguments */ static void WINAPI saveDataCallback(const char* filename, const StreamHandle handle, const void* userargs) { const DataCallbackArgs *args = static_cast(userargs); InStreamBuf buf(*args->impl, handle); std::istream is(&buf); args->writer->saveStream(filename, is); } /** callback method to load data * @param filename filename to load data from * @param handle stream handle to write loaded data to * @param userargs user defined arguments * @returns TRUE on success, FALSE otherwise */ static bool WINAPI loadDataCallback(const char* filename, const StreamHandle handle, const void* userargs) { const DataCallbackArgs *args = static_cast(userargs); OutStreamBuf buf(*args->impl, handle); std::ostream os(&buf); return args->reader->loadStream(filename, os); } }; /* Library ************************************************************************************************************************/ template inline void loadProc(lsf::Library::Handle handle, T& proc, const char* name) { proc = getAddr(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_load_from_func, "lsf_ShaderFile_loadFromFunc"); loadProc(_handle, _impl->lsf_shader_file_save_to_file, "lsf_ShaderFile_saveToFile"); loadProc(_handle, _impl->lsf_shader_file_save_to_func, "lsf_ShaderFile_saveToFunc"); 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_stream_get_size, "lsf_Stream_getSize"); loadProc(_handle, _impl->lsf_stream_set_size, "lsf_Stream_setSize"); loadProc(_handle, _impl->lsf_stream_seek, "lsf_Stream_seek"); loadProc(_handle, _impl->lsf_stream_read, "lsf_Stream_read"); loadProc(_handle, _impl->lsf_stream_write, "lsf_Stream_write"); 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(_impl.lsf_get_last_error_msg(), err); } void lsf::ShaderFile::loadFromFunc(std::string filename, IFileReader& reader) { lsf::Library::Impl::DataCallbackArgs args; args.impl = &_impl; args.reader = &reader; ErrorCode err = _impl.lsf_shader_file_load_from_func(_handle, filename.c_str(), &Library::Impl::loadDataCallback, &args); if (err != errNone) throw Exception(_impl.lsf_get_last_error_msg(), 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(_impl.lsf_get_last_error_msg(), err); } void lsf::ShaderFile::saveToFunc(std::string filename, IFileWriter& writer) { lsf::Library::Impl::DataCallbackArgs args; args.impl = &_impl; args.writer = &writer; ErrorCode err = _impl.lsf_shader_file_save_to_func(_handle, filename.c_str(), &Library::Impl::saveDataCallback, &args); if (err != errNone) throw Exception(_impl.lsf_get_last_error_msg(), 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(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 */