You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

897 lines
36 KiB

  1. #ifndef LIB_SHADER_FILE_HPP
  2. #define LIB_SHADER_FILE_HPP
  3. #include <string>
  4. #include <sstream>
  5. #include <cstring>
  6. #include <vector>
  7. #include <stdint.h>
  8. #if WIN32 || WIN64 || _WIN32 || _WIN64
  9. # include <windows.h>
  10. #elif LINUX || __linux__
  11. # include <dlfcn.h>
  12. #else
  13. # error "unknown operation system"
  14. #endif
  15. #if __MINGW32__
  16. # define WINAPI __stdcall
  17. #else
  18. # define WINAPI
  19. #endif
  20. /**********************************************************************************************************************************/
  21. /* public interface */
  22. /**********************************************************************************************************************************/
  23. namespace lsf
  24. {
  25. enum LogLevel
  26. {
  27. llDebug = 0,
  28. llInfo = 1,
  29. llWarning = 2,
  30. llError = 3,
  31. };
  32. enum ErrorCode
  33. {
  34. errUnknown = -1,
  35. errNone = 0x00000000,
  36. errNotInit = 0x00000001,
  37. errInvalidHandleShaderFile = 0x00000010,
  38. errInvalidHandleShaderGenerator = 0x00000011,
  39. errInvalidHandleStream = 0x00000012,
  40. errInvalidGeneratorName = 0x00000020,
  41. errInvalidPropertyIndex = 0x00000021,
  42. errInvalidPropertyName = 0x00000022,
  43. errGeneratorNotAssignedToFile = 0x00000023,
  44. errUnknownIdentfifier = 0x00001000,
  45. errDuplicateIdentifier = 0x00001001,
  46. errOutOfRange = 0x00001002,
  47. errInvalidIdentifier = 0x00001003,
  48. errInvalidParamterCount = 0x00001004,
  49. errInvalidParamter = 0x00001005,
  50. errUnexpectedToken = 0x00001006,
  51. errInvalidToken = 0x00001007,
  52. errExpressionInternal = 0x00001008,
  53. errExpression = 0x00001009,
  54. errShaderPartInternal = 0x0000100a,
  55. errShaderPart = 0x0000100b,
  56. errInvalidLibraryName = 0x00002000,
  57. errInvalidLibraryHandle = 0x00002001,
  58. errInvalidMethodName = 0x00002002,
  59. };
  60. enum SeekOrigin
  61. {
  62. soBeg = 0,
  63. soCur = 1,
  64. soEnd = 2,
  65. };
  66. class IFileReader
  67. {
  68. public:
  69. /** request to load shader code
  70. * @param filename filename/name to identify data to be load
  71. * @param is input stream to write loaded data into
  72. * @returns TRUE on success, FALSE otherwise */
  73. virtual bool loadStream(const std::string& filename, std::ostream& os) = 0;
  74. };
  75. class IFileWriter
  76. {
  77. public:
  78. /** request to store shader code
  79. * @param filename filename/name to identify data to be saved
  80. * @param os output stream to read saved data from */
  81. virtual void saveStream(const std::string& filename, std::istream& is) = 0;
  82. };
  83. /** class to load and manage shared library */
  84. class Library
  85. {
  86. friend class ShaderFile;
  87. friend class Generator;
  88. public:
  89. #if WIN32 || WIN64 || _WIN32 || _WIN64
  90. typedef HMODULE Handle; //!< shader file handle
  91. #elif LINUX || __linux__
  92. typedef void* Handle; //!< shader file handle
  93. #else
  94. #error "unknown operation system"
  95. #endif
  96. private:
  97. struct Impl; //!< struct that implements the libraries methods
  98. Impl* _impl; //!< struct that implements the libraries methods
  99. Handle _handle; //!< handle of shared library
  100. public:
  101. /** get last error code
  102. * @return error code of last failed operation */
  103. ErrorCode getLastErrorCode() const;
  104. /** get last error message
  105. * @return error message of last failed operation */
  106. std::string getLastErrorMsg() const;
  107. /** get last error trace
  108. * @return error trace of last failed operation */
  109. std::string getLastErrorTrace() const;
  110. /** constructor
  111. * @param libName name of shared library file */
  112. Library(std::string libName);
  113. /** destructor */
  114. virtual ~Library();
  115. private:
  116. /** deleted copy constructor */
  117. Library(const Library& that) { };
  118. };
  119. /** class to manage a shader file */
  120. class ShaderFile
  121. {
  122. public:
  123. typedef void* Handle; //!< shader file handle
  124. private:
  125. const Library::Impl& _impl; //!< struct that implements the libraries methods
  126. Handle _handle; //!< handle of this shader file
  127. protected:
  128. /** method to log messages from shader file and code generation
  129. * @param logLevel level of the log message
  130. * @param msg message to write log log */
  131. virtual void logMsg(LogLevel logLevel, const std::string& msg);
  132. public:
  133. /** get shader file handle
  134. * @return handle of this shader file */
  135. Handle getHandle() const;
  136. /** get library
  137. * @return library object this shader file is attached to */
  138. const Library& getLibrary() const;
  139. /** load shader file from a given file
  140. * @param filename file to load shader code from */
  141. void loadFromFile(std::string filename);
  142. /** load shader file from function
  143. * @param filename file to load shader code from
  144. * @param reader file reader to use for loading */
  145. void loadFromFunc(std::string filename, IFileReader& reader);
  146. /** save shader file to a given file
  147. * @param filename file to save shader code to */
  148. void saveToFile(std::string filename) const;
  149. /** save shader file to function
  150. * @param filename file to save shader code to
  151. * @param writer file writer to use for saving */
  152. void saveToFunc(std::string filename, IFileWriter& writer);
  153. /** constructor
  154. * @param library library this shader file is attached to */
  155. ShaderFile(const Library& library);
  156. /** destructor */
  157. virtual ~ShaderFile();
  158. private:
  159. /** deleted copy constructor */
  160. ShaderFile(const ShaderFile& that);
  161. public:
  162. /** callback method for log messages
  163. * @param logLevel log level of the log message
  164. * @param msg log message
  165. * @param userargs user defined arguments */
  166. static void WINAPI logCallback(const LogLevel loglevel, const char* msg, void* userargs);
  167. };
  168. /** class to manage a shader code generator */
  169. class Generator
  170. {
  171. public:
  172. typedef void* Handle; //!< shader generator handle
  173. typedef std::vector<std::string> StringVec; //!< vector of strings
  174. private:
  175. const Library::Impl& _impl; //!< struct that implements the libraries methods
  176. const ShaderFile& _shaderFile; //!< shader file the generator is attached to
  177. std::string _name; //!< name of this generator
  178. Handle _handle; //!< handle of this generator
  179. StringVec _propertyNames; //!< vector with all known properties
  180. public:
  181. /** get generator name
  182. * @return name of this generator */
  183. std::string getName() const;
  184. /** get generator handle
  185. * @return handle of this generator */
  186. Handle getHandle() const;
  187. /** get shader file this generator is attached to
  188. * @return shader file this genrator is attached to */
  189. const ShaderFile& getShaderFile() const;
  190. /** get a vector of all known properties
  191. * @return vector with all known properties */
  192. const StringVec& getPropertyNames() const;
  193. /** get the value of a single property by its name
  194. * @param name name of the property
  195. * @return value of the property */
  196. std::string getProperty(const std::string& name) const;
  197. /** get the value of a single property by its index
  198. * @param index index of the property (see getPropertyNames() to get the index of a property)
  199. * @return value of the property */
  200. std::string getProperty(int index) const;
  201. /** set the value of a single property by its name
  202. * @param name name of the property
  203. * @param value value of the property */
  204. void setProperty(const std::string& name, const std::string& value);
  205. /** set the value of a single property by its index
  206. * @param index index of the property (see getPropertyNames() to get the index of a property)
  207. * @param value value of the property */
  208. void setProperty(int index, const std::string& value);
  209. /** generate the shader code with the current property setup
  210. * @return generated shader code */
  211. std::string generateCode() const;
  212. /** constructor
  213. * @param shaderFile shader file this generator is attached to
  214. * @param name name of a valid generator inside the shaderFile */
  215. Generator(const ShaderFile& shaderFile, std::string name);
  216. /** destructor */
  217. virtual ~Generator();
  218. private:
  219. /** deleted copy constructor */
  220. Generator(const Generator& that);
  221. };
  222. /** object to handle error inside this library */
  223. class Exception : public std::exception
  224. {
  225. private:
  226. std::string _message; //!< error message
  227. ErrorCode _errorCode; //!< suitable error code to the error message
  228. public:
  229. /** get error code
  230. * @return error code of this exception */
  231. ErrorCode getErrorCode() const;
  232. /** get error message
  233. * @return error message of this exception */
  234. std::string getMessage() const;
  235. /** @return error message of this exception */
  236. virtual const char* what() const throw();
  237. /** constructor */
  238. Exception(std::string message, ErrorCode errorCode = errUnknown);
  239. /** destructor */
  240. ~Exception() throw();
  241. };
  242. }
  243. /**********************************************************************************************************************************/
  244. /* private implementation */
  245. /**********************************************************************************************************************************/
  246. #if WIN32 || WIN64 || _WIN32 || _WIN64
  247. lsf::Library::Handle libOpen(const char* name)
  248. { return LoadLibrary(name); };
  249. template <typename T>
  250. T getAddr(lsf::Library::Handle handle, const char* name)
  251. { return reinterpret_cast<T>(GetProcAddress(handle, name)); };
  252. int libClose(lsf::Library::Handle handle)
  253. { return FreeLibrary(handle); };
  254. #elif LINUX || __linux__
  255. lsf::Library::Handle libOpen(const char* name)
  256. { return dlopen(name, RTLD_LAZY); };
  257. template <typename T>
  258. T getAddr(lsf::Library::Handle handle, const char* name)
  259. { return reinterpret_cast<T>(dlsym(handle, name)); };
  260. int libClose(lsf::Library::Handle handle)
  261. { return !dlclose(handle); };
  262. #else
  263. # error "unknown operation system"
  264. #endif
  265. /* Library::Impl ******************************************************************************************************************/
  266. struct lsf::Library::Impl
  267. {
  268. public:
  269. typedef void* StreamHandle;
  270. /* pure callbacks */
  271. typedef void (WINAPI *lsf_shader_file_log_callback_t) (const LogLevel loglevel, const char* msg, void* userargs);
  272. typedef void (WINAPI *lsf_save_data_callback_t) (const char* filename, const StreamHandle handle, const void* userargs);
  273. typedef bool (WINAPI *lsf_load_data_callback_t) (const char* filename, const StreamHandle handle, const void* userargs);
  274. /* ShaderFile */
  275. typedef ShaderFile::Handle (WINAPI *lsf_shader_file_create_t) ();
  276. typedef ErrorCode (WINAPI *lsf_shader_file_set_log_callback_t) (const ShaderFile::Handle handle, const lsf_shader_file_log_callback_t callback, void* userargs);
  277. typedef ErrorCode (WINAPI *lsf_shader_file_load_from_file_t) (const ShaderFile::Handle handle, const char* filename);
  278. 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);
  279. typedef ErrorCode (WINAPI *lsf_shader_file_save_to_file_t) (const ShaderFile::Handle handle, const char* filename);
  280. 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);
  281. typedef const char* (WINAPI *lsf_shader_file_get_generator_names_t) (const ShaderFile::Handle handle);
  282. typedef ErrorCode (WINAPI *lsf_shader_file_destroy_t) (const ShaderFile::Handle handle);
  283. /* Generator */
  284. typedef Generator::Handle (WINAPI *lsf_generator_create_t) (const ShaderFile::Handle handle, const char* name);
  285. typedef const char* (WINAPI *lsf_generator_get_property_names_t) (const Generator::Handle handle);
  286. typedef const char* (WINAPI *lsf_generator_get_property_t) (const Generator::Handle handle, const int index);
  287. typedef const char* (WINAPI *lsf_generator_get_property_by_name_t) (const Generator::Handle handle, const char* name);
  288. typedef ErrorCode (WINAPI *lsf_generator_set_property_t) (const Generator::Handle handle, const int index, const char* value);
  289. typedef ErrorCode (WINAPI *lsf_generator_set_property_by_name_t) (const Generator::Handle handle, const char* name, const char* value);
  290. typedef const char* (WINAPI *lsf_generator_generate_code_t) (const Generator::Handle handle);
  291. typedef ErrorCode (WINAPI *lsf_generator_destroy_t) (const Generator::Handle handle);
  292. /* Stream */
  293. typedef int (WINAPI *lsf_stream_get_size_t) (const StreamHandle handle);
  294. typedef ErrorCode (WINAPI *lsf_stream_set_size_t) (const StreamHandle handle, const int size);
  295. typedef int (WINAPI *lsf_stream_seek_t) (const StreamHandle handle, const int offset, const SeekOrigin origin);
  296. typedef int (WINAPI *lsf_stream_read_t) (const StreamHandle handle, void *buffer, const int size);
  297. typedef int (WINAPI *lsf_stream_write_t) (const StreamHandle handle, const void *buffer, const int size);
  298. /* Library */
  299. typedef ErrorCode (WINAPI *lsf_init_t) ();
  300. typedef ErrorCode (WINAPI *lsf_get_last_error_code_t) ();
  301. typedef const char* (WINAPI *lsf_get_last_error_msg_t) ();
  302. typedef const char* (WINAPI *lsf_get_last_error_trace_t) ();
  303. typedef ErrorCode (WINAPI *lsf_finish_t) ();
  304. public:
  305. class InStreamBuf : public std::streambuf
  306. {
  307. private:
  308. const Library::Impl& _impl;
  309. StreamHandle _handle;
  310. const std::streamsize _bufferSize;
  311. const std::streamsize _putBack;
  312. std::vector<char> _buffer;
  313. void resetBuffer()
  314. {
  315. char* end = &_buffer.front() + _buffer.size();
  316. setg(end, end, end);
  317. }
  318. protected:
  319. virtual int_type underflow()
  320. {
  321. if (gptr() < egptr())
  322. return traits_type::to_int_type(*gptr());
  323. char *base = &_buffer.front();
  324. char *start = base;
  325. if (eback() == base)
  326. {
  327. std::memmove(base, egptr() - _putBack, _putBack);
  328. start += _putBack;
  329. }
  330. int n = _impl.lsf_stream_read(_handle, start, _buffer.size() - (start - base));
  331. if (n < 0)
  332. throw Exception(_impl.lsf_get_last_error_msg(), _impl.lsf_get_last_error_code());
  333. if (n == 0)
  334. return traits_type::eof();
  335. setg(base, start, start + n);
  336. return traits_type::to_int_type(*gptr());
  337. }
  338. virtual std::streamsize xsgetn(char* buffer, std::streamsize count)
  339. {
  340. std::streamsize ret = 0;
  341. char* b = buffer;
  342. std::streamsize s = std::min(static_cast<std::streamsize>(egptr() - gptr()), count);
  343. if (s > 0)
  344. {
  345. memmove(b, gptr(), s);
  346. gbump(s);
  347. b += s;
  348. ret += s;
  349. count -= s;
  350. resetBuffer();
  351. }
  352. if (count > 0)
  353. {
  354. int n = _impl.lsf_stream_read(_handle, b, count);
  355. if (n < 0)
  356. throw Exception(_impl.lsf_get_last_error_msg(), _impl.lsf_get_last_error_code());
  357. ret += n;
  358. }
  359. return ret;
  360. }
  361. virtual pos_type seekoff(off_type offset, std::ios_base::seekdir dir, std::ios_base::openmode mode)
  362. {
  363. if (mode & std::ios_base::out)
  364. return (std::streampos(-1));
  365. int pos = 0;
  366. switch(dir)
  367. {
  368. case std::ios::beg:
  369. pos = _impl.lsf_stream_seek(_handle, offset, soBeg);
  370. break;
  371. case std::ios::cur:
  372. pos = _impl.lsf_stream_seek(_handle, offset, soCur);
  373. break;
  374. case std::ios::end:
  375. pos = _impl.lsf_stream_seek(_handle, offset, soEnd);
  376. break;
  377. }
  378. if (pos < 0)
  379. throw Exception(_impl.lsf_get_last_error_msg(), _impl.lsf_get_last_error_code());
  380. resetBuffer();
  381. return pos;
  382. }
  383. virtual pos_type seekpos(pos_type offset, std::ios_base::openmode mode)
  384. {
  385. return seekoff(offset, std::ios::beg, mode);
  386. }
  387. public:
  388. InStreamBuf(const Impl& impl, StreamHandle handle, std::streamsize bufferSize = 1024, std::streamsize putBack = 32) :
  389. _impl (impl),
  390. _handle (handle),
  391. _bufferSize (bufferSize),
  392. _putBack (putBack),
  393. _buffer (bufferSize)
  394. {
  395. resetBuffer();
  396. };
  397. };
  398. class OutStreamBuf : public std::streambuf
  399. {
  400. private:
  401. const Library::Impl& _impl;
  402. StreamHandle _handle;
  403. const std::streamsize _bufferSize;
  404. std::vector<char> _buffer;
  405. inline int doWrite(const char* buffer, int size)
  406. {
  407. int ret = _impl.lsf_stream_write(_handle, buffer, size);
  408. if (ret < 0)
  409. throw Exception(_impl.lsf_get_last_error_msg(), _impl.lsf_get_last_error_code());
  410. }
  411. bool doFlush()
  412. {
  413. int n = pptr() - pbase();
  414. pbump(-n);
  415. int ret = doWrite(pbase(), n);
  416. return (ret == n);
  417. }
  418. protected:
  419. virtual int_type overflow(int_type ch)
  420. {
  421. if (ch != traits_type::eof())
  422. {
  423. if (pptr() > epptr())
  424. throw Exception("internal error in OutStreamBuf", errUnknown);
  425. *pptr() = ch;
  426. pbump(1);
  427. if (doFlush())
  428. return ch;
  429. }
  430. return traits_type::eof();
  431. }
  432. virtual int sync()
  433. {
  434. return (doFlush() ? 0 : -1);
  435. }
  436. virtual std::streamsize xsputn(const char *buffer, std::streamsize count)
  437. {
  438. if (!doFlush())
  439. return 0;
  440. return doWrite(buffer, count);
  441. }
  442. virtual pos_type seekoff(off_type offset, std::ios_base::seekdir dir, std::ios_base::openmode mode)
  443. {
  444. if (mode & std::ios_base::in)
  445. return (std::streampos(-1));
  446. int pos = 0;
  447. switch(dir)
  448. {
  449. case std::ios::beg:
  450. pos = _impl.lsf_stream_seek(_handle, offset, soBeg);
  451. break;
  452. case std::ios::cur:
  453. pos = _impl.lsf_stream_seek(_handle, offset, soCur);
  454. break;
  455. case std::ios::end:
  456. pos = _impl.lsf_stream_seek(_handle, offset, soEnd);
  457. break;
  458. }
  459. if (pos < 0)
  460. throw Exception(_impl.lsf_get_last_error_msg(), _impl.lsf_get_last_error_code());
  461. return pos;
  462. }
  463. virtual pos_type seekpos(pos_type offset, std::ios_base::openmode mode)
  464. {
  465. return seekoff(offset, std::ios::beg, mode);
  466. }
  467. public:
  468. OutStreamBuf(const Impl& impl, StreamHandle handle, std::streamsize bufferSize = 1024) :
  469. _impl (impl),
  470. _handle (handle),
  471. _bufferSize (bufferSize),
  472. _buffer (bufferSize)
  473. {
  474. char *base = &_buffer.front();
  475. setp(base, base + _buffer.size() - 1);
  476. };
  477. };
  478. public:
  479. const Library& library;
  480. lsf_shader_file_create_t lsf_shader_file_create;
  481. lsf_shader_file_set_log_callback_t lsf_shader_file_set_log_callback;
  482. lsf_shader_file_load_from_file_t lsf_shader_file_load_from_file;
  483. lsf_shader_file_load_from_func_t lsf_shader_file_load_from_func;
  484. lsf_shader_file_save_to_file_t lsf_shader_file_save_to_file;
  485. lsf_shader_file_save_to_func_t lsf_shader_file_save_to_func;
  486. lsf_shader_file_get_generator_names_t lsf_shader_file_get_generator_names;
  487. lsf_shader_file_destroy_t lsf_shader_file_destroy;
  488. lsf_generator_create_t lsf_generator_create;
  489. lsf_generator_get_property_names_t lsf_generator_get_property_names;
  490. lsf_generator_get_property_t lsf_generator_get_property;
  491. lsf_generator_get_property_by_name_t lsf_generator_get_property_by_name;
  492. lsf_generator_set_property_t lsf_generator_set_property;
  493. lsf_generator_set_property_by_name_t lsf_generator_set_property_by_name;
  494. lsf_generator_generate_code_t lsf_generator_generate_code;
  495. lsf_generator_destroy_t lsf_generator_destroy;
  496. lsf_stream_get_size_t lsf_stream_get_size;
  497. lsf_stream_set_size_t lsf_stream_set_size;
  498. lsf_stream_seek_t lsf_stream_seek;
  499. lsf_stream_read_t lsf_stream_read;
  500. lsf_stream_write_t lsf_stream_write;
  501. lsf_init_t lsf_init;
  502. lsf_get_last_error_code_t lsf_get_last_error_code;
  503. lsf_get_last_error_msg_t lsf_get_last_error_msg;
  504. lsf_get_last_error_trace_t lsf_get_last_error_trace;
  505. lsf_finish_t lsf_finish;
  506. Impl(const Library& library) :
  507. library (library),
  508. lsf_shader_file_create (NULL),
  509. lsf_shader_file_set_log_callback (NULL),
  510. lsf_shader_file_load_from_file (NULL),
  511. lsf_shader_file_load_from_func (NULL),
  512. lsf_shader_file_save_to_file (NULL),
  513. lsf_shader_file_save_to_func (NULL),
  514. lsf_shader_file_get_generator_names (NULL),
  515. lsf_shader_file_destroy (NULL),
  516. lsf_generator_create (NULL),
  517. lsf_generator_get_property_names (NULL),
  518. lsf_generator_get_property (NULL),
  519. lsf_generator_get_property_by_name (NULL),
  520. lsf_generator_set_property (NULL),
  521. lsf_generator_set_property_by_name (NULL),
  522. lsf_generator_generate_code (NULL),
  523. lsf_generator_destroy (NULL),
  524. lsf_stream_get_size (NULL),
  525. lsf_stream_set_size (NULL),
  526. lsf_stream_seek (NULL),
  527. lsf_stream_read (NULL),
  528. lsf_stream_write (NULL),
  529. lsf_init (NULL),
  530. lsf_get_last_error_code (NULL),
  531. lsf_get_last_error_msg (NULL),
  532. lsf_get_last_error_trace (NULL),
  533. lsf_finish (NULL)
  534. { };
  535. public:
  536. struct DataCallbackArgs
  537. {
  538. const Impl* impl;
  539. IFileReader* reader;
  540. IFileWriter* writer;
  541. };
  542. /** callback method to save data
  543. * @param filename filename to save data to
  544. * @param handle stream handle with data to save
  545. * @param userargs user defined arguments */
  546. static void WINAPI saveDataCallback(const char* filename, const StreamHandle handle, const void* userargs)
  547. {
  548. const DataCallbackArgs *args = static_cast<const DataCallbackArgs*>(userargs);
  549. InStreamBuf buf(*args->impl, handle);
  550. std::istream is(&buf);
  551. args->writer->saveStream(filename, is);
  552. }
  553. /** callback method to load data
  554. * @param filename filename to load data from
  555. * @param handle stream handle to write loaded data to
  556. * @param userargs user defined arguments
  557. * @returns TRUE on success, FALSE otherwise */
  558. static bool WINAPI loadDataCallback(const char* filename, const StreamHandle handle, const void* userargs)
  559. {
  560. const DataCallbackArgs *args = static_cast<const DataCallbackArgs*>(userargs);
  561. OutStreamBuf buf(*args->impl, handle);
  562. std::ostream os(&buf);
  563. return args->reader->loadStream(filename, os);
  564. }
  565. };
  566. /* Library ************************************************************************************************************************/
  567. template <typename T>
  568. inline void loadProc(lsf::Library::Handle handle, T& proc, const char* name)
  569. {
  570. proc = getAddr<T>(handle, name);
  571. if (!proc)
  572. throw lsf::Exception(std::string("unable to load method from library: ") + name, lsf::errInvalidMethodName);
  573. }
  574. lsf::ErrorCode lsf::Library::getLastErrorCode() const
  575. { return _impl->lsf_get_last_error_code(); }
  576. std::string lsf::Library::getLastErrorMsg() const
  577. { return std::string(_impl->lsf_get_last_error_msg()); }
  578. std::string lsf::Library::getLastErrorTrace() const
  579. { return std::string(_impl->lsf_get_last_error_trace()); }
  580. lsf::Library::Library(std::string libName) :
  581. _impl(new Impl(*this))
  582. {
  583. _handle = libOpen(libName.c_str());
  584. if (!_handle)
  585. throw Exception("unable to open shared library: " + libName, lsf::errInvalidLibraryName);
  586. loadProc(_handle, _impl->lsf_shader_file_create, "lsf_ShaderFile_create");
  587. loadProc(_handle, _impl->lsf_shader_file_set_log_callback, "lsf_ShaderFile_setLogCallback");
  588. loadProc(_handle, _impl->lsf_shader_file_load_from_file, "lsf_ShaderFile_loadFromFile");
  589. loadProc(_handle, _impl->lsf_shader_file_load_from_func, "lsf_ShaderFile_loadFromFunc");
  590. loadProc(_handle, _impl->lsf_shader_file_save_to_file, "lsf_ShaderFile_saveToFile");
  591. loadProc(_handle, _impl->lsf_shader_file_save_to_func, "lsf_ShaderFile_saveToFunc");
  592. loadProc(_handle, _impl->lsf_shader_file_get_generator_names, "lsf_ShaderFile_getGeneratorNames");
  593. loadProc(_handle, _impl->lsf_shader_file_destroy, "lsf_ShaderFile_destroy");
  594. loadProc(_handle, _impl->lsf_generator_create, "lsf_Generator_create");
  595. loadProc(_handle, _impl->lsf_generator_get_property_names, "lsf_Generator_getPropertyNames");
  596. loadProc(_handle, _impl->lsf_generator_get_property, "lsf_Generator_getProperty");
  597. loadProc(_handle, _impl->lsf_generator_get_property_by_name, "lsf_Generator_getPropertyByName");
  598. loadProc(_handle, _impl->lsf_generator_set_property, "lsf_Generator_setProperty");
  599. loadProc(_handle, _impl->lsf_generator_set_property_by_name, "lsf_Generator_setPropertyByName");
  600. loadProc(_handle, _impl->lsf_generator_generate_code, "lsf_Generator_generateCode");
  601. loadProc(_handle, _impl->lsf_generator_destroy, "lsf_Generator_destroy");
  602. loadProc(_handle, _impl->lsf_stream_get_size, "lsf_Stream_getSize");
  603. loadProc(_handle, _impl->lsf_stream_set_size, "lsf_Stream_setSize");
  604. loadProc(_handle, _impl->lsf_stream_seek, "lsf_Stream_seek");
  605. loadProc(_handle, _impl->lsf_stream_read, "lsf_Stream_read");
  606. loadProc(_handle, _impl->lsf_stream_write, "lsf_Stream_write");
  607. loadProc(_handle, _impl->lsf_init, "lsf_init");
  608. loadProc(_handle, _impl->lsf_get_last_error_code, "lsf_getLastErrorCode");
  609. loadProc(_handle, _impl->lsf_get_last_error_msg, "lsf_getLastErrorMsg");
  610. loadProc(_handle, _impl->lsf_get_last_error_trace, "lsf_getLastErrorTrace");
  611. loadProc(_handle, _impl->lsf_finish, "lsf_finish");
  612. ErrorCode err = _impl->lsf_init();
  613. if (err != lsf::errNone)
  614. throw Exception("unable to initialize library", err);
  615. }
  616. lsf::Library::~Library()
  617. {
  618. if (_impl)
  619. {
  620. _impl->lsf_finish();
  621. delete _impl;
  622. _impl = NULL;
  623. }
  624. if (_handle)
  625. {
  626. libClose(_handle);
  627. _handle = NULL;
  628. }
  629. }
  630. /* ShaderFile *********************************************************************************************************************/
  631. void lsf::ShaderFile::logMsg(LogLevel logLevel, const std::string& msg)
  632. { /* DUMMY */ }
  633. inline lsf::ShaderFile::Handle lsf::ShaderFile::getHandle() const
  634. { return _handle; }
  635. inline const lsf::Library& lsf::ShaderFile::getLibrary() const
  636. { return _impl.library; }
  637. void lsf::ShaderFile::loadFromFile(std::string filename)
  638. {
  639. ErrorCode err = _impl.lsf_shader_file_load_from_file(_handle, filename.c_str());
  640. if (err != errNone)
  641. throw Exception(_impl.lsf_get_last_error_msg(), err);
  642. }
  643. void lsf::ShaderFile::loadFromFunc(std::string filename, IFileReader& reader)
  644. {
  645. lsf::Library::Impl::DataCallbackArgs args;
  646. args.impl = &_impl;
  647. args.reader = &reader;
  648. ErrorCode err = _impl.lsf_shader_file_load_from_func(_handle, filename.c_str(), &Library::Impl::loadDataCallback, &args);
  649. if (err != errNone)
  650. throw Exception(_impl.lsf_get_last_error_msg(), err);
  651. }
  652. void lsf::ShaderFile::saveToFile(std::string filename) const
  653. {
  654. ErrorCode err = _impl.lsf_shader_file_load_from_file(_handle, filename.c_str());
  655. if (err != errNone)
  656. throw Exception(_impl.lsf_get_last_error_msg(), err);
  657. }
  658. void lsf::ShaderFile::saveToFunc(std::string filename, IFileWriter& writer)
  659. {
  660. lsf::Library::Impl::DataCallbackArgs args;
  661. args.impl = &_impl;
  662. args.writer = &writer;
  663. ErrorCode err = _impl.lsf_shader_file_save_to_func(_handle, filename.c_str(), &Library::Impl::saveDataCallback, &args);
  664. if (err != errNone)
  665. throw Exception(_impl.lsf_get_last_error_msg(), err);
  666. }
  667. lsf::ShaderFile::ShaderFile(const Library& library) :
  668. _impl(*library._impl)
  669. {
  670. _handle = _impl.lsf_shader_file_create();
  671. if (!_handle)
  672. throw Exception(_impl.lsf_get_last_error_msg(), _impl.lsf_get_last_error_code());
  673. ErrorCode err = _impl.lsf_shader_file_set_log_callback(_handle, &ShaderFile::logCallback, this);
  674. if (err != errNone)
  675. logMsg(llWarning, "unable to register log callback");
  676. }
  677. lsf::ShaderFile::~ShaderFile()
  678. {
  679. _impl.lsf_shader_file_destroy(_handle);
  680. _handle = NULL;
  681. }
  682. void lsf::ShaderFile::logCallback(const lsf::LogLevel loglevel, const char* msg, void* userargs)
  683. {
  684. static_cast<ShaderFile*>(userargs)->logMsg(loglevel, std::string(msg));
  685. }
  686. /* Generator **********************************************************************************************************************/
  687. inline std::string lsf::Generator::getName() const
  688. { return _name; };
  689. inline lsf::Generator::Handle lsf::Generator::getHandle() const
  690. { return _handle; };
  691. inline const lsf::ShaderFile& lsf::Generator::getShaderFile() const
  692. { return _shaderFile; };
  693. inline const lsf::Generator::StringVec& lsf::Generator::getPropertyNames() const
  694. { return _propertyNames; };
  695. std::string lsf::Generator::getProperty(const std::string& name) const
  696. {
  697. const char* ret = _impl.lsf_generator_get_property_by_name(_handle, name.c_str());
  698. if (!ret)
  699. throw Exception(_impl.lsf_get_last_error_msg(), _impl.lsf_get_last_error_code());
  700. return std::string(ret);
  701. }
  702. std::string lsf::Generator::getProperty(int index) const
  703. {
  704. const char* ret = _impl.lsf_generator_get_property(_handle, index);
  705. if (!ret)
  706. throw Exception(_impl.lsf_get_last_error_msg(), _impl.lsf_get_last_error_code());
  707. return std::string(ret);
  708. }
  709. void lsf::Generator::setProperty(const std::string& name, const std::string& value)
  710. {
  711. ErrorCode err = _impl.lsf_generator_set_property_by_name(_handle, name.c_str(), value.c_str());
  712. if (err != errNone)
  713. throw Exception(_impl.lsf_get_last_error_msg(), err);
  714. }
  715. void lsf::Generator::setProperty(int index, const std::string& value)
  716. {
  717. ErrorCode err = _impl.lsf_generator_set_property(_handle, index, value.c_str());
  718. if (err != errNone)
  719. throw Exception(_impl.lsf_get_last_error_msg(), err);
  720. }
  721. std::string lsf::Generator::generateCode() const
  722. {
  723. const char* ret = _impl.lsf_generator_generate_code(_handle);
  724. if (!ret)
  725. throw Exception(_impl.lsf_get_last_error_msg(), _impl.lsf_get_last_error_code());
  726. return std::string(ret);
  727. }
  728. lsf::Generator::Generator(const ShaderFile& shaderFile, std::string name) :
  729. _shaderFile (shaderFile),
  730. _impl (*shaderFile.getLibrary()._impl),
  731. _name (name)
  732. {
  733. _handle = _impl.lsf_generator_create(_shaderFile.getHandle(), _name.c_str());
  734. if (!_handle)
  735. throw Exception(_impl.lsf_get_last_error_msg(), _impl.lsf_get_last_error_code());
  736. const char* propertyNames = _impl.lsf_generator_get_property_names(_handle);
  737. if (propertyNames)
  738. {
  739. std::stringstream ss(propertyNames);
  740. std::string item;
  741. while (std::getline(ss, item, '\x10'))
  742. _propertyNames.push_back(item);
  743. }
  744. }
  745. lsf::Generator::~Generator()
  746. {
  747. _impl.lsf_generator_destroy(_handle);
  748. _handle = NULL;
  749. }
  750. /* Exception **********************************************************************************************************************/
  751. inline lsf::ErrorCode lsf::Exception::getErrorCode() const
  752. { return _errorCode; }
  753. inline std::string lsf::Exception::getMessage() const
  754. { return _message; }
  755. const char* lsf::Exception::what() const throw()
  756. { return _message.c_str(); };
  757. lsf::Exception::Exception(std::string message, ErrorCode errorCode) :
  758. _message (message),
  759. _errorCode (errorCode)
  760. { }
  761. lsf::Exception::~Exception() throw()
  762. { }
  763. #endif /* LIB_SHADER_FILE_HPP */