| @@ -1,10 +1,11 @@ | |||
| #include <fstream> | |||
| #include <iostream> | |||
| #include "../../libShaderFile.hpp" | |||
| #if _WIN64 | |||
| static const char* LibName = "..\..\..\libShaderFile-x86_64-win64.dll"; | |||
| static const char* LibName = "..\\..\\..\\libShaderFile-x86_64-win64.dll"; | |||
| #elif _WIN32 | |||
| static const char* LibName = "..\..\..\libShaderFile-i386-win32.dll"; | |||
| static const char* LibName = "..\\..\\..\\libShaderFile-i386-win32.dll"; | |||
| #elif __linux__ && (__amd64 || __x86_64 || _M_AMD64 || __ppc64__) | |||
| static const char* LibName = "../../../libShaderFile-x86_64-linux.so"; | |||
| #elif __linux__ && (__i386 || _X86_) | |||
| @@ -13,6 +14,19 @@ static const char* LibName = "../../../libShaderFile-i386-linux.so"; | |||
| # error 'unknown operation system' | |||
| #endif | |||
| class FileReader : public lsf::IFileReader | |||
| { | |||
| public: | |||
| virtual bool loadStream(const std::string& filename, std::ostream& os) | |||
| { | |||
| std::ifstream fs(filename.c_str()); | |||
| if (!fs) | |||
| return false; | |||
| os << fs.rdbuf(); | |||
| return true; | |||
| } | |||
| }; | |||
| int main(int argc, char **argv) | |||
| { | |||
| try | |||
| @@ -28,7 +42,8 @@ int main(int argc, char **argv) | |||
| // create and load shader file | |||
| lsf::ShaderFile shaderFile(lib); | |||
| shaderFile.loadFromFile(argv[1]); | |||
| FileReader reader; | |||
| shaderFile.loadFromFunc(argv[1], reader); | |||
| const lsf::Library& l = shaderFile.getLibrary(); | |||
| @@ -2,9 +2,9 @@ | |||
| #include "../../libShaderFile.h" | |||
| #if _WIN64 | |||
| # define LIB_NAME "..\..\..\libShaderFile-x86_64-win64.dll" | |||
| # define LIB_NAME "..\\..\\..\\libShaderFile-x86_64-win64.dll" | |||
| #elif _WIN32 | |||
| # define LIB_NAME "..\..\..\libShaderFile-i386-win32.dll" | |||
| # define LIB_NAME "..\\..\\..\\libShaderFile-i386-win32.dll" | |||
| #elif __linux__ && (__amd64 || __x86_64 || _M_AMD64 || __ppc64__) | |||
| # define LIB_NAME "../../../libShaderFile-x86_64-linux.so" | |||
| #elif __linux__ && (__i386 || _X86_) | |||
| @@ -3,15 +3,34 @@ program example; | |||
| {$APPTYPE CONSOLE} | |||
| uses | |||
| SysUtils, | |||
| SysUtils, Classes, | |||
| ulibShaderFile; | |||
| type | |||
| TFileReader = class(TInterfacedObject, IlsfFileReader) | |||
| public | |||
| function LoadStream(const aFilename: String; const aStream: TStream): Boolean; | |||
| end; | |||
| var | |||
| i: Integer; | |||
| s: String; | |||
| ShaderFile: TlsfShaderFile; | |||
| Generator: TlsfGenerator; | |||
| function TFileReader.LoadStream(const aFilename: String; const aStream: TStream): Boolean; | |||
| var | |||
| fs: TFileStream; | |||
| begin | |||
| fs := TFileStream.Create(aFilename, fmOpenRead); | |||
| try | |||
| aStream.CopyFrom(fs, fs.Size - fs.Position); | |||
| result := true; | |||
| finally | |||
| FreeAndNil(fs); | |||
| end; | |||
| end; | |||
| begin | |||
| lsf_init(ExtractFilePath(ParamStr(0)) + '..\..\..\libShaderFile-i386-win32.dll'); | |||
| try | |||
| @@ -22,8 +41,8 @@ begin | |||
| end; | |||
| ShaderFile := TlsfShaderFile.Create; | |||
| try | |||
| ShaderFile.LoadFromFile(ParamStr(1)); | |||
| Generator := TlsfGenerator.Create(ShaderFile, ParamStr(2)); | |||
| ShaderFile.LoadFromFunc(ParamStr(1), TFileReader.Create); | |||
| Generator := TlsfGenerator.Create(ShaderFile, Trim(ParamStr(2))); | |||
| try | |||
| i := 3; | |||
| while (i < ParamCount) do begin | |||
| @@ -1,7 +1,7 @@ | |||
| program example; | |||
| uses | |||
| sysutils, variants, | |||
| sysutils, variants, Classes, | |||
| ulibShaderFile; | |||
| const | |||
| @@ -17,12 +17,31 @@ const | |||
| {$ERROR 'unknown operation system'} | |||
| {$IFEND} | |||
| type | |||
| TFileReader = class(TInterfacedObject, IlsfFileReader) | |||
| public | |||
| function LoadStream(const aFilename: String; const aStream: TStream): Boolean; | |||
| end; | |||
| var | |||
| i: Integer; | |||
| s: String; | |||
| ShaderFile: TlsfShaderFile; | |||
| Generator: TlsfGenerator; | |||
| function TFileReader.LoadStream(const aFilename: String; const aStream: TStream): Boolean; | |||
| var | |||
| fs: TFileStream; | |||
| begin | |||
| fs := TFileStream.Create(aFilename, fmOpenRead); | |||
| try | |||
| aStream.CopyFrom(fs, fs.Size - fs.Position); | |||
| result := true; | |||
| finally | |||
| FreeAndNil(fs); | |||
| end; | |||
| end; | |||
| begin | |||
| lsf_init(ExtractFilePath(ParamStr(0)) + LibName); | |||
| try | |||
| @@ -33,7 +52,7 @@ begin | |||
| end; | |||
| ShaderFile := TlsfShaderFile.Create; | |||
| try | |||
| ShaderFile.LoadFromFile(ParamStr(1)); | |||
| ShaderFile.LoadFromFunc(ParamStr(1), TFileReader.Create); | |||
| Generator := TlsfGenerator.Create(ShaderFile, ParamStr(2)); | |||
| try | |||
| i := 3; | |||
| @@ -2,6 +2,7 @@ | |||
| #define LIB_SHADER_FILE_H | |||
| #include <stdint.h> | |||
| #include <stdbool.h> | |||
| /**********************************************************************************************************************************/ | |||
| /* public interface */ | |||
| @@ -15,6 +16,7 @@ | |||
| #define LSF_ERR_NOT_INIT 0x00000001 | |||
| #define LSF_ERR_INVALID_HANDLE_SHADER_FILE 0x00000010 | |||
| #define LSF_ERR_INVALID_HANDLE_SHADER_GENERATOR 0x00000011 | |||
| #define LSF_ERR_INVALID_HANDLE_STREAM 0x00000012 | |||
| #define LSF_ERR_INVALID_GENERATOR_NAME 0x00000020 | |||
| #define LSF_ERR_INVALID_PROPERTY_INDEX 0x00000021 | |||
| #define LSF_ERR_INVALID_PROPERTY_NAME 0x00000022 | |||
| @@ -36,6 +38,10 @@ | |||
| #define LSF_ERR_INVALID_METHOD_NAME 0x00002002 | |||
| #define LSF_ERR_UNKNOWN 0xFFFFFFFF | |||
| #define LSF_SEEK_BEG 0 | |||
| #define LSF_SEEK_CUR 1 | |||
| #define LSF_SEEK_END 2 | |||
| #if __MINGW32__ | |||
| # define WINAPI __stdcall | |||
| #else | |||
| @@ -44,10 +50,30 @@ | |||
| typedef uint32_t lsf_error_code_t; | |||
| typedef uint32_t lsf_log_level_t; | |||
| typedef uint32_t lsf_seek_origin_t; | |||
| typedef void* lsf_shader_file_handle_t; | |||
| typedef void* lsf_shader_generator_handle_t; | |||
| typedef void* lsf_stream_handle_t; | |||
| /** function pointer to write log messages | |||
| * @param loglevel log level of current message (see LSF_LOGLEVEL_*) | |||
| * @param msg message to log | |||
| * @param userargs user defined arguments */ | |||
| typedef void (WINAPI *lsf_shader_file_log_callback_t)(const lsf_log_level_t loglevel, const char* msg, const void* userargs); | |||
| /** function pointer to save shader code | |||
| * @param filename filename to save shader code to | |||
| * @param handle handle to stream data (use lsf_stream_* methods to read/write data) | |||
| * @param userargs user defined arguments */ | |||
| typedef void (WINAPI *lsf_save_data_callback_t)(const char* filename, const lsf_stream_handle_t handle, const void* userargs); | |||
| /** function pointer to load shader code | |||
| * @param filename filename to load shader code from | |||
| * @param handle handle to stream data (use lsf_stream_* methods to read/write data) | |||
| * @param userargs user defined arguments */ | |||
| typedef bool (WINAPI *lsf_load_data_callback_t)(const char* filename, const lsf_stream_handle_t handle, const void* userargs); | |||
| typedef void (*lsf_shader_file_log_callback_t)(const lsf_log_level_t loglevel, const char* msg, const void* userargs); | |||
| /** create a new shader file handle | |||
| * @returns shader file handle or NULL (check lsf_get_last_error_* for more details) */ | |||
| @@ -66,12 +92,28 @@ lsf_error_code_t (WINAPI *lsf_shader_file_set_log_callback) (const lsf_shader_fi | |||
| * @returns error code (see LSF_ERR_*) */ | |||
| lsf_error_code_t (WINAPI *lsf_shader_file_load_from_file) (const lsf_shader_file_handle_t handle, const char* filename); | |||
| /** load shader code from function | |||
| * @param handle handle of shader file to load | |||
| * @param filename name of the file to load code from (will be passed to callback; can be used as key to identify data to load) | |||
| * @param callback function to call to request data | |||
| * @param userargs user defined arguments (will be passed to callback) | |||
| * @returns error code (see LSF_ERR_) */ | |||
| lsf_error_code_t (WINAPI *lsf_shader_file_load_from_func) (const lsf_shader_file_handle_t handle, const char* filename, const lsf_load_data_callback_t callback, const void* userargs); | |||
| /** save shader file code to a given file | |||
| * @param handle handle of shader file to save to file | |||
| * @param filename file to save shader code to | |||
| * @returns error code (see LSF_ERR_*) */ | |||
| lsf_error_code_t (WINAPI *lsf_shader_file_save_to_file) (const lsf_shader_file_handle_t handle, const char* filename); | |||
| /** save shader code to function | |||
| * @param handle handle of shader file to load | |||
| * @param filename name of the file to save code to (will be passed to callback; can be used as key to identify data to save) | |||
| * @param callback function to call to save data | |||
| * @param userargs user defined arguments (will be passed to callback) | |||
| * @returns error code (see LSF_ERR_) */ | |||
| lsf_error_code_t (WINAPI *lsf_shader_file_save_to_func) (const lsf_shader_file_handle_t handle, const char* filename, const lsf_load_data_callback_t callback, const void* userargs); | |||
| /** generate a list of all code generators in a shader file | |||
| * @param handle shader file handle to generate list for | |||
| * @returns list of code generators (seperated by linebreak) or NULL (check lsf_get_last_error_* for more details) */ | |||
| @@ -111,14 +153,14 @@ const char* (WINAPI *lsf_generator_get_property_by_name) (const lsf_shader_gener | |||
| * @param handle generator handle | |||
| * @param index index of the property (see lsf_generator_get_property_names to calculate property index) | |||
| * @param value new value of the property | |||
| * @return property value or NULL (check lsf_get_last_error_* for more details) */ | |||
| * @return error code (see LSF_ERR_*) */ | |||
| lsf_error_code_t (WINAPI *lsf_generator_set_property) (const lsf_shader_generator_handle_t handle, const int index, const char* value); | |||
| /** set a property value by its name | |||
| * @param handle generator handle | |||
| * @param name name of the property | |||
| * @param value new value of the property | |||
| * @return property value or NULL (check lsf_get_last_error_* for more details) */ | |||
| * @return error code (see LSF_ERR_*) */ | |||
| lsf_error_code_t (WINAPI *lsf_generator_set_property_by_name) (const lsf_shader_generator_handle_t handle, const char* name, const char* value); | |||
| /** generate shader code | |||
| @@ -132,6 +174,38 @@ const char* (WINAPI *lsf_generator_generate_code) (const lsf_shader_generator_ha | |||
| lsf_error_code_t (WINAPI *lsf_generator_destroy) (const lsf_shader_generator_handle_t handle); | |||
| /** get size of stream | |||
| * @param handle stream handle to get size from | |||
| * @returns stream size on success, -1 otherwise (check lsf_get_last_error_* for more details) */ | |||
| int (WINAPI *lsf_stream_get_size) (const lsf_stream_handle_t handle); | |||
| /** set size of stream | |||
| * @param handle stream handle to set size from | |||
| * @returns error code (see LSF_ERR_*) */ | |||
| lsf_error_code_t (WINAPI *lsf_stream_set_size) (const lsf_stream_handle_t handle, const int size); | |||
| /** seek stream | |||
| * @param handle stream handle to seek | |||
| * @param offset number of bytes to use as offset | |||
| * @param origin seek origin | |||
| * @returns new position on success, -1 otherwise (check lsf_get_last_error_* for more details) */ | |||
| int (WINAPI *lsf_stream_seek) (const lsf_stream_handle_t handle, const int offset, const lsf_seek_origin_t origin); | |||
| /** read data from stream | |||
| * @param handle stream handle to read data from | |||
| * @param buffer buffer to copy data into | |||
| * @param size number of bytes to read | |||
| * @returns number of read bytes on success, -1 otherwise (check lsf_get_last_error_* for more details) */ | |||
| int (WINAPI *lsf_stream_read) (const lsf_stream_handle_t handle, const void *buffer, const int size); | |||
| /** write data to stream | |||
| * @param handle stream handle to write data to | |||
| * @param buffer buffer to copy data from | |||
| * @param size number of bytes to write | |||
| * @returns number of written bytes on success, -1 otherwise (check lsf_get_last_error_* for more details) */ | |||
| int (WINAPI *lsf_stream_write) (const lsf_stream_handle_t handle, const void *buffer, const int size); | |||
| /** get last error code | |||
| * @return error code of last failed operation */ | |||
| lsf_error_code_t (WINAPI *lsf_get_last_error_code) (); | |||
| @@ -242,6 +316,12 @@ int lsf_init(const char* libname) | |||
| LoadProc(lsf_generator_generate_code, "lsf_Generator_generateCode"); | |||
| LoadProc(lsf_generator_destroy, "lsf_Generator_destroy"); | |||
| LoadProc(lsf_stream_get_size, "lsf_Stream_getSize"); | |||
| LoadProc(lsf_stream_set_size, "lsf_Stream_setSize"); | |||
| LoadProc(lsf_stream_seek, "lsf_Stream_seek"); | |||
| LoadProc(lsf_stream_read, "lsf_Stream_read"); | |||
| LoadProc(lsf_stream_write, "lsf_Stream_write"); | |||
| LoadProc(lsf_init_intern, "lsf_init"); | |||
| LoadProc(lsf_get_last_error_code, "lsf_getLastErrorCode"); | |||
| LoadProc(lsf_get_last_error_msg, "lsf_getLastErrorMsg"); | |||
| @@ -3,6 +3,7 @@ | |||
| #include <string> | |||
| #include <sstream> | |||
| #include <cstring> | |||
| #include <vector> | |||
| #include <stdint.h> | |||
| @@ -35,6 +36,7 @@ namespace lsf | |||
| enum ErrorCode | |||
| { | |||
| errUnknown = -1, | |||
| errNone = 0x00000000, | |||
| errNotInit = 0x00000001, | |||
| errInvalidHandleShaderFile = 0x00000010, | |||
| @@ -58,7 +60,32 @@ namespace lsf | |||
| errInvalidLibraryName = 0x00002000, | |||
| errInvalidLibraryHandle = 0x00002001, | |||
| errInvalidMethodName = 0x00002002, | |||
| errUnknown = 0xffffffff, | |||
| }; | |||
| 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 */ | |||
| @@ -135,10 +162,20 @@ namespace lsf | |||
| * @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); | |||
| @@ -186,7 +223,7 @@ namespace lsf | |||
| const ShaderFile& getShaderFile() const; | |||
| /** get a vector of all known properties | |||
| * @return vecotr with all known properties */ | |||
| * @return vector with all known properties */ | |||
| const StringVec& getPropertyNames() const; | |||
| /** get the value of a single property by its name | |||
| @@ -255,7 +292,6 @@ namespace lsf | |||
| /**********************************************************************************************************************************/ | |||
| /* private implementation */ | |||
| /**********************************************************************************************************************************/ | |||
| @@ -288,35 +324,244 @@ int libClose(lsf::Library::Handle handle) | |||
| /* Library::Impl ******************************************************************************************************************/ | |||
| struct lsf::Library::Impl | |||
| { | |||
| typedef ShaderFile::Handle (WINAPI *lsf_shader_file_create_t) (); | |||
| typedef void (WINAPI *lsf_shader_file_log_callback_t) (const LogLevel loglevel, const char* msg, void* userargs); | |||
| typedef ErrorCode (WINAPI *lsf_shader_file_set_log_callback_t) (const ShaderFile::Handle handle, const lsf_shader_file_log_callback_t callback, void* userargs); | |||
| typedef ErrorCode (WINAPI *lsf_shader_file_load_from_file_t) (const ShaderFile::Handle handle, const char* filename); | |||
| typedef ErrorCode (WINAPI *lsf_shader_file_save_to_file_t) (const ShaderFile::Handle handle, const char* filename); | |||
| typedef const char* (WINAPI *lsf_shader_file_get_generator_names_t) (const ShaderFile::Handle handle); | |||
| typedef ErrorCode (WINAPI *lsf_shader_file_destroy_t) (const ShaderFile::Handle handle); | |||
| typedef Generator::Handle (WINAPI *lsf_generator_create_t) (const ShaderFile::Handle handle, const char* name); | |||
| typedef const char* (WINAPI *lsf_generator_get_property_names_t) (const Generator::Handle handle); | |||
| typedef const char* (WINAPI *lsf_generator_get_property_t) (const Generator::Handle handle, const int index); | |||
| typedef const char* (WINAPI *lsf_generator_get_property_by_name_t) (const Generator::Handle handle, const char* name); | |||
| typedef ErrorCode (WINAPI *lsf_generator_set_property_t) (const Generator::Handle handle, const int index, const char* value); | |||
| typedef ErrorCode (WINAPI *lsf_generator_set_property_by_name_t) (const Generator::Handle handle, const char* name, const char* value); | |||
| typedef const char* (WINAPI *lsf_generator_generate_code_t) (const Generator::Handle handle); | |||
| typedef ErrorCode (WINAPI *lsf_generator_destroy_t) (const Generator::Handle handle); | |||
| typedef ErrorCode (WINAPI *lsf_init_t) (); | |||
| typedef ErrorCode (WINAPI *lsf_get_last_error_code_t) (); | |||
| typedef const char* (WINAPI *lsf_get_last_error_msg_t) (); | |||
| typedef const char* (WINAPI *lsf_get_last_error_trace_t) (); | |||
| typedef ErrorCode (WINAPI *lsf_finish_t) (); | |||
| 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<char> _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<std::streamsize>(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<char> _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; | |||
| @@ -329,6 +574,12 @@ struct lsf::Library::Impl | |||
| 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; | |||
| @@ -341,7 +592,9 @@ struct lsf::Library::Impl | |||
| 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), | |||
| @@ -354,12 +607,51 @@ struct lsf::Library::Impl | |||
| 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<const DataCallbackArgs*>(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<const DataCallbackArgs*>(userargs); | |||
| OutStreamBuf buf(*args->impl, handle); | |||
| std::ostream os(&buf); | |||
| return args->reader->loadStream(filename, os); | |||
| } | |||
| }; | |||
| /* Library ************************************************************************************************************************/ | |||
| @@ -390,7 +682,9 @@ lsf::Library::Library(std::string libName) : | |||
| 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"); | |||
| @@ -403,6 +697,12 @@ lsf::Library::Library(std::string libName) : | |||
| 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"); | |||
| @@ -443,14 +743,34 @@ void lsf::ShaderFile::loadFromFile(std::string filename) | |||
| { | |||
| ErrorCode err = _impl.lsf_shader_file_load_from_file(_handle, filename.c_str()); | |||
| if (err != errNone) | |||
| throw Exception("unable to load file", err); | |||
| 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("unable to load file", err); | |||
| 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) : | |||
| @@ -572,3 +892,4 @@ lsf::Exception::~Exception() throw() | |||
| @@ -26,6 +26,7 @@ type | |||
| errNotInit = $00000001, | |||
| errInvalidHandleShaderFile = $00000010, | |||
| errInvalidHandleShaderGenerator = $00000011, | |||
| errInvalidHandleStream = $00000012, | |||
| errInvalidGeneratorName = $00000020, | |||
| errInvalidPropertyIndex = $00000021, | |||
| errInvalidPropertyName = $00000022, | |||
| @@ -47,16 +48,28 @@ type | |||
| errInvalidMethodName = $00002002 | |||
| ); | |||
| {$Z4} | |||
| TlsfSeekOrigin = ( | |||
| soBeg = 0, | |||
| soCur = 1, | |||
| soEnd = 2 | |||
| ); | |||
| TlsfShaderFileHandle = Pointer; | |||
| TlsfGeneratorHandle = Pointer; | |||
| TlsfStreamHandle = Pointer; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| TlsfShaderFileLogEvent = procedure(const aLogLevel: TlsfLogLevel; const aMsg: PAnsiChar; const aUserArgs: Pointer); stdcall; | |||
| TlsfSaveDataCallback = procedure(const aFilename: PAnsiChar; const aHandle: TlsfStreamHandle; const aUserArgs: Pointer); stdcall; | |||
| TlsfLoadDataCallback = function(const aFilename: PAnsiChar; const aHandle: TlsfStreamHandle; const aUserArgs: Pointer): Boolean; stdcall; | |||
| Tlsf_ShaderFile_create = function: TlsfShaderFileHandle; stdcall; | |||
| Tlsf_ShaderFile_setLogCallback = function(const aHandle: TlsfShaderFileHandle; const aCallback: TlsfShaderFileLogEvent; const aUserArgs: Pointer): TlsfErrorCode; stdcall; | |||
| Tlsf_ShaderFile_loadFromFile = function(const aHandle: TlsfShaderFileHandle; const aFilename: PAnsiChar): TlsfErrorCode; stdcall; | |||
| Tlsf_ShaderFile_loadFromFunc = function(const aHandle: TlsfShaderFileHandle; const aFilename: PAnsiChar; const aCallback: TlsfLoadDataCallback; const aUserArgs: Pointer): TlsfErrorCode; stdcall; | |||
| Tlsf_ShaderFile_saveToFile = function(const aHandle: TlsfShaderFileHandle; const aFilename: PAnsiChar): TlsfErrorCode; stdcall; | |||
| Tlsf_ShaderFile_saveToFunc = function(const aHandle: TlsfShaderFileHandle; const aFilename: PAnsiChar; const aCallback: TlsfSaveDataCallback; const aUserArgs: Pointer): TlsfErrorCode; stdcall; | |||
| Tlsf_ShaderFile_getGeneratorNames = function(const aHandle: TlsfShaderFileHandle): PAnsiChar; stdcall; | |||
| Tlsf_ShaderFile_destroy = function(const aHandle: TlsfShaderFileHandle): TlsfErrorCode; stdcall; | |||
| @@ -69,12 +82,29 @@ type | |||
| Tlsf_Generator_generateCode = function(const aHandle: TlsfGeneratorHandle): PAnsiChar; stdcall; | |||
| Tlsf_Generator_destroy = function(const aHandle: TlsfGeneratorHandle): TlsfErrorCode; stdcall; | |||
| Tlsf_Stream_getSize = function(const aHandle: TlsfStreamHandle): Integer; stdcall; | |||
| Tlsf_Stream_setSize = function(const aHandle: TlsfStreamHandle; const aSize: Integer): TlsfErrorCode; stdcall; | |||
| Tlsf_Stream_seek = function(const aHandle: TlsfStreamHandle; const aOffset: Integer; const aOrigin: TlsfSeekOrigin): Integer; stdcall; | |||
| Tlsf_Stream_read = function(const aHandle: TlsfStreamHandle; const aBuffer: Pointer; const aSize: Integer): Integer; stdcall; | |||
| Tlsf_Stream_write = function(const aHandle: TlsfStreamHandle; const aBuffer: Pointer; const aSize: Integer): Integer; stdcall; | |||
| Tlsf_init = function: TlsfErrorCode; stdcall; | |||
| Tlsf_getLastErrorCode = function: TlsfErrorCode; stdcall; | |||
| Tlsf_getLastErrorMsg = function: PAnsiChar; stdcall; | |||
| Tlsf_getLastErrorTrace = function: PAnsiChar; stdcall; | |||
| Tlsf_finish = function: TlsfErrorCode; stdcall; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| IlsfFileReader = interface | |||
| ['{1820220E-0043-491A-B841-19A4B11C6090}'] | |||
| function LoadStream(const aFilename: String; const aStream: TStream): Boolean; | |||
| end; | |||
| IlsfFileWriter = interface | |||
| ['{FEF0760E-402B-4627-9171-273AE215FADB}'] | |||
| procedure SaveStream(const aFilename: String; const aStream: TStream); | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| TlsfShaderFile = class(TObject) | |||
| private | |||
| @@ -85,7 +115,9 @@ type | |||
| property Handle: TlsfShaderFileHandle read fHandle; | |||
| procedure LoadFromFile(const aFilename: String); | |||
| procedure LoadFromFunc(const aFilename: String; const aFileReader: IlsfFileReader); | |||
| procedure SaveToFile(const aFilename: String); | |||
| procedure SaveToFunc(const aFilename: String; const aFileWriter: IlsfFileWriter); | |||
| constructor Create; | |||
| destructor Destroy; override; | |||
| @@ -130,7 +162,9 @@ var | |||
| lsf_ShaderFile_create: Tlsf_ShaderFile_create; | |||
| lsf_ShaderFile_setLogCallback: Tlsf_ShaderFile_setLogCallback; | |||
| lsf_ShaderFile_loadFromFile: Tlsf_ShaderFile_loadFromFile; | |||
| lsf_ShaderFile_loadFromFunc: Tlsf_ShaderFile_loadFromFunc; | |||
| lsf_ShaderFile_saveToFile: Tlsf_ShaderFile_saveToFile; | |||
| lsf_ShaderFile_saveToFunc: Tlsf_ShaderFile_saveToFunc; | |||
| lsf_ShaderFile_getGeneratorNames: Tlsf_ShaderFile_getGeneratorNames; | |||
| lsf_ShaderFile_destroy: Tlsf_ShaderFile_destroy; | |||
| @@ -143,6 +177,12 @@ var | |||
| lsf_Generator_generateCode: Tlsf_Generator_generateCode; | |||
| lsf_Generator_destroy: Tlsf_Generator_destroy; | |||
| lsf_Stream_getSize: Tlsf_Stream_getSize; | |||
| lsf_Stream_setSize: Tlsf_Stream_setSize; | |||
| lsf_Stream_seek: Tlsf_Stream_seek; | |||
| lsf_Stream_read: Tlsf_Stream_read; | |||
| lsf_Stream_write: Tlsf_Stream_write; | |||
| lsf_getLastErrorCode: Tlsf_getLastErrorCode; | |||
| lsf_getLastErrorMsg: Tlsf_getLastErrorMsg; | |||
| lsf_getLastErrorTrace: Tlsf_getLastErrorTrace; | |||
| @@ -218,6 +258,21 @@ var | |||
| lsf_init_intern: Tlsf_init; | |||
| lsf_finish_intern: Tlsf_finish; | |||
| type | |||
| TlsfStream = class(TStream) | |||
| private | |||
| fHandle: TlsfStreamHandle; | |||
| protected | |||
| function GetSize: Int64; override; | |||
| procedure SetSize(NewSize: Longint); override; {$IFDEF FPC}overload;{$ENDIF} | |||
| public | |||
| function Seek(Offset: Longint; Origin: Word): Longint; override; {$IFDEF FPC}overload;{$ENDIF} | |||
| function Read(var Buffer; Count: Longint): Longint; override; | |||
| function Write(const Buffer; Count: Longint): Longint; override; | |||
| constructor Create(const aHandle: TlsfStreamHandle); | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| procedure lsf_init(const aLibName: String); | |||
| @@ -239,7 +294,9 @@ begin | |||
| lsf_ShaderFile_create := Tlsf_ShaderFile_create( LoadProc('lsf_ShaderFile_create')); | |||
| lsf_ShaderFile_setLogCallback := Tlsf_ShaderFile_setLogCallback( LoadProc('lsf_ShaderFile_setLogCallback')); | |||
| lsf_ShaderFile_loadFromFile := Tlsf_ShaderFile_loadFromFile( LoadProc('lsf_ShaderFile_loadFromFile')); | |||
| lsf_ShaderFile_loadFromFunc := Tlsf_ShaderFile_loadFromFunc( LoadProc('lsf_ShaderFile_loadFromFunc')); | |||
| lsf_ShaderFile_saveToFile := Tlsf_ShaderFile_saveToFile( LoadProc('lsf_ShaderFile_saveToFile')); | |||
| lsf_ShaderFile_saveToFunc := Tlsf_ShaderFile_saveToFunc( LoadProc('lsf_ShaderFile_saveToFunc')); | |||
| lsf_ShaderFile_getGeneratorNames := Tlsf_ShaderFile_getGeneratorNames( LoadProc('lsf_ShaderFile_getGeneratorNames')); | |||
| lsf_ShaderFile_destroy := Tlsf_ShaderFile_destroy( LoadProc('lsf_ShaderFile_destroy')); | |||
| @@ -252,6 +309,12 @@ begin | |||
| lsf_Generator_generateCode := Tlsf_Generator_generateCode( LoadProc('lsf_Generator_generateCode')); | |||
| lsf_Generator_destroy := Tlsf_Generator_destroy( LoadProc('lsf_Generator_destroy')); | |||
| lsf_Stream_getSize := Tlsf_Stream_getSize( LoadProc('lsf_Stream_getSize')); | |||
| lsf_Stream_setSize := Tlsf_Stream_setSize( LoadProc('lsf_Stream_setSize')); | |||
| lsf_Stream_seek := Tlsf_Stream_seek( LoadProc('lsf_Stream_seek')); | |||
| lsf_Stream_read := Tlsf_Stream_read( LoadProc('lsf_Stream_read')); | |||
| lsf_Stream_write := Tlsf_Stream_write( LoadProc('lsf_Stream_write')); | |||
| lsf_init_intern := Tlsf_init( LoadProc('lsf_init')); | |||
| lsf_getLastErrorCode := Tlsf_getLastErrorCode( LoadProc('lsf_getLastErrorCode')); | |||
| lsf_getLastErrorMsg := Tlsf_getLastErrorMsg( LoadProc('lsf_getLastErrorMsg')); | |||
| @@ -267,27 +330,128 @@ end; | |||
| procedure lsf_finish; | |||
| begin | |||
| lsf_finish_intern(); | |||
| lsf_ShaderFile_create := nil; | |||
| lsf_ShaderFile_setLogCallback := nil; | |||
| lsf_ShaderFile_loadFromFile := nil; | |||
| lsf_ShaderFile_saveToFile := nil; | |||
| lsf_ShaderFile_getGeneratorNames := nil; | |||
| lsf_ShaderFile_destroy := nil; | |||
| lsf_getLastErrorCode := nil; | |||
| lsf_getLastErrorMsg := nil; | |||
| lsf_getLastErrorTrace := nil; | |||
| lsf_ShaderFile_create := nil; | |||
| lsf_ShaderFile_setLogCallback := nil; | |||
| lsf_ShaderFile_loadFromFile := nil; | |||
| lsf_ShaderFile_loadFromFunc := nil; | |||
| lsf_ShaderFile_saveToFile := nil; | |||
| lsf_ShaderFile_saveToFunc := nil; | |||
| lsf_ShaderFile_getGeneratorNames := nil; | |||
| lsf_ShaderFile_destroy := nil; | |||
| lsf_Generator_create := nil; | |||
| lsf_Generator_getPropertyNames := nil; | |||
| lsf_Generator_getProperty := nil; | |||
| lsf_Generator_getPropertyByName := nil; | |||
| lsf_Generator_setProperty := nil; | |||
| lsf_Generator_setPropertyByName := nil; | |||
| lsf_Generator_generateCode := nil; | |||
| lsf_Generator_destroy := nil; | |||
| lsf_Stream_getSize := nil; | |||
| lsf_Stream_setSize := nil; | |||
| lsf_Stream_seek := nil; | |||
| lsf_Stream_read := nil; | |||
| lsf_Stream_write := nil; | |||
| lsf_init_intern := nil; | |||
| lsf_getLastErrorCode := nil; | |||
| lsf_getLastErrorMsg := nil; | |||
| lsf_getLastErrorTrace := nil; | |||
| lsf_finish_intern := nil; | |||
| if (libHandle <> InvalidLibHandle) then begin | |||
| LibClose(libHandle); | |||
| libHandle := InvalidLibHandle; | |||
| end; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| //Callbacks From Library//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| procedure LogCallback(const aLogLevel: TlsfLogLevel; const aMsg: PAnsiChar; const aUserArgs: Pointer); stdcall; | |||
| begin | |||
| TlsfShaderFile(aUserArgs).LogMsg(aLogLevel, String(aMsg)); | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| procedure SaveDataCallback(const aFilename: PAnsiChar; const aHandle: TlsfStreamHandle; const aUserArgs: Pointer); stdcall; | |||
| var | |||
| s: TlsfStream; | |||
| begin | |||
| s := TlsfStream.Create(aHandle); | |||
| try | |||
| IlsfFileWriter(aUserArgs).SaveStream(aFilename, s); | |||
| finally | |||
| FreeAndNil(s); | |||
| end; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function LoadDataCallback(const aFilename: PAnsiChar; const aHandle: TlsfStreamHandle; const aUserArgs: Pointer): Boolean; stdcall; | |||
| var | |||
| s: TlsfStream; | |||
| begin | |||
| s := TlsfStream.Create(aHandle); | |||
| try | |||
| result := IlsfFileReader(aUserArgs).LoadStream(aFilename, s); | |||
| finally | |||
| FreeAndNil(s); | |||
| end; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| //TlsfStream//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function TlsfStream.GetSize: Int64; | |||
| begin | |||
| result := lsf_Stream_getSize(fHandle); | |||
| if (result < 0) then | |||
| raise TlsfException.Create('error in TlsfStream.GetSize: ' + lsf_getLastErrorMsg(), lsf_getLastErrorCode()); | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| procedure TlsfStream.SetSize(NewSize: Longint); | |||
| var | |||
| err: TlsfErrorCode; | |||
| begin | |||
| err := lsf_Stream_setSize(fHandle, NewSize); | |||
| if (err <> errNone) then | |||
| raise TlsfException.Create('error in TlsfStream.SetSize: ' + lsf_getLastErrorMsg(), lsf_getLastErrorCode()); | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function TlsfStream.Seek(Offset: Longint; Origin: Word): Longint; | |||
| begin | |||
| result := lsf_Stream_seek(fHandle, Offset, TlsfSeekOrigin(Origin)); | |||
| if (result < 0) then | |||
| raise TlsfException.Create('error in TlsfStream.Seek: ' + lsf_getLastErrorMsg(), lsf_getLastErrorCode()); | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function TlsfStream.Read(var Buffer; Count: Longint): Longint; | |||
| begin | |||
| result := lsf_Stream_read(fHandle, @Buffer, Count); | |||
| if (result < 0) then | |||
| raise TlsfException.Create('error in TlsfStream.Read: ' + lsf_getLastErrorMsg(), lsf_getLastErrorCode()); | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function TlsfStream.Write(const Buffer; Count: Longint): Longint; | |||
| begin | |||
| result := lsf_Stream_write(fHandle, @Buffer, Count); | |||
| if (result < 0) then | |||
| raise TlsfException.Create('error in TlsfStream.Write: ' + lsf_getLastErrorMsg(), lsf_getLastErrorCode()); | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| constructor TlsfStream.Create(const aHandle: TlsfStreamHandle); | |||
| begin | |||
| inherited Create; | |||
| fHandle := aHandle; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| //TlsfShaderFile//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| @@ -306,6 +470,18 @@ begin | |||
| raise TlsfException.Create('error while loading from file: ' + lsf_getLastErrorMsg(), lsf_getLastErrorCode()); | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| procedure TlsfShaderFile.LoadFromFunc(const aFilename: String; const aFileReader: IlsfFileReader); | |||
| var | |||
| err: TlsfErrorCode; | |||
| begin | |||
| if not Assigned(aFileReader) then | |||
| LoadFromFile(aFilename); | |||
| err := lsf_ShaderFile_loadFromFunc(fHandle, PAnsiChar(AnsiString(aFilename)), @LoadDataCallback, Pointer(aFileReader)); | |||
| if (err <> errNone) then | |||
| raise TlsfException.Create('error while loading from function: ' + lsf_getLastErrorMsg(), lsf_getLastErrorCode()); | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| procedure TlsfShaderFile.SaveToFile(const aFilename: String); | |||
| var | |||
| @@ -316,6 +492,18 @@ begin | |||
| raise TlsfException.Create('error while saving to file: ' + lsf_getLastErrorMsg(), lsf_getLastErrorCode()); | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| procedure TlsfShaderFile.SaveToFunc(const aFilename: String; const aFileWriter: IlsfFileWriter); | |||
| var | |||
| err: TlsfErrorCode; | |||
| begin | |||
| if not Assigned(aFileWriter) then | |||
| SaveToFile(aFilename); | |||
| err := lsf_ShaderFile_saveToFunc(fHandle, PAnsiChar(AnsiString(aFilename)), @SaveDataCallback, Pointer(aFileWriter)); | |||
| if (err <> errNone) then | |||
| raise TlsfException.Create('error while saving to function: ' + lsf_getLastErrorMsg(), lsf_getLastErrorCode()); | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| constructor TlsfShaderFile.Create; | |||
| var | |||
| @@ -3,7 +3,7 @@ library libShaderFile; | |||
| {$mode objfpc}{$H+} | |||
| uses | |||
| SysUtils, variants, | |||
| SysUtils, variants, Classes, | |||
| uengShaderFile, uengShaderGenerator, uengShaderPart, | |||
| uengShaderFileGenerics, uengShaderFileTypes; | |||
| @@ -20,6 +20,7 @@ const | |||
| LSF_ERR_NOT_INIT = $00000001; | |||
| LSF_ERR_INVALID_HANDLE_SHADER_FILE = $00000010; | |||
| LSF_ERR_INVALID_HANDLE_SHADER_GENERATOR = $00000011; | |||
| LSF_ERR_INVALID_HANDLE_STREAM = $00000012; | |||
| LSF_ERR_INVALID_GENERATOR_NAME = $00000020; | |||
| LSF_ERR_INVALID_PROPERTY_INDEX = $00000021; | |||
| LSF_ERR_INVALID_PROPERTY_NAME = $00000022; | |||
| @@ -38,13 +39,23 @@ const | |||
| LSF_ERR_SHADER_PART = $0000100B; | |||
| LSF_ERR_UNKNOWN = $FFFFFFFF; | |||
| {%H-}LSF_SEEK_BEG = soBeginning; | |||
| {%H-}LSF_SEEK_CUR = soCurrent; | |||
| {%H-}LSF_SEEK_END = soEnd; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| type | |||
| TlsfErrorCode = Cardinal; | |||
| TlsfLogLevel = Cardinal; | |||
| TlsfSeekOrigin = Cardinal; | |||
| TlsfShaderFileHandle = Pointer; | |||
| TlsfShaderGeneratorHandle = Pointer; | |||
| TlsfStreamHandle = Pointer; | |||
| TlsfShaderFileLogEvent = procedure(const aLogLevel: TlsfLogLevel; const aMsg: PAnsiChar; const aUserArgs: Pointer); stdcall; | |||
| TlsfSaveDataCallback = procedure(const aFilename: PAnsiChar; const aHandle: TlsfStreamHandle; const aUserArgs: Pointer); stdcall; | |||
| TlsfLoadDataCallback = function(const aFilename: PAnsiChar; const aHandle: TlsfStreamHandle; const aUserArgs: Pointer): Boolean; stdcall; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| //internal types and contstants///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| @@ -56,7 +67,9 @@ type | |||
| TPropertyMap = specialize TutlMap<string, variant>; | |||
| TShaderGeneratorHandleHashSet = specialize TutlHashSet<TlsfShaderGeneratorHandle>; | |||
| TShaderGeneratorHashSet = specialize TutlHashSet<TShaderGenerator>; | |||
| TStreamHashSet = specialize TutlHashSet<TStream>; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| TShaderGenerator = class(TObject) | |||
| private | |||
| fOwner: TShaderFile; | |||
| @@ -80,6 +93,7 @@ type | |||
| destructor Destroy; override; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| TShaderFile = class(TengShaderFile) | |||
| private | |||
| fLogUserArgs: Pointer; | |||
| @@ -93,7 +107,7 @@ type | |||
| property LogUserArgs: Pointer read fLogUserArgs write fLogUserArgs; | |||
| property GeneratorNames: String read fGeneratorNames; | |||
| procedure LoadFromFile(const aFilename: String); reintroduce; | |||
| procedure LoadFromFile(const aFilename: String; const aFileReader: IengShaderFileReader = nil); reintroduce; | |||
| function CreateGenerator(const aName: String): TShaderGenerator; | |||
| function DestroyGenerator(const aGenerator: TShaderGenerator): TlsfErrorCode; | |||
| @@ -103,10 +117,31 @@ type | |||
| end; | |||
| TShaderFileHashSet = specialize TutlHashSet<TShaderFile>; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| TFileWriterProxy = class(TInterfacedObject, IengShaderFileWriter) | |||
| private | |||
| fUserArgs: Pointer; | |||
| fCallback: TlsfSaveDataCallback; | |||
| public | |||
| procedure SaveStream(const aFilename: String; const aStream: TStream); | |||
| constructor Create(const aCallback: TlsfSaveDataCallback; const aUserArgs: Pointer); | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| TFileReaderProxy = class(TInterfacedObject, IengShaderFileReader) | |||
| private | |||
| fUserArgs: Pointer; | |||
| fCallback: TlsfLoadDataCallback; | |||
| public | |||
| function LoadStream(const aFilename: String; const aStream: TStream): Boolean; | |||
| constructor Create(const aCallback: TlsfLoadDataCallback; const aUserArgs: Pointer); | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| var | |||
| ShaderFiles: TShaderFileHashSet = nil; | |||
| ShaderGenerators: TShaderGeneratorHandleHashSet = nil; | |||
| Streams: TStreamHashSet = nil; | |||
| LastErrorCode: TlsfErrorCode = LSF_ERR_NONE; | |||
| LastErrorMsg: String = ''; | |||
| LastErrorTrace: String = ''; | |||
| @@ -159,51 +194,41 @@ end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function CheckIfInitialized: Boolean; | |||
| begin | |||
| try | |||
| result := Assigned(ShaderFiles); | |||
| if not result then | |||
| SetLastError(LSf_ERR_NOT_INIT, 'libShaderFile has not been initialized. call lsf_init before using any other methods.'); | |||
| except | |||
| on e: Exception do begin | |||
| SetLastError(e); | |||
| result := false; | |||
| end; | |||
| end; | |||
| result := Assigned(ShaderFiles); | |||
| if not result then | |||
| SetLastError(LSf_ERR_NOT_INIT, 'libShaderFile has not been initialized. call lsf_init before using any other methods.'); | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function CheckShaderFileHandle(const aHandle: TlsfShaderFileHandle): Boolean; | |||
| begin | |||
| try | |||
| result := CheckIfInitialized; | |||
| if result then begin | |||
| result := ShaderFiles.Contains(TShaderFile(aHandle)); | |||
| if not result then | |||
| SetLastError(LSF_ERR_INVALID_HANDLE_SHADER_FILE, Format('0x%x is not a valid shader file handle', [{%H-}PtrUInt(aHandle)])); | |||
| end; | |||
| except | |||
| on e: Exception do begin | |||
| SetLastError(e); | |||
| result := false; | |||
| end; | |||
| result := CheckIfInitialized; | |||
| if result then begin | |||
| result := ShaderFiles.Contains(TShaderFile(aHandle)); | |||
| if not result then | |||
| SetLastError(LSF_ERR_INVALID_HANDLE_SHADER_FILE, Format('0x%x is not a valid shader file handle', [{%H-}PtrUInt(aHandle)])); | |||
| end; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function CheckShaderGeneratorHandle(const aHandle: TlsfShaderGeneratorHandle): Boolean; | |||
| begin | |||
| try | |||
| result := CheckIfInitialized; | |||
| if result then begin | |||
| result := ShaderGenerators.Contains(TShaderGenerator(aHandle)); | |||
| if not result then | |||
| SetLastError(LSF_ERR_INVALID_HANDLE_SHADER_GENERATOR, Format('0x%x is not a valid shader generator handle', [{%H-}PtrUInt(aHandle)])); | |||
| end; | |||
| except | |||
| on e: Exception do begin | |||
| SetLastError(e); | |||
| result := false; | |||
| end; | |||
| result := CheckIfInitialized; | |||
| if result then begin | |||
| result := ShaderGenerators.Contains(TShaderGenerator(aHandle)); | |||
| if not result then | |||
| SetLastError(LSF_ERR_INVALID_HANDLE_SHADER_GENERATOR, Format('0x%x is not a valid shader generator handle', [{%H-}PtrUInt(aHandle)])); | |||
| end; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function CheckStreamHandle(const aHandle: TlsfStreamHandle): Boolean; | |||
| begin | |||
| result := CheckIfInitialized; | |||
| if result then begin | |||
| result := Streams.Contains(TStream(aHandle)); | |||
| if not result then | |||
| SetLastError(LSF_ERR_INVALID_HANDLE_STREAM, Format('0x%x is not a valid stream handle', [{%H-}PtrUInt(aHandle)])); | |||
| end; | |||
| end; | |||
| @@ -263,6 +288,23 @@ begin | |||
| end; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function lsf_ShaderFile_loadFromFunc(const aHandle: TlsfShaderFileHandle; const aFilename: PAnsiChar; | |||
| const aCallback: TlsfLoadDataCallback; const aUserArgs: Pointer): TlsfErrorCode; stdcall; | |||
| begin | |||
| try | |||
| result := LSF_ERR_NONE; | |||
| if not CheckShaderFileHandle(aHandle) | |||
| then result := LastErrorCode | |||
| else TShaderFile(aHandle).LoadFromFile(aFilename, TFileReaderProxy.Create(aCallback, aUserArgs)); | |||
| except | |||
| on e: Exception do begin | |||
| SetLastError(e); | |||
| result := LastErrorCode; | |||
| end; | |||
| end; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function lsf_ShaderFile_saveToFile(const aHandle: TlsfShaderFileHandle; const aFilename: PAnsiChar): TlsfErrorCode; stdcall; | |||
| begin | |||
| @@ -279,6 +321,23 @@ begin | |||
| end; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function lsf_ShaderFile_saveToFunc(const aHandle: TlsfShaderFileHandle; const aFilename: PAnsiChar; | |||
| const aCallback: TlsfSaveDataCallback; const aUserArgs: Pointer): TlsfErrorCode; stdcall; | |||
| begin | |||
| try | |||
| result := LSF_ERR_NONE; | |||
| if not CheckShaderFileHandle(aHandle) | |||
| then result := LastErrorCode | |||
| else TShaderFile(aHandle).SaveToFile(aFilename, TFileWriterProxy.Create(aCallback, aUserArgs)); | |||
| except | |||
| on e: Exception do begin | |||
| SetLastError(e); | |||
| result := LastErrorCode; | |||
| end; | |||
| end; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function lsf_ShaderFile_getGeneratorNames(const aHandle: TlsfShaderFileHandle): PAnsiChar; stdcall; | |||
| begin | |||
| @@ -439,6 +498,83 @@ begin | |||
| end; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| //Stream//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function lsf_Stream_getSize(const aHandle: TlsfStreamHandle): Integer; stdcall; | |||
| begin | |||
| try | |||
| if CheckStreamHandle(aHandle) | |||
| then result := TStream(aHandle).Size | |||
| else result := -1; | |||
| except | |||
| on e: Exception do begin | |||
| SetLastError(e); | |||
| result := LastErrorCode; | |||
| end; | |||
| end; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function lsf_Stream_setSize(const aHandle: TlsfStreamHandle; const aSize: Integer): TlsfErrorCode; stdcall; | |||
| begin | |||
| try | |||
| if CheckStreamHandle(aHandle) | |||
| then TStream(aHandle).Size := aSize | |||
| else result := LastErrorCode; | |||
| except | |||
| on e: Exception do begin | |||
| SetLastError(e); | |||
| result := LastErrorCode; | |||
| end; | |||
| end; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function lsf_Stream_seek(const aHandle: TlsfStreamHandle; const aOffset: Integer; const aOrigin: TlsfSeekOrigin): Integer; stdcall; | |||
| begin | |||
| try | |||
| if CheckStreamHandle(aHandle) | |||
| then result := TStream(aHandle).Seek(aOrigin, aOrigin) | |||
| else result := -1; | |||
| except | |||
| on e: Exception do begin | |||
| SetLastError(e); | |||
| result := LastErrorCode; | |||
| end; | |||
| end; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function lsf_Stream_read(const aHandle: TlsfStreamHandle; const aBuffer: Pointer; const aSize: Integer): Integer; stdcall; | |||
| begin | |||
| try | |||
| if CheckStreamHandle(aHandle) | |||
| then result := TStream(aHandle).Read(aBuffer^, aSize) | |||
| else result := -1; | |||
| except | |||
| on e: Exception do begin | |||
| SetLastError(e); | |||
| result := LastErrorCode; | |||
| end; | |||
| end; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function lsf_Stream_write(const aHandle: TlsfStreamHandle; const aBuffer: Pointer; const aSize: Integer): Integer; stdcall; | |||
| begin | |||
| try | |||
| if CheckStreamHandle(aHandle) | |||
| then result := TStream(aHandle).Write(aBuffer^, aSize) | |||
| else result := -1; | |||
| except | |||
| on e: Exception do begin | |||
| SetLastError(e); | |||
| result := LastErrorCode; | |||
| end; | |||
| end; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| //Global//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| @@ -448,6 +584,7 @@ begin | |||
| result := LSF_ERR_NONE; | |||
| ShaderFiles := TShaderFileHashSet.Create(true); | |||
| ShaderGenerators := TShaderGeneratorHandleHashSet.Create(true); | |||
| Streams := TStreamHashSet.Create(false); | |||
| except | |||
| on e: Exception do begin | |||
| SetLastError(e); | |||
| @@ -479,6 +616,7 @@ function lsf_finish: TlsfErrorCode; stdcall; | |||
| begin | |||
| try | |||
| result := LSF_ERR_NONE; | |||
| FreeAndNil(Streams); | |||
| FreeAndNil(ShaderGenerators); | |||
| FreeAndNil(ShaderFiles); | |||
| except | |||
| @@ -493,7 +631,9 @@ exports | |||
| lsf_ShaderFile_create, | |||
| lsf_ShaderFile_setLogCallback, | |||
| lsf_ShaderFile_loadFromFile, | |||
| lsf_ShaderFile_loadFromFunc, | |||
| lsf_ShaderFile_saveToFile, | |||
| lsf_ShaderFile_saveToFunc, | |||
| lsf_ShaderFile_getGeneratorNames, | |||
| lsf_ShaderFile_destroy, | |||
| @@ -506,6 +646,12 @@ exports | |||
| lsf_Generator_generateCode, | |||
| lsf_Generator_destroy, | |||
| lsf_Stream_getSize, | |||
| lsf_Stream_setSize, | |||
| lsf_Stream_seek, | |||
| lsf_Stream_read, | |||
| lsf_Stream_write, | |||
| lsf_init, | |||
| lsf_getLastErrorCode, | |||
| lsf_getLastErrorMsg, | |||
| @@ -617,11 +763,11 @@ begin | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| procedure TShaderFile.LoadFromFile(const aFilename: String); | |||
| procedure TShaderFile.LoadFromFile(const aFilename: String; const aFileReader: IengShaderFileReader); | |||
| var | |||
| i: Integer; | |||
| begin | |||
| inherited LoadFromFile(aFilename, nil); | |||
| inherited LoadFromFile(aFilename, aFileReader); | |||
| fGeneratorNames := ''; | |||
| for i := 0 to GeneratorCount-1 do | |||
| fGeneratorNames := fGeneratorNames + inherited GeneratorNames[i] + sLineBreak; | |||
| @@ -678,4 +824,47 @@ begin | |||
| inherited Destroy; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| //TFileWriterProxy////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| procedure TFileWriterProxy.SaveStream(const aFilename: String; const aStream: TStream); | |||
| begin | |||
| Streams.Add(aStream); | |||
| try | |||
| fCallback(PAnsiChar(aFilename), TlsfStreamHandle(aStream), fUserArgs); | |||
| finally | |||
| Streams.Remove(aStream); | |||
| end; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| constructor TFileWriterProxy.Create(const aCallback: TlsfSaveDataCallback; const aUserArgs: Pointer); | |||
| begin | |||
| inherited Create; | |||
| fCallback := aCallback; | |||
| fUserArgs := aUserArgs; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| //TFileReaderProxy////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| function TFileReaderProxy.LoadStream(const aFilename: String; const aStream: TStream): Boolean; | |||
| begin | |||
| Streams.Add(aStream); | |||
| try | |||
| result := fCallback(PAnsiChar(aFilename), TlsfStreamHandle(aStream), fUserArgs); | |||
| finally | |||
| Streams.Remove(aStream); | |||
| end; | |||
| end; | |||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
| constructor TFileReaderProxy.Create(const aCallback: TlsfLoadDataCallback; const aUserArgs: Pointer); | |||
| begin | |||
| inherited Create; | |||
| fCallback := aCallback; | |||
| fUserArgs := aUserArgs; | |||
| end; | |||
| end. | |||