Browse Source

* implemented loadFromFunc and saveToFunc

master
Bergmann89 11 years ago
parent
commit
a2da0168ad
8 changed files with 918 additions and 87 deletions
  1. +18
    -3
      header/examples/c++/example.cpp
  2. +2
    -2
      header/examples/c/example.c
  3. +22
    -3
      header/examples/delphi/example.dpr
  4. +21
    -2
      header/examples/fpc/example.lpr
  5. +83
    -3
      header/libShaderFile.h
  6. +348
    -27
      header/libShaderFile.hpp
  7. +197
    -9
      header/ulibShaderFile.pas
  8. +227
    -38
      libShaderFile.lpr

+ 18
- 3
header/examples/c++/example.cpp View File

@@ -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
- 2
header/examples/c/example.c View File

@@ -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_)


+ 22
- 3
header/examples/delphi/example.dpr View File

@@ -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


+ 21
- 2
header/examples/fpc/example.lpr View File

@@ -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;


+ 83
- 3
header/libShaderFile.h View File

@@ -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");


+ 348
- 27
header/libShaderFile.hpp View File

@@ -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()





+ 197
- 9
header/ulibShaderFile.pas View File

@@ -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


+ 227
- 38
libShaderFile.lpr View File

@@ -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.

Loading…
Cancel
Save