25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

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