From e10c601c035f38f602e7d05763e4638514bfc3e7 Mon Sep 17 00:00:00 2001 From: Bergmann89 Date: Thu, 17 Sep 2015 20:45:37 +0200 Subject: [PATCH] * implemented c++ header file * changed directory structure for header files * implemented some small examples for c and c++ --- library/header/c/libShaderFile.c | 91 --- library/header/c/libShaderFile.h | 88 --- .../{c/example/test.c => examples/example.c} | 21 +- library/header/examples/example.cpp | 42 ++ library/header/libShaderFile.h | 247 ++++++++ library/header/libShaderFile.hpp | 563 ++++++++++++++++++ .../header/{delphi => }/ulibShaderFile.pas | 0 library/libShaderFile.lpr | 23 +- 8 files changed, 883 insertions(+), 192 deletions(-) delete mode 100644 library/header/c/libShaderFile.c delete mode 100644 library/header/c/libShaderFile.h rename library/header/{c/example/test.c => examples/example.c} (79%) create mode 100644 library/header/examples/example.cpp create mode 100644 library/header/libShaderFile.h create mode 100644 library/header/libShaderFile.hpp rename library/header/{delphi => }/ulibShaderFile.pas (100%) diff --git a/library/header/c/libShaderFile.c b/library/header/c/libShaderFile.c deleted file mode 100644 index f5c9130..0000000 --- a/library/header/c/libShaderFile.c +++ /dev/null @@ -1,91 +0,0 @@ -#include "libShaderFile.h" - -//#define LSF_DEBUG -#ifdef LSF_DEBUG -# include -#endif - -#if defined(WIN32) || defined(WIN64) -# include - -typedef HMODULE lib_handle_t; - -lib_handle_t open_lib(const char* name) - { return LoadLibrary(name); }; - -void* get_addr(lib_handle_t handle, const char* name) - { return GetProcAddress(handle, name); }; - -int close_lib(lib_handle_t handle) - { return FreeLibrary(handle); }; - -#elif defined(LINUX) -# include -# error "linux is not supported yet" -#else -# error "unknown operation system" -#endif - -lib_handle_t handle = NULL; -lsf_init_t lsf_init_intern = NULL; -lsf_finish_t lsf_finish_intern = NULL; - -#ifndef LSF_DEBUG -# define LoadProc(proc, name) \ - proc = get_addr(handle, name); \ - if (!proc) \ - return LSF_ERR_INVALID_METHOD_NAME -#else -# define LoadProc(proc, name) \ - proc = get_addr(handle, name); \ - printf("load method '%s' (addr=0x%016x)\n", name, proc); \ - if (!proc) \ - return LSF_ERR_INVALID_METHOD_NAME -#endif - -int lsf_init(const char* libname) -{ -#ifdef LSF_DEBUG - printf("loading library '%s'\n", libname); -#endif - - handle = open_lib(libname); - if (!handle) - return LSF_ERR_INVALID_LIBRARY_NAME; - -#ifdef LSF_DEBUG - printf(" done (handle=0x%016x)\n", handle); -#endif - - LoadProc(lsf_shader_file_create, "lsf_ShaderFile_create"); - LoadProc(lsf_shader_file_set_log_callback, "lsf_ShaderFile_setLogCallback"); - LoadProc(lsf_shader_file_load_from_file, "lsf_ShaderFile_loadFromFile"); - LoadProc(lsf_shader_file_save_to_file, "lsf_ShaderFile_saveToFile"); - LoadProc(lsf_shader_file_get_generator_names, "lsf_ShaderFile_getGeneratorNames"); - LoadProc(lsf_shader_file_destroy, "lsf_ShaderFile_destroy"); - - LoadProc(lsf_generator_create, "lsf_Generator_create"); - LoadProc(lsf_generator_get_property_names, "lsf_Generator_getPropertyNames"); - LoadProc(lsf_generator_get_property, "lsf_Generator_getProperty"); - LoadProc(lsf_generator_get_property_by_name, "lsf_Generator_getPropertyByName"); - LoadProc(lsf_generator_set_property, "lsf_Generator_setProperty"); - LoadProc(lsf_generator_set_property_by_name, "lsf_Generator_setPropertyByName"); - LoadProc(lsf_generator_generate_code, "lsf_Generator_generateCode"); - LoadProc(lsf_generator_destroy, "lsf_Generator_destroy"); - - LoadProc(lsf_init_intern, "lsf_init"); - LoadProc(lsf_get_last_error_code, "lsf_getLastErrorCode"); - LoadProc(lsf_get_last_error_msg, "lsf_getLastErrorMsg"); - LoadProc(lsf_get_last_error_trace, "lsf_getLastErrorTrace"); - LoadProc(lsf_finish_intern, "lsf_finish"); - - return lsf_init_intern(); -} - -int lsf_finish(void) -{ - lsf_error_code_t err = lsf_finish_intern(); - if (!close_lib(handle)) - return LSF_ERR_INVALID_LIBRARY_HANDLE; - return err; -} diff --git a/library/header/c/libShaderFile.h b/library/header/c/libShaderFile.h deleted file mode 100644 index 57e3bb6..0000000 --- a/library/header/c/libShaderFile.h +++ /dev/null @@ -1,88 +0,0 @@ -#ifndef LIB_SHADER_FILE_H -#define LIB_SHADER_FILE_H - -#include - -#define LSF_LOGLEVEL_DEBUG 0 -#define LSF_LOGLEVEL_INFO 1 -#define LSF_LOGLEVEL_WARNING 2 -#define LSF_LOGLEVEL_ERROR 3 - -#define LSF_ERR_NONE 0x00000000 -#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_GENERATOR_NAME 0x00000020 -#define LSF_ERR_INVALID_PROPERTY_INDEX 0x00000021 -#define LSF_ERR_INVALID_PROPERTY_NAME 0x00000022 -#define LSF_ERR_UNKNOWN_IDENTFIFIER 0x00001000 -#define LSF_ERR_DUPLICATE_IDENTIFIER 0x00001001 -#define LSF_ERR_OUT_OF_RANGE 0x00001002 -#define LSF_ERR_INVALID_IDENTIFIER 0x00001003 -#define LSF_ERR_INVALID_PARAMTER_COUNT 0x00001004 -#define LSF_ERR_INVALID_PARAMTER 0x00001005 -#define LSF_ERR_UNEXPECTED_TOKEN 0x00001006 -#define LSF_ERR_INVALID_TOKEN 0x00001007 -#define LSF_ERR_EXPRESSION_INTERNAL 0x00001008 -#define LSF_ERR_EXPRESSION 0x00001009 -#define LSF_ERR_SHADER_PART_INTERNAL 0x0000100A -#define LSF_ERR_SHADER_PART 0x0000100B -#define LSF_ERR_INVALID_LIBRARY_NAME 0x00002000 -#define LSF_ERR_INVALID_LIBRARY_HANDLE 0x00002001 -#define LSF_ERR_INVALID_METHOD_NAME 0x00002002 -#define LSF_ERR_UNKNOWN 0xFFFFFFFF - -#define WINAPI __stdcall - -typedef uint32_t lsf_error_code_t; -typedef uint32_t lsf_log_level_t; -typedef void* lsf_shader_file_handle_t; -typedef void* lsf_shader_generator_handle_t; -typedef void (*lsf_shader_file_log_callback_t)(const lsf_log_level_t loglevel, const char* msg, const void* userargs); - -typedef lsf_shader_file_handle_t (WINAPI *lsf_shader_file_create_t) (); -typedef lsf_error_code_t (WINAPI *lsf_shader_file_set_log_callback_t) (const lsf_shader_file_handle_t handle, const lsf_shader_file_log_callback_t callback, const void* userargs); -typedef lsf_error_code_t (WINAPI *lsf_shader_file_load_from_file_t) (const lsf_shader_file_handle_t handle, const char* filename); -typedef lsf_error_code_t (WINAPI *lsf_shader_file_save_to_file_t) (const lsf_shader_file_handle_t handle, const char* filename); -typedef const char* (WINAPI *lsf_shader_file_get_generator_names_t) (const lsf_shader_file_handle_t handle); -typedef lsf_error_code_t (WINAPI *lsf_shader_file_destroy_t) (const lsf_shader_file_handle_t handle); - -typedef lsf_shader_generator_handle_t (WINAPI *lsf_generator_create_t) (const lsf_shader_file_handle_t handle, const char* name); -typedef const char* (WINAPI *lsf_generator_get_property_names_t) (const lsf_shader_generator_handle_t handle); -typedef const char* (WINAPI *lsf_generator_get_property_t) (const lsf_shader_generator_handle_t handle, const int index); -typedef const char* (WINAPI *lsf_generator_get_property_by_name_t) (const lsf_shader_generator_handle_t handle, const char* name); -typedef lsf_error_code_t (WINAPI *lsf_generator_set_property_t) (const lsf_shader_generator_handle_t handle, const int index, const char* value); -typedef lsf_error_code_t (WINAPI *lsf_generator_set_property_by_name_t) (const lsf_shader_generator_handle_t handle, const char* name, const char* value); -typedef const char* (WINAPI *lsf_generator_generate_code_t) (const lsf_shader_generator_handle_t handle); -typedef lsf_error_code_t (WINAPI *lsf_generator_destroy_t) (const lsf_shader_generator_handle_t handle); - -typedef lsf_error_code_t (WINAPI *lsf_init_t) (); -typedef lsf_error_code_t (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 lsf_error_code_t (WINAPI *lsf_finish_t) (); - -lsf_shader_file_create_t lsf_shader_file_create; -lsf_shader_file_set_log_callback_t lsf_shader_file_set_log_callback; -lsf_shader_file_load_from_file_t lsf_shader_file_load_from_file; -lsf_shader_file_save_to_file_t lsf_shader_file_save_to_file; -lsf_shader_file_get_generator_names_t lsf_shader_file_get_generator_names; -lsf_shader_file_destroy_t lsf_shader_file_destroy; - -lsf_generator_create_t lsf_generator_create; -lsf_generator_get_property_names_t lsf_generator_get_property_names; -lsf_generator_get_property_t lsf_generator_get_property; -lsf_generator_get_property_by_name_t lsf_generator_get_property_by_name; -lsf_generator_set_property_t lsf_generator_set_property; -lsf_generator_set_property_by_name_t lsf_generator_set_property_by_name; -lsf_generator_generate_code_t lsf_generator_generate_code; -lsf_generator_destroy_t lsf_generator_destroy; - -lsf_get_last_error_code_t lsf_get_last_error_code; -lsf_get_last_error_msg_t lsf_get_last_error_msg; -lsf_get_last_error_trace_t lsf_get_last_error_trace; - -int lsf_init(const char* libname); -int lsf_finish(void); - -#endif /* LIB_SHADER_FILE_H */ \ No newline at end of file diff --git a/library/header/c/example/test.c b/library/header/examples/example.c similarity index 79% rename from library/header/c/example/test.c rename to library/header/examples/example.c index 5d79863..2596631 100644 --- a/library/header/c/example/test.c +++ b/library/header/examples/example.c @@ -15,7 +15,7 @@ int main(int argc, char **argv) return 1; } - lsf_init("../../library/libShaderFile-i386-win32.dll"); + lsf_init("../../libShaderFile-i386-win32.dll"); // create shader file sfHandle = lsf_shader_file_create(); @@ -25,7 +25,7 @@ int main(int argc, char **argv) ret = 2; goto cleanup_lib; } - + // load shader file err = lsf_shader_file_load_from_file(sfHandle, argv[1]); if (err != LSF_ERR_NONE) @@ -34,7 +34,7 @@ int main(int argc, char **argv) ret = 3; goto cleanup_shader_file; } - + // create generator sgHandle = lsf_generator_create(sfHandle, argv[2]); if (!sgHandle) @@ -69,10 +69,19 @@ int main(int argc, char **argv) printf("%s", code); cleanup_shader_generator: - lsf_generator_destroy(sgHandle); + err = lsf_generator_destroy(sgHandle); + if (err != LSF_ERR_NONE) + printf("warning: could not destroy generator handle: %d\n", err); + cleanup_shader_file: - lsf_shader_file_destroy(sfHandle); + err = lsf_shader_file_destroy(sfHandle); + if (err != LSF_ERR_NONE) + printf("warning: could not destroy shader file handle: %d\n", err); + cleanup_lib: - lsf_finish(); + err = lsf_finish(); + if (err != LSF_ERR_NONE) + printf("warning: could finish library: %d\n", err); + return ret; } \ No newline at end of file diff --git a/library/header/examples/example.cpp b/library/header/examples/example.cpp new file mode 100644 index 0000000..3f2bdcd --- /dev/null +++ b/library/header/examples/example.cpp @@ -0,0 +1,42 @@ +#include +#include "../libShaderFile.hpp" + +int main(int argc, char **argv) +{ + try + { + if (argc < 3) + { + std::cout << "error: expected input file and generator/class name as parameter" << std::endl; + return 1; + } + + // initialize library + lsf::Library lib("../../libShaderFile-i386-win32.dll"); + + // create and load shader file + lsf::ShaderFile shaderFile(lib); + shaderFile.loadFromFile(argv[1]); + + const lsf::Library& l = shaderFile.getLibrary(); + + // get generator + lsf::Generator generator(shaderFile, argv[2]); + + int i = 3; + while (i < argc-1) + { + generator.setProperty(argv[i], argv[i+1]); + i += 2; + } + + std::cout << generator.generateCode() << std::endl; + + return 0; + } + catch(const std::exception& ex) + { + std::cout << "error: " << ex.what() << std::endl; + return 2; + } +} \ No newline at end of file diff --git a/library/header/libShaderFile.h b/library/header/libShaderFile.h new file mode 100644 index 0000000..3b975be --- /dev/null +++ b/library/header/libShaderFile.h @@ -0,0 +1,247 @@ +#ifndef LIB_SHADER_FILE_H +#define LIB_SHADER_FILE_H + +#include + +/**********************************************************************************************************************************/ +/* public interface */ +/**********************************************************************************************************************************/ +#define LSF_LOGLEVEL_DEBUG 0 +#define LSF_LOGLEVEL_INFO 1 +#define LSF_LOGLEVEL_WARNING 2 +#define LSF_LOGLEVEL_ERROR 3 + +#define LSF_ERR_NONE 0x00000000 +#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_GENERATOR_NAME 0x00000020 +#define LSF_ERR_INVALID_PROPERTY_INDEX 0x00000021 +#define LSF_ERR_INVALID_PROPERTY_NAME 0x00000022 +#define LSF_ERR_GENERATOR_NOT_ASSIGNED_TO_FILE 0x00000023 +#define LSF_ERR_UNKNOWN_IDENTFIFIER 0x00001000 +#define LSF_ERR_DUPLICATE_IDENTIFIER 0x00001001 +#define LSF_ERR_OUT_OF_RANGE 0x00001002 +#define LSF_ERR_INVALID_IDENTIFIER 0x00001003 +#define LSF_ERR_INVALID_PARAMTER_COUNT 0x00001004 +#define LSF_ERR_INVALID_PARAMTER 0x00001005 +#define LSF_ERR_UNEXPECTED_TOKEN 0x00001006 +#define LSF_ERR_INVALID_TOKEN 0x00001007 +#define LSF_ERR_EXPRESSION_INTERNAL 0x00001008 +#define LSF_ERR_EXPRESSION 0x00001009 +#define LSF_ERR_SHADER_PART_INTERNAL 0x0000100A +#define LSF_ERR_SHADER_PART 0x0000100B +#define LSF_ERR_INVALID_LIBRARY_NAME 0x00002000 +#define LSF_ERR_INVALID_LIBRARY_HANDLE 0x00002001 +#define LSF_ERR_INVALID_METHOD_NAME 0x00002002 +#define LSF_ERR_UNKNOWN 0xFFFFFFFF + +#define WINAPI __stdcall + +typedef uint32_t lsf_error_code_t; +typedef uint32_t lsf_log_level_t; +typedef void* lsf_shader_file_handle_t; +typedef void* lsf_shader_generator_handle_t; + +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) */ +lsf_shader_file_handle_t (WINAPI *lsf_shader_file_create) (); + +/** set the callback for log messages of a specific shader file handle + * @param handle shader file handle to set callback for + * @param callback pointer to callback function + * @param userargs user defined arguments + * @returns error code (see LSF_ERR_*) */ +lsf_error_code_t (WINAPI *lsf_shader_file_set_log_callback) (const lsf_shader_file_handle_t handle, const lsf_shader_file_log_callback_t callback, const void* userargs); + +/** load shader file code from a given file + * @param handle handle of shader file to load from file + * @param filename file to load shader code from + * @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); + +/** 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); + +/** 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) */ +const char* (WINAPI *lsf_shader_file_get_generator_names) (const lsf_shader_file_handle_t handle); + +/** destroy a shader file handle + * @param handle shader file handle to destroy + * @returns error code (see LSF_ERR_*) */ +lsf_error_code_t (WINAPI *lsf_shader_file_destroy) (const lsf_shader_file_handle_t handle); + + +/** create a new code generator from a given shader file. the generator is owned by the shader file handle. + * if you destroy a shader file handle, all associated generator handles will be destroyed to. + * @param handle shader file handle to create generator from + * @param name name of the generator (see lsf_shader_file_get_generator_names to get a list of all valid names) + * @return generator handle of NULL (check lsf_get_last_error_* for more details) */ +lsf_shader_generator_handle_t (WINAPI *lsf_generator_create) (const lsf_shader_file_handle_t handle, const char* name); + +/** generate a list of all known properties within a given generator handle + * @handle generator handle to get properties from + * @return list of all known properties (seperated by linebreak) or NULL (check lsf_get_last_error_* for more details) */ +const char* (WINAPI *lsf_generator_get_property_names) (const lsf_shader_generator_handle_t handle); + +/** get a property value by its index + * @param handle generator handle + * @param index index of the property (see lsf_generator_get_property_names to calculate property index) + * @return property value or NULL (check lsf_get_last_error_* for more details) */ +const char* (WINAPI *lsf_generator_get_property) (const lsf_shader_generator_handle_t handle, const int index); + +/** get a property value by its name + * @param handle generator handle + * @param name name of the property + * @return property value or NULL (check lsf_get_last_error_* for more details) */ +const char* (WINAPI *lsf_generator_get_property_by_name) (const lsf_shader_generator_handle_t handle, const char* name); + +/** set a property value by its index + * @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) */ +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) */ +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 + * @param handle generator handle + * @return generated shader code or NULL (check lsf_get_last_error_* for more details) */ +const char* (WINAPI *lsf_generator_generate_code) (const lsf_shader_generator_handle_t handle); + +/** destroy a generator handle + * @param handle generator handle to destroy + * @returns error code (see LSF_ERR_*) */ +lsf_error_code_t (WINAPI *lsf_generator_destroy) (const lsf_shader_generator_handle_t handle); + + +/** get last error code + * @return error code of last failed operation */ +lsf_error_code_t (WINAPI *lsf_get_last_error_code) (); + +/** get last error message + * @return error message of last failed operation */ +const char* (WINAPI *lsf_get_last_error_msg) (); + +/** get last error trace + * @return error message and a trace of last failed operation */ +const char* (WINAPI *lsf_get_last_error_trace) (); + +/** initialize the library + * @param libname name of the shared library to load data from + * @return 0 on success, LSF_ERR_* otherwise */ +int lsf_init(const char* libname); + +/** finalize the library + * @return 0 on success, LSF_ERR_* otherwise */ +int lsf_finish(void); + + +/**********************************************************************************************************************************/ +/* internal initialization code */ +/**********************************************************************************************************************************/ +//#define LSF_DEBUG +#ifdef LSF_DEBUG +# include +#endif + +#if defined(WIN32) || defined(WIN64) +# include + +typedef HMODULE lib_handle_t; + +lib_handle_t open_lib(const char* name) + { return LoadLibrary(name); }; + +void* get_addr(lib_handle_t handle, const char* name) + { return GetProcAddress(handle, name); }; + +int close_lib(lib_handle_t handle) + { return FreeLibrary(handle); }; + +#elif defined(LINUX) +# include +# error "linux is not supported yet" +#else +# error "unknown operation system" +#endif + +#ifndef LSF_DEBUG +# define LoadProc(proc, name) \ + proc = get_addr(handle, name); \ + if (!proc) \ + return LSF_ERR_INVALID_METHOD_NAME +#else +# define LoadProc(proc, name) \ + proc = get_addr(handle, name); \ + printf("load method '%s' (addr=0x%016x)\n", name, proc); \ + if (!proc) \ + return LSF_ERR_INVALID_METHOD_NAME +#endif + +lsf_error_code_t (WINAPI *lsf_init_intern)(); +lsf_error_code_t (WINAPI *lsf_finish_intern)(); + +lib_handle_t handle = NULL; + +int lsf_init(const char* libname) +{ +#ifdef LSF_DEBUG + printf("loading library '%s'\n", libname); +#endif + + handle = open_lib(libname); + if (!handle) + return LSF_ERR_INVALID_LIBRARY_NAME; + +#ifdef LSF_DEBUG + printf(" done (handle=0x%016x)\n", handle); +#endif + + LoadProc(lsf_shader_file_create, "lsf_ShaderFile_create"); + LoadProc(lsf_shader_file_set_log_callback, "lsf_ShaderFile_setLogCallback"); + LoadProc(lsf_shader_file_load_from_file, "lsf_ShaderFile_loadFromFile"); + LoadProc(lsf_shader_file_save_to_file, "lsf_ShaderFile_saveToFile"); + LoadProc(lsf_shader_file_get_generator_names, "lsf_ShaderFile_getGeneratorNames"); + LoadProc(lsf_shader_file_destroy, "lsf_ShaderFile_destroy"); + + LoadProc(lsf_generator_create, "lsf_Generator_create"); + LoadProc(lsf_generator_get_property_names, "lsf_Generator_getPropertyNames"); + LoadProc(lsf_generator_get_property, "lsf_Generator_getProperty"); + LoadProc(lsf_generator_get_property_by_name, "lsf_Generator_getPropertyByName"); + LoadProc(lsf_generator_set_property, "lsf_Generator_setProperty"); + LoadProc(lsf_generator_set_property_by_name, "lsf_Generator_setPropertyByName"); + LoadProc(lsf_generator_generate_code, "lsf_Generator_generateCode"); + LoadProc(lsf_generator_destroy, "lsf_Generator_destroy"); + + LoadProc(lsf_init_intern, "lsf_init"); + LoadProc(lsf_get_last_error_code, "lsf_getLastErrorCode"); + LoadProc(lsf_get_last_error_msg, "lsf_getLastErrorMsg"); + LoadProc(lsf_get_last_error_trace, "lsf_getLastErrorTrace"); + LoadProc(lsf_finish_intern, "lsf_finish"); + + return lsf_init_intern(); +} + +int lsf_finish(void) +{ + lsf_error_code_t err = lsf_finish_intern(); + if (!close_lib(handle)) + return LSF_ERR_INVALID_LIBRARY_HANDLE; + return err; +} + +#endif /* LIB_SHADER_FILE_H */ \ No newline at end of file diff --git a/library/header/libShaderFile.hpp b/library/header/libShaderFile.hpp new file mode 100644 index 0000000..817a5fa --- /dev/null +++ b/library/header/libShaderFile.hpp @@ -0,0 +1,563 @@ +#ifndef LIB_SHADER_FILE_HPP +#define LIB_SHADER_FILE_HPP + +#include +#include +#include +#include + +#if defined(WIN32) || defined(WIN64) +# include +#elif defined(LINUX) +# include +#else +# error "unknown operation system" +#endif + +/**********************************************************************************************************************************/ +/* public interface */ +/**********************************************************************************************************************************/ +namespace lsf +{ + enum LogLevel + { + llDebug = 0, + llInfo = 1, + llWarning = 2, + llError = 3, + }; + + enum ErrorCode + { + errNone = 0x00000000, + errNotInit = 0x00000001, + errInvalidHandleShaderFile = 0x00000010, + errInvalidHandleShaderGenerator = 0x00000011, + errInvalidGeneratorName = 0x00000020, + errInvalidPropertyIndex = 0x00000021, + errInvalidPropertyName = 0x00000022, + errGeneratorNotAssignedToFile = 0x00000023, + errUnknownIdentfifier = 0x00001000, + errDuplicateIdentifier = 0x00001001, + errOutOfRange = 0x00001002, + errInvalidIdentifier = 0x00001003, + errInvalidParamterCount = 0x00001004, + errInvalidParamter = 0x00001005, + errUnexpectedToken = 0x00001006, + errInvalidToken = 0x00001007, + errExpressionInternal = 0x00001008, + errExpression = 0x00001009, + errShaderPartInternal = 0x0000100a, + errShaderPart = 0x0000100b, + errInvalidLibraryName = 0x00002000, + errInvalidLibraryHandle = 0x00002001, + errInvalidMethodName = 0x00002002, + errUnknown = 0xffffffff, + }; + + /** class to load and manage shared library */ + class Library + { + friend class ShaderFile; + friend class Generator; + + public: + #if defined(WIN32) || defined(WIN64) + typedef HMODULE Handle; //!< shader file handle + #elif defined(LINUX) + #error "linux is not supported yet" + #else + #error "unknown operation system" + #endif + + private: + struct Impl; //!< struct that implements the libraries methods + Impl* _impl; //!< struct that implements the libraries methods + Handle _handle; //!< handle of shared library + + public: + /** get last error code + * @return error code of last failed operation */ + ErrorCode getLastErrorCode() const; + + /** get last error message + * @return error message of last failed operation */ + std::string getLastErrorMsg() const; + + /** get last error trace + * @return error trace of last failed operation */ + std::string getLastErrorTrace() const; + + /** constructor + * @param libName name of shared library file */ + Library(std::string libName); + + /** destructor */ + virtual ~Library(); + + private: + /** deleted copy constructor */ + Library(const Library& that) { }; + }; + + /** class to manage a shader file */ + class ShaderFile + { + public: + typedef void* Handle; //!< shader file handle + + private: + const Library::Impl& _impl; //!< struct that implements the libraries methods + Handle _handle; //!< handle of this shader file + + protected: + /** method to log messages from shader file and code generation + * @param logLevel level of the log message + * @param msg message to write log log */ + virtual void logMsg(LogLevel logLevel, const std::string& msg); + + public: + /** get shader file handle + * @return handle of this shader file */ + Handle getHandle() const; + + /** get library + * @return library object this shader file is attached to */ + const Library& getLibrary() const; + + /** load shader file from a given file + * @param filename file to load shader code from */ + void loadFromFile(std::string filename); + + /** save shader file to a given file + * @param filename file to save shader code to */ + void saveToFile(std::string filename) const; + + /** constructor + * @param library library this shader file is attached to */ + ShaderFile(const Library& library); + + /** destructor */ + virtual ~ShaderFile(); + + private: + /** deleted copy constructor */ + ShaderFile(const ShaderFile& that); + + public: + /** callback method for log messages + * @param logLevel log level of the log message + * @param msg log message + * @param userargs user defined arguments */ + static void __stdcall logCallback(const LogLevel loglevel, const char* msg, void* userargs); + }; + + /** class to manage a shader code generator */ + class Generator + { + public: + typedef void* Handle; //!< shader generator handle + typedef std::vector StringVec; //!< vector of strings + + private: + const Library::Impl& _impl; //!< struct that implements the libraries methods + const ShaderFile& _shaderFile; //!< shader file the generator is attached to + std::string _name; //!< name of this generator + Handle _handle; //!< handle of this generator + StringVec _propertyNames; //!< vector with all known properties + + public: + /** get generator name + * @return name of this generator */ + std::string getName() const; + + /** get generator handle + * @return handle of this generator */ + Handle getHandle() const; + + /** get shader file this generator is attached to + * @return shader file this genrator is attached to */ + const ShaderFile& getShaderFile() const; + + /** get a vector of all known properties + * @return vecotr with all known properties */ + const StringVec& getPropertyNames() const; + + /** get the value of a single property by its name + * @param name name of the property + * @return value of the property */ + std::string getProperty(const std::string& name) const; + + /** get the value of a single property by its index + * @param index index of the property (see getPropertyNames() to get the index of a property) + * @return value of the property */ + std::string getProperty(int index) const; + + /** set the value of a single property by its name + * @param name name of the property + * @param value value of the property */ + void setProperty(const std::string& name, const std::string& value); + + /** set the value of a single property by its index + * @param index index of the property (see getPropertyNames() to get the index of a property) + * @param value value of the property */ + void setProperty(int index, const std::string& value); + + /** generate the shader code with the current property setup + * @return generated shader code */ + std::string generateCode() const; + + /** constructor + * @param shaderFile shader file this generator is attached to + * @param name name of a valid generator inside the shaderFile */ + Generator(const ShaderFile& shaderFile, std::string name); + + /** destructor */ + virtual ~Generator(); + + private: + /** deleted copy constructor */ + Generator(const Generator& that); + }; + + /** object to handle error inside this library */ + class Exception : public std::exception + { + private: + std::string _message; //!< error message + ErrorCode _errorCode; //!< suitable error code to the error message + + public: + /** get error code + * @return error code of this exception */ + ErrorCode getErrorCode() const; + + /** get error message + * @return error message of this exception */ + std::string getMessage() const; + + /** @return error message of this exception */ + virtual const char* what() const throw(); + + /** constructor */ + Exception(std::string message, ErrorCode errorCode = errUnknown); + + /** destructor */ + ~Exception() throw(); + }; +} + + + + +/**********************************************************************************************************************************/ +/* private implementation */ +/**********************************************************************************************************************************/ +#if defined(WIN32) || defined(WIN64) +lsf::Library::Handle libOpen(const char* name) + { return LoadLibrary(name); }; + +template +T getAddr(lsf::Library::Handle handle, const char* name) +{ + FARPROC tmp = GetProcAddress(handle, name); + return reinterpret_cast(tmp); +}; + +int libClose(lsf::Library::Handle handle) + { return FreeLibrary(handle); }; + +#elif defined(LINUX) +# include +# error "linux is not supported yet" +#else +# error "unknown operation system" +#endif + +/* Library::Impl ******************************************************************************************************************/ +struct lsf::Library::Impl +{ + typedef ShaderFile::Handle (__stdcall *lsf_shader_file_create_t) (); + typedef void (__stdcall *lsf_shader_file_log_callback_t) (const LogLevel loglevel, const char* msg, void* userargs); + typedef ErrorCode (__stdcall *lsf_shader_file_set_log_callback_t) (const ShaderFile::Handle handle, const lsf_shader_file_log_callback_t callback, void* userargs); + typedef ErrorCode (__stdcall *lsf_shader_file_load_from_file_t) (const ShaderFile::Handle handle, const char* filename); + typedef ErrorCode (__stdcall *lsf_shader_file_save_to_file_t) (const ShaderFile::Handle handle, const char* filename); + typedef const char* (__stdcall *lsf_shader_file_get_generator_names_t) (const ShaderFile::Handle handle); + typedef ErrorCode (__stdcall *lsf_shader_file_destroy_t) (const ShaderFile::Handle handle); + + typedef Generator::Handle (__stdcall *lsf_generator_create_t) (const ShaderFile::Handle handle, const char* name); + typedef const char* (__stdcall *lsf_generator_get_property_names_t) (const Generator::Handle handle); + typedef const char* (__stdcall *lsf_generator_get_property_t) (const Generator::Handle handle, const int index); + typedef const char* (__stdcall *lsf_generator_get_property_by_name_t) (const Generator::Handle handle, const char* name); + typedef ErrorCode (__stdcall *lsf_generator_set_property_t) (const Generator::Handle handle, const int index, const char* value); + typedef ErrorCode (__stdcall *lsf_generator_set_property_by_name_t) (const Generator::Handle handle, const char* name, const char* value); + typedef const char* (__stdcall *lsf_generator_generate_code_t) (const Generator::Handle handle); + typedef ErrorCode (__stdcall *lsf_generator_destroy_t) (const Generator::Handle handle); + + typedef ErrorCode (__stdcall *lsf_init_t) (); + typedef ErrorCode (__stdcall *lsf_get_last_error_code_t) (); + typedef const char* (__stdcall *lsf_get_last_error_msg_t) (); + typedef const char* (__stdcall *lsf_get_last_error_trace_t) (); + typedef ErrorCode (__stdcall *lsf_finish_t) (); + + const Library& library; + + lsf_shader_file_create_t lsf_shader_file_create; + lsf_shader_file_set_log_callback_t lsf_shader_file_set_log_callback; + lsf_shader_file_load_from_file_t lsf_shader_file_load_from_file; + lsf_shader_file_save_to_file_t lsf_shader_file_save_to_file; + lsf_shader_file_get_generator_names_t lsf_shader_file_get_generator_names; + lsf_shader_file_destroy_t lsf_shader_file_destroy; + + lsf_generator_create_t lsf_generator_create; + lsf_generator_get_property_names_t lsf_generator_get_property_names; + lsf_generator_get_property_t lsf_generator_get_property; + lsf_generator_get_property_by_name_t lsf_generator_get_property_by_name; + lsf_generator_set_property_t lsf_generator_set_property; + lsf_generator_set_property_by_name_t lsf_generator_set_property_by_name; + lsf_generator_generate_code_t lsf_generator_generate_code; + lsf_generator_destroy_t lsf_generator_destroy; + + lsf_init_t lsf_init; + lsf_get_last_error_code_t lsf_get_last_error_code; + lsf_get_last_error_msg_t lsf_get_last_error_msg; + lsf_get_last_error_trace_t lsf_get_last_error_trace; + lsf_finish_t lsf_finish; + + Impl(const Library& library) : + library (library), + + lsf_shader_file_create (NULL), + lsf_shader_file_set_log_callback (NULL), + lsf_shader_file_load_from_file (NULL), + lsf_shader_file_save_to_file (NULL), + lsf_shader_file_get_generator_names (NULL), + lsf_shader_file_destroy (NULL), + + lsf_generator_create (NULL), + lsf_generator_get_property_names (NULL), + lsf_generator_get_property (NULL), + lsf_generator_get_property_by_name (NULL), + lsf_generator_set_property (NULL), + lsf_generator_set_property_by_name (NULL), + lsf_generator_generate_code (NULL), + lsf_generator_destroy (NULL), + + lsf_init (NULL), + lsf_get_last_error_code (NULL), + lsf_get_last_error_msg (NULL), + lsf_get_last_error_trace (NULL), + lsf_finish (NULL) + { }; +}; + +/* Library ************************************************************************************************************************/ +template +inline void loadProc(lsf::Library::Handle handle, T& proc, const char* name) +{ + proc = getAddr(handle, name); + if (!proc) + throw lsf::Exception(std::string("unable to load method from library: ") + name, lsf::errInvalidMethodName); +} + +lsf::ErrorCode lsf::Library::getLastErrorCode() const + { return _impl->lsf_get_last_error_code(); } + +std::string lsf::Library::getLastErrorMsg() const + { return std::string(_impl->lsf_get_last_error_msg()); } + +std::string lsf::Library::getLastErrorTrace() const + { return std::string(_impl->lsf_get_last_error_trace()); } + +lsf::Library::Library(std::string libName) : + _impl(new Impl(*this)) +{ + _handle = libOpen(libName.c_str()); + if (!_handle) + throw Exception("unable to open shared library: " + libName, lsf::errInvalidLibraryName); + + loadProc(_handle, _impl->lsf_shader_file_create, "lsf_ShaderFile_create"); + loadProc(_handle, _impl->lsf_shader_file_set_log_callback, "lsf_ShaderFile_setLogCallback"); + loadProc(_handle, _impl->lsf_shader_file_load_from_file, "lsf_ShaderFile_loadFromFile"); + loadProc(_handle, _impl->lsf_shader_file_save_to_file, "lsf_ShaderFile_saveToFile"); + loadProc(_handle, _impl->lsf_shader_file_get_generator_names, "lsf_ShaderFile_getGeneratorNames"); + loadProc(_handle, _impl->lsf_shader_file_destroy, "lsf_ShaderFile_destroy"); + + loadProc(_handle, _impl->lsf_generator_create, "lsf_Generator_create"); + loadProc(_handle, _impl->lsf_generator_get_property_names, "lsf_Generator_getPropertyNames"); + loadProc(_handle, _impl->lsf_generator_get_property, "lsf_Generator_getProperty"); + loadProc(_handle, _impl->lsf_generator_get_property_by_name, "lsf_Generator_getPropertyByName"); + loadProc(_handle, _impl->lsf_generator_set_property, "lsf_Generator_setProperty"); + loadProc(_handle, _impl->lsf_generator_set_property_by_name, "lsf_Generator_setPropertyByName"); + loadProc(_handle, _impl->lsf_generator_generate_code, "lsf_Generator_generateCode"); + loadProc(_handle, _impl->lsf_generator_destroy, "lsf_Generator_destroy"); + + loadProc(_handle, _impl->lsf_init, "lsf_init"); + loadProc(_handle, _impl->lsf_get_last_error_code, "lsf_getLastErrorCode"); + loadProc(_handle, _impl->lsf_get_last_error_msg, "lsf_getLastErrorMsg"); + loadProc(_handle, _impl->lsf_get_last_error_trace, "lsf_getLastErrorTrace"); + loadProc(_handle, _impl->lsf_finish, "lsf_finish"); + + ErrorCode err = _impl->lsf_init(); + if (err != lsf::errNone) + throw Exception("unable to initialize library", err); +} + +lsf::Library::~Library() +{ + if (_impl) + { + _impl->lsf_finish(); + delete _impl; + _impl = NULL; + } + if (_handle) + { + libClose(_handle); + _handle = NULL; + } +} + +/* ShaderFile *********************************************************************************************************************/ +void lsf::ShaderFile::logMsg(LogLevel logLevel, const std::string& msg) + { /* DUMMY */ } + +inline lsf::ShaderFile::Handle lsf::ShaderFile::getHandle() const + { return _handle; } + +inline const lsf::Library& lsf::ShaderFile::getLibrary() const + { return _impl.library; } + +void lsf::ShaderFile::loadFromFile(std::string filename) +{ + ErrorCode err = _impl.lsf_shader_file_load_from_file(_handle, filename.c_str()); + if (err != errNone) + throw Exception("unable to load file", err); +} + +void lsf::ShaderFile::saveToFile(std::string filename) const +{ + ErrorCode err = _impl.lsf_shader_file_load_from_file(_handle, filename.c_str()); + if (err != errNone) + throw Exception("unable to load file", err); +} + +lsf::ShaderFile::ShaderFile(const Library& library) : + _impl(*library._impl) +{ + _handle = _impl.lsf_shader_file_create(); + if (!_handle) + throw Exception(_impl.lsf_get_last_error_msg(), _impl.lsf_get_last_error_code()); + ErrorCode err = _impl.lsf_shader_file_set_log_callback(_handle, &ShaderFile::logCallback, this); + if (err != errNone) + logMsg(llWarning, "unable to register log callback"); +} + +lsf::ShaderFile::~ShaderFile() +{ + _impl.lsf_shader_file_destroy(_handle); + _handle = NULL; +} + +void lsf::ShaderFile::logCallback(const lsf::LogLevel loglevel, const char* msg, void* userargs) +{ + static_cast(userargs)->logMsg(loglevel, std::string(msg)); +} + +/* Generator **********************************************************************************************************************/ +inline std::string lsf::Generator::getName() const + { return _name; }; + +inline lsf::Generator::Handle lsf::Generator::getHandle() const + { return _handle; }; + +inline const lsf::ShaderFile& lsf::Generator::getShaderFile() const + { return _shaderFile; }; + +inline const lsf::Generator::StringVec& lsf::Generator::getPropertyNames() const + { return _propertyNames; }; + +std::string lsf::Generator::getProperty(const std::string& name) const +{ + const char* ret = _impl.lsf_generator_get_property_by_name(_handle, name.c_str()); + if (!ret) + throw Exception(_impl.lsf_get_last_error_msg(), _impl.lsf_get_last_error_code()); + return std::string(ret); +} + +std::string lsf::Generator::getProperty(int index) const +{ + const char* ret = _impl.lsf_generator_get_property(_handle, index); + if (!ret) + throw Exception(_impl.lsf_get_last_error_msg(), _impl.lsf_get_last_error_code()); + return std::string(ret); +} + +void lsf::Generator::setProperty(const std::string& name, const std::string& value) +{ + ErrorCode err = _impl.lsf_generator_set_property_by_name(_handle, name.c_str(), value.c_str()); + if (err != errNone) + throw Exception(_impl.lsf_get_last_error_msg(), err); +} + +void lsf::Generator::setProperty(int index, const std::string& value) +{ + ErrorCode err = _impl.lsf_generator_set_property(_handle, index, value.c_str()); + if (err != errNone) + throw Exception(_impl.lsf_get_last_error_msg(), err); +} + +std::string lsf::Generator::generateCode() const +{ + const char* ret = _impl.lsf_generator_generate_code(_handle); + if (!ret) + throw Exception(_impl.lsf_get_last_error_msg(), _impl.lsf_get_last_error_code()); + return std::string(ret); +} + +lsf::Generator::Generator(const ShaderFile& shaderFile, std::string name) : + _shaderFile (shaderFile), + _impl (*shaderFile.getLibrary()._impl), + _name (name) +{ + _handle = _impl.lsf_generator_create(_shaderFile.getHandle(), _name.c_str()); + if (!_handle) + throw Exception(_impl.lsf_get_last_error_msg(), _impl.lsf_get_last_error_code()); + const char* propertyNames = _impl.lsf_generator_get_property_names(_handle); + if (propertyNames) + { + std::stringstream ss(propertyNames); + std::string item; + while (std::getline(ss, item, '\x10')) + _propertyNames.push_back(item); + } +} + +lsf::Generator::~Generator() +{ + _impl.lsf_generator_destroy(_handle); + _handle = NULL; +} + +/* Exception **********************************************************************************************************************/ +inline lsf::ErrorCode lsf::Exception::getErrorCode() const + { return _errorCode; } + +inline std::string lsf::Exception::getMessage() const + { return _message; } + +const char* lsf::Exception::what() const throw() + { return _message.c_str(); }; + +lsf::Exception::Exception(std::string message, ErrorCode errorCode) : + _message (message), + _errorCode (errorCode) + { } + +lsf::Exception::~Exception() throw() + { } + +#endif /* LIB_SHADER_FILE_HPP */ + + + diff --git a/library/header/delphi/ulibShaderFile.pas b/library/header/ulibShaderFile.pas similarity index 100% rename from library/header/delphi/ulibShaderFile.pas rename to library/header/ulibShaderFile.pas diff --git a/library/libShaderFile.lpr b/library/libShaderFile.lpr index beebb71..24b75d0 100644 --- a/library/libShaderFile.lpr +++ b/library/libShaderFile.lpr @@ -23,6 +23,7 @@ const LSF_ERR_INVALID_GENERATOR_NAME = $00000020; LSF_ERR_INVALID_PROPERTY_INDEX = $00000021; LSF_ERR_INVALID_PROPERTY_NAME = $00000022; + LSF_ERR_GENERATOR_NOT_ASSIGNED_TO_FILE = $00000023; LSF_ERR_UNKNOWN_IDENTFIFIER = $00001000; LSF_ERR_DUPLICATE_IDENTIFIER = $00001001; LSF_ERR_OUT_OF_RANGE = $00001002; @@ -43,15 +44,19 @@ type TlsfLogLevel = Cardinal; TlsfShaderFileHandle = Pointer; TlsfShaderGeneratorHandle = Pointer; - TlsfShaderFileLogEvent = procedure(const aLogLevel: TlsfLogLevel; const aMsg: PAnsiChar; const aUserArgs: Pointer); + TlsfShaderFileLogEvent = procedure(const aLogLevel: TlsfLogLevel; const aMsg: PAnsiChar; const aUserArgs: Pointer); stdcall; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //internal types and contstants///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// type TShaderFile = class; + TShaderGenerator = class; TPropertyMap = specialize TutlMap; + TShaderGeneratorHandleHashSet = specialize TutlHashSet; + TShaderGeneratorHashSet = specialize TutlHashSet; + TShaderGenerator = class(TObject) private fOwner: TShaderFile; @@ -75,7 +80,7 @@ type destructor Destroy; override; end; - TShaderGeneratorHashSet = specialize TutlHashSet; + TShaderFile = class(TengShaderFile) private fLogUserArgs: Pointer; @@ -92,7 +97,7 @@ type procedure LoadFromFile(const aFilename: String); reintroduce; function CreateGenerator(const aName: String): TShaderGenerator; - procedure DestroyGenerator(const aGenerator: TShaderGenerator); + function DestroyGenerator(const aGenerator: TShaderGenerator): TlsfErrorCode; constructor Create; overload; destructor Destroy; override; @@ -102,7 +107,7 @@ type //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// var ShaderFiles: TShaderFileHashSet = nil; - ShaderGenerators: TShaderGeneratorHashSet = nil; + ShaderGenerators: TShaderGeneratorHandleHashSet = nil; LastErrorCode: TlsfErrorCode = LSF_ERR_NONE; LastErrorMsg: String = ''; LastErrorTrace: String = ''; @@ -443,7 +448,7 @@ begin try result := LSF_ERR_NONE; ShaderFiles := TShaderFileHashSet.Create(true); - ShaderGenerators := TShaderGeneratorHashSet.Create(false); + ShaderGenerators := TShaderGeneratorHandleHashSet.Create(true); except on e: Exception do begin SetLastError(e); @@ -649,11 +654,15 @@ begin end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -procedure TShaderFile.DestroyGenerator(const aGenerator: TShaderGenerator); +function TShaderFile.DestroyGenerator(const aGenerator: TShaderGenerator): TlsfErrorCode; begin if Assigned(ShaderGenerators) then ShaderGenerators.Remove(aGenerator); - fGenerators.Remove(aGenerator); + if not fGenerators.Remove(aGenerator) then begin + SetLastError(LSF_ERR_GENERATOR_NOT_ASSIGNED_TO_FILE, 'the passed generator handle is not owned by any file'); + result := LastErrorCode; + end else + result := LSF_ERR_NONE; end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////