From f52829fe512661c16cfdf7be6c5da3c843a94735 Mon Sep 17 00:00:00 2001 From: Bergmann89 Date: Sun, 13 Sep 2015 01:47:34 +0200 Subject: [PATCH] * started implementation of dynamic library --- .gitignore | 6 +- header/ulibShaderFile.pas | 126 ++++++++++++++++ libShaderFile.lpi | 75 ++++++++++ libShaderFile.lpr | 298 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 503 insertions(+), 2 deletions(-) create mode 100644 header/ulibShaderFile.pas create mode 100644 libShaderFile.lpi create mode 100644 libShaderFile.lpr diff --git a/.gitignore b/.gitignore index d5ded14..13a06e0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ -*/lib/ +lib/ +debug/ *.lps *.exe *.res -*.ico \ No newline at end of file +*.ico +*.dll \ No newline at end of file diff --git a/header/ulibShaderFile.pas b/header/ulibShaderFile.pas new file mode 100644 index 0000000..8e3b5bd --- /dev/null +++ b/header/ulibShaderFile.pas @@ -0,0 +1,126 @@ +unit ulibShaderFile; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +const + LSF_LOGLEVEL_DEBUG = 0; + LSF_LOGLEVEL_INFO = 1; + LSF_LOGLEVEL_WARNING = 2; + LSF_LOGLEVEL_ERROR = 3; + + LSF_ERR_NONE = $00000000; + LSF_ERR_NOT_INIT = $00000001; + LSF_ERR_INVALID_HANDLE_SHADER_FILE = $00000002; + LSF_ERR_UNKNOWN_IDENTFIFIER = $00001000; + LSF_ERR_DUPLICATE_IDENTIFIER = $00001001; + LSF_ERR_OUT_OF_RANGE = $00001002; + LSF_ERR_INVALID_IDENTIFIER = $00001003; + LSF_ERR_INVALID_PARAMTER_COUNT = $00001004; + LSF_ERR_INVALID_PARAMTER = $00001005; + LSF_ERR_UNEXPECTED_TOKEN = $00001006; + LSF_ERR_INVALID_TOKEN = $00001007; + LSF_ERR_EXPRESSION_INTERNAL = $00001008; + LSF_ERR_EXPRESSION = $00001009; + LSF_ERR_SHADER_PART_INTERNAL = $0000100A; + LSF_ERR_SHADER_PART = $0000100B; + LSF_ERR_UNKNOWN = $FFFFFFFF; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +type + TlsfErrorCode = Cardinal; + TlsfLogLevel = Cardinal; + TlsfShaderFileHandle = Pointer; + TlsfShaderFileLogEvent = procedure(const aLogLevel: TlsfLogLevel; const aMsg: PAnsiChar); + + Tlsf_ShaderFile_create = function: TlsfShaderFileHandle; stdcall; + Tlsf_ShaderFile_setLogCallback = function(const aHandle: TlsfShaderFileHandle; const aCallback: TlsfShaderFileLogEvent): TlsfErrorCode; stdcall; + Tlsf_ShaderFile_loadFromFile = function(const aHandle: TlsfShaderFileHandle; const aFilename: PAnsiChar): TlsfErrorCode; stdcall; + Tlsf_ShaderFile_saveToFile = function(const aHandle: TlsfShaderFileHandle; const aFilename: PAnsiChar): TlsfErrorCode; stdcall; + Tlsf_ShaderFile_destroy = function(const aHandle: TlsfShaderFileHandle): TlsfErrorCode; 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; + +var + lsf_ShaderFile_create: Tlsf_ShaderFile_create; + lsf_ShaderFile_setLogCallback: Tlsf_ShaderFile_setLogCallback; + lsf_ShaderFile_loadFromFile: Tlsf_ShaderFile_loadFromFile; + lsf_ShaderFile_saveToFile: Tlsf_ShaderFile_saveToFile; + lsf_ShaderFile_destroy: Tlsf_ShaderFile_destroy; + + lsf_getLastErrorCode: Tlsf_getLastErrorCode; + lsf_getLastErrorMsg: Tlsf_getLastErrorMsg; + lsf_getLastErrorTrace: Tlsf_getLastErrorTrace; + +procedure lsf_init(const aLibName: String); +procedure lsf_finish; + +implementation + +uses + dynlibs; + +var + libHandle: TLibHandle; + lsf_init_intern: Tlsf_init; + lsf_finish_intern: Tlsf_finish; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure lsf_init(const aLibName: String); + + function LoadProc(const aName: AnsiString): Pointer; + begin + result := GetProcedureAddress(libHandle, aName); + if not Assigned(result) then + raise Exception.CreateFmt('unable to load ''%s'' from ''%s''', [aName, aLibName]); + end; + +begin + libHandle := LoadLibrary(aLibName); + if (libHandle = 0) then + raise Exception.CreateFmt('unable to load library: %s', [aLibName]); + 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_saveToFile := Tlsf_ShaderFile_saveToFile( LoadProc('lsf_ShaderFile_saveToFile')); + lsf_ShaderFile_destroy := Tlsf_ShaderFile_destroy( LoadProc('lsf_ShaderFile_destroy')); + + lsf_init_intern := Tlsf_init( LoadProc('lsf_init')); + lsf_getLastErrorCode := Tlsf_getLastErrorCode( LoadProc('lsf_getLastErrorCode')); + lsf_getLastErrorMsg := Tlsf_getLastErrorMsg( LoadProc('lsf_getLastErrorMsg')); + lsf_getLastErrorTrace := Tlsf_getLastErrorTrace( LoadProc('lsf_getLastErrorTrace')); + lsf_finish_intern := Tlsf_finish( LoadProc('lsf_finish')); + + if (lsf_init_intern() <> LSF_ERR_NONE) then + raise Exception.Create('error while initializing library: ' + lsf_getLastErrorMsg()); +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_destroy := nil; + lsf_getLastErrorCode := nil; + lsf_getLastErrorMsg := nil; + lsf_getLastErrorTrace := nil; + if (libHandle <> 0) then begin + FreeLibrary(libHandle); + libHandle := 0; + end; +end; + +end. + diff --git a/libShaderFile.lpi b/libShaderFile.lpi new file mode 100644 index 0000000..936f3c6 --- /dev/null +++ b/libShaderFile.lpi @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + <UseAppBundle Value="False"/> + <ResourceType Value="res"/> + </General> + <i18n> + <EnableI18N LFM="False"/> + </i18n> + <VersionInfo> + <StringTable ProductVersion=""/> + </VersionInfo> + <BuildModes Count="1"> + <Item1 Name="Default" Default="True"/> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + </PublishOptions> + <RunParams> + <local> + <FormatVersion Value="1"/> + </local> + </RunParams> + <Units Count="1"> + <Unit0> + <Filename Value="libShaderFile.lpr"/> + <IsPartOfProject Value="True"/> + <UnitName Value="libShaderFile"/> + </Unit0> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="libShaderFile"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <OtherUnitFiles Value=".."/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <CodeGeneration> + <RelocatableUnit Value="True"/> + </CodeGeneration> + <Linking> + <Options> + <ExecutableType Value="Library"/> + </Options> + </Linking> + </CompilerOptions> + <Debugging> + <Exceptions Count="3"> + <Item1> + <Name Value="EAbort"/> + </Item1> + <Item2> + <Name Value="ECodetoolError"/> + </Item2> + <Item3> + <Name Value="EFOpenError"/> + </Item3> + </Exceptions> + </Debugging> +</CONFIG> diff --git a/libShaderFile.lpr b/libShaderFile.lpr new file mode 100644 index 0000000..7faa7ff --- /dev/null +++ b/libShaderFile.lpr @@ -0,0 +1,298 @@ +library libShaderFile; + +{$mode objfpc}{$H+} + +uses + SysUtils, + uengShaderFile, uengShaderPart, uengShaderFileGenerics, uengShaderFileTypes; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//external types and contstants///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +const + LSF_LOGLEVEL_DEBUG = llDebug; + LSF_LOGLEVEL_INFO = llInfo; + LSF_LOGLEVEL_WARNING = llWarning; + LSF_LOGLEVEL_ERROR = llError; + + LSF_ERR_NONE = $00000000; + LSF_ERR_NOT_INIT = $00000001; + LSF_ERR_INVALID_HANDLE_SHADER_FILE = $00000002; + LSF_ERR_UNKNOWN_IDENTFIFIER = $00001000; + LSF_ERR_DUPLICATE_IDENTIFIER = $00001001; + LSF_ERR_OUT_OF_RANGE = $00001002; + LSF_ERR_INVALID_IDENTIFIER = $00001003; + LSF_ERR_INVALID_PARAMTER_COUNT = $00001004; + LSF_ERR_INVALID_PARAMTER = $00001005; + LSF_ERR_UNEXPECTED_TOKEN = $00001006; + LSF_ERR_INVALID_TOKEN = $00001007; + LSF_ERR_EXPRESSION_INTERNAL = $00001008; + LSF_ERR_EXPRESSION = $00001009; + LSF_ERR_SHADER_PART_INTERNAL = $0000100A; + LSF_ERR_SHADER_PART = $0000100B; + LSF_ERR_UNKNOWN = $FFFFFFFF; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +type + TlsfErrorCode = Cardinal; + TlsfLogLevel = Cardinal; + TlsfShaderFileHandle = Pointer; + TlsfShaderFileLogEvent = procedure(const aLogLevel: TlsfLogLevel; const aMsg: PAnsiChar); + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//internal types and contstants///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +type + TShaderFile = class(TengShaderFile) + private + fLogCallback: TlsfShaderFileLogEvent; + protected + procedure LogMsgIntern(const aSender: TengShaderPart; const aLogLevel: TengShaderPartLogLevel; const aMsg: String); override; + public + property LogCallback: TlsfShaderFileLogEvent read fLogCallback write fLogCallback; + end; + TengShaderFiles = specialize TutlHashSet<TShaderFile>; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +var + ShaderFiles: TengShaderFiles = nil; + LastErrorCode: TlsfErrorCode = LSF_ERR_NONE; + LastErrorMsg: String = ''; + LastErrorTrace: String = ''; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//Misc (not exportet)/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure SetLastError(const aErrorCode: TlsfErrorCode; const aMsg: String); +begin + LastErrorCode := aErrorCode; + LastErrorMsg := aMsg; + LastErrorTrace := ''; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure SetLastError(const aException: Exception); +begin + if (aException is EengUnknownIdentifier) then + LastErrorCode := LSF_ERR_UNKNOWN_IDENTFIFIER + else if (aException is EengDuplicateIdentifier) then + LastErrorCode := LSF_ERR_DUPLICATE_IDENTIFIER + else if (aException is EengOutOfRange) then + LastErrorCode := LSF_ERR_OUT_OF_RANGE + else if (aException is EengInvalidIdentifier) then + LastErrorCode := LSF_ERR_INVALID_IDENTIFIER + else if (aException is EengInvalidParamterCount) then + LastErrorCode := LSF_ERR_INVALID_PARAMTER_COUNT + else if (aException is EengInvalidParamter) then + LastErrorCode := LSF_ERR_INVALID_PARAMTER + else if (aException is EengUnexpectedToken) then + LastErrorCode := LSF_ERR_UNEXPECTED_TOKEN + else if (aException is EengInvalidToken) then + LastErrorCode := LSF_ERR_INVALID_TOKEN + else if (aException is EengExpressionInternal) then + LastErrorCode := LSF_ERR_EXPRESSION_INTERNAL + else if (aException is EengExpression) then + LastErrorCode := LSF_ERR_EXPRESSION + else if (aException is EengShaderPartInternal) then + LastErrorCode := LSF_ERR_SHADER_PART_INTERNAL + else if (aException is EengShaderPart ) then + LastErrorCode := LSF_ERR_SHADER_PART + else + LastErrorCode := LSF_ERR_UNKNOWN; + if (aException is EengShaderPart) + then LastErrorTrace := (aException as EengShaderPart).PrintTrace + else LastErrorTrace := ''; + LastErrorMsg := aException.Message; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function CheckIfInitialized: Boolean; +begin + try + result := Assigned(ShaderFiles); + if not result then + SetLastError(LSf_ERR_NOT_INIT, 'libShaderFile has not been initialized. call esf_init before using any other methods.'); + except + on e: Exception do begin + SetLastError(e); + result := false; + end; + end; +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', [PtrUInt(aHandle)])); + end; + except + on e: Exception do begin + SetLastError(e); + result := false; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//ShaderFile//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function lsf_ShaderFile_create: TlsfShaderFileHandle; stdcall; +begin + try + result := nil; + if not CheckIfInitialized then + exit; + result := TengShaderFile.Create; + ShaderFiles.Add(TShaderFile(result)); + except + on e: Exception do begin + SetLastError(e); + result := nil; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function lsf_ShaderFile_setLogCallback(const aHandle: TlsfShaderFileHandle; const aCallback: TlsfShaderFileLogEvent): TlsfErrorCode; stdcall; +begin + try + result := LSF_ERR_NONE; + if not CheckShaderFileHandle(aHandle) + then result := LastErrorCode + else TShaderFile(aHandle).LogCallback := aCallback; + except + on e: Exception do begin + SetLastError(e); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function lsf_ShaderFile_loadFromFile(const aHandle: TlsfShaderFileHandle; const aFilename: PAnsiChar): TlsfErrorCode; stdcall; +begin + try + result := LSF_ERR_NONE; + if not CheckShaderFileHandle(aHandle) + then result := LastErrorCode + else TShaderFile(aHandle).LoadFromFile(aFilename); + 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 + try + result := LSF_ERR_NONE; + if not CheckShaderFileHandle(aHandle) + then result := LastErrorCode + else TShaderFile(aHandle).SaveToFile(aFilename); + except + on e: Exception do begin + SetLastError(e); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function lsf_ShaderFile_destroy(const aHandle: TlsfShaderFileHandle): TlsfErrorCode; stdcall; +begin + try + result := LSF_ERR_NONE; + if not CheckShaderFileHandle(aHandle) + then result := LastErrorCode + else ShaderFiles.Remove(TShaderFile(aHandle)); + except + on e: Exception do begin + SetLastError(e); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//Global//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function lsf_init: TlsfErrorCode; stdcall; +begin + try + result := LSF_ERR_NONE; + ShaderFiles := TengShaderFiles.Create(true); + except + on e: Exception do begin + SetLastError(e); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function lsf_getLastErrorCode: TlsfErrorCode; stdcall; +begin + result := LastErrorCode; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function lsf_getLastErrorMsg: PAnsiChar; stdcall; +begin + result := PAnsiChar(LastErrorMsg); +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function lsf_getLastErrorTrace: PAnsiChar; stdcall; +begin + result := PAnsiChar(LastErrorTrace); +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function lsf_finish: TlsfErrorCode; stdcall; +begin + try + result := LSF_ERR_NONE; + FreeAndNil(ShaderFiles); + except + on e: Exception do begin + SetLastError(e); + result := LastErrorCode; + end; + end; +end; + +exports + lsf_ShaderFile_create, + lsf_ShaderFile_setLogCallback, + lsf_ShaderFile_loadFromFile, + lsf_ShaderFile_saveToFile, + lsf_ShaderFile_destroy, + + lsf_init, + lsf_getLastErrorCode, + lsf_getLastErrorMsg, + lsf_getLastErrorTrace, + lsf_finish; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//TShaderFile/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TShaderFile.LogMsgIntern(const aSender: TengShaderPart; const aLogLevel: TengShaderPartLogLevel; const aMsg: String); +var + tmp: TlsfShaderFileLogEvent; +begin + inherited LogMsgIntern(aSender, aLogLevel, aMsg); + tmp := fLogCallback; + if Assigned(tmp) then + tmp(Cardinal(aLogLevel), PAnsiChar(aMsg)); +end; + +end.