選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

299 行
12 KiB

  1. library libShaderFile;
  2. {$mode objfpc}{$H+}
  3. uses
  4. SysUtils,
  5. uengShaderFile, uengShaderPart, uengShaderFileGenerics, uengShaderFileTypes;
  6. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7. //external types and contstants/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  8. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  9. const
  10. LSF_LOGLEVEL_DEBUG = llDebug;
  11. LSF_LOGLEVEL_INFO = llInfo;
  12. LSF_LOGLEVEL_WARNING = llWarning;
  13. LSF_LOGLEVEL_ERROR = llError;
  14. LSF_ERR_NONE = $00000000;
  15. LSF_ERR_NOT_INIT = $00000001;
  16. LSF_ERR_INVALID_HANDLE_SHADER_FILE = $00000002;
  17. LSF_ERR_UNKNOWN_IDENTFIFIER = $00001000;
  18. LSF_ERR_DUPLICATE_IDENTIFIER = $00001001;
  19. LSF_ERR_OUT_OF_RANGE = $00001002;
  20. LSF_ERR_INVALID_IDENTIFIER = $00001003;
  21. LSF_ERR_INVALID_PARAMTER_COUNT = $00001004;
  22. LSF_ERR_INVALID_PARAMTER = $00001005;
  23. LSF_ERR_UNEXPECTED_TOKEN = $00001006;
  24. LSF_ERR_INVALID_TOKEN = $00001007;
  25. LSF_ERR_EXPRESSION_INTERNAL = $00001008;
  26. LSF_ERR_EXPRESSION = $00001009;
  27. LSF_ERR_SHADER_PART_INTERNAL = $0000100A;
  28. LSF_ERR_SHADER_PART = $0000100B;
  29. LSF_ERR_UNKNOWN = $FFFFFFFF;
  30. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  31. type
  32. TlsfErrorCode = Cardinal;
  33. TlsfLogLevel = Cardinal;
  34. TlsfShaderFileHandle = Pointer;
  35. TlsfShaderFileLogEvent = procedure(const aLogLevel: TlsfLogLevel; const aMsg: PAnsiChar);
  36. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  37. //internal types and contstants/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  38. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  39. type
  40. TShaderFile = class(TengShaderFile)
  41. private
  42. fLogCallback: TlsfShaderFileLogEvent;
  43. protected
  44. procedure LogMsgIntern(const aSender: TengShaderPart; const aLogLevel: TengShaderPartLogLevel; const aMsg: String); override;
  45. public
  46. property LogCallback: TlsfShaderFileLogEvent read fLogCallback write fLogCallback;
  47. end;
  48. TengShaderFiles = specialize TutlHashSet<TShaderFile>;
  49. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  50. var
  51. ShaderFiles: TengShaderFiles = nil;
  52. LastErrorCode: TlsfErrorCode = LSF_ERR_NONE;
  53. LastErrorMsg: String = '';
  54. LastErrorTrace: String = '';
  55. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  56. //Misc (not exportet)///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  57. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  58. procedure SetLastError(const aErrorCode: TlsfErrorCode; const aMsg: String);
  59. begin
  60. LastErrorCode := aErrorCode;
  61. LastErrorMsg := aMsg;
  62. LastErrorTrace := '';
  63. end;
  64. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  65. procedure SetLastError(const aException: Exception);
  66. begin
  67. if (aException is EengUnknownIdentifier) then
  68. LastErrorCode := LSF_ERR_UNKNOWN_IDENTFIFIER
  69. else if (aException is EengDuplicateIdentifier) then
  70. LastErrorCode := LSF_ERR_DUPLICATE_IDENTIFIER
  71. else if (aException is EengOutOfRange) then
  72. LastErrorCode := LSF_ERR_OUT_OF_RANGE
  73. else if (aException is EengInvalidIdentifier) then
  74. LastErrorCode := LSF_ERR_INVALID_IDENTIFIER
  75. else if (aException is EengInvalidParamterCount) then
  76. LastErrorCode := LSF_ERR_INVALID_PARAMTER_COUNT
  77. else if (aException is EengInvalidParamter) then
  78. LastErrorCode := LSF_ERR_INVALID_PARAMTER
  79. else if (aException is EengUnexpectedToken) then
  80. LastErrorCode := LSF_ERR_UNEXPECTED_TOKEN
  81. else if (aException is EengInvalidToken) then
  82. LastErrorCode := LSF_ERR_INVALID_TOKEN
  83. else if (aException is EengExpressionInternal) then
  84. LastErrorCode := LSF_ERR_EXPRESSION_INTERNAL
  85. else if (aException is EengExpression) then
  86. LastErrorCode := LSF_ERR_EXPRESSION
  87. else if (aException is EengShaderPartInternal) then
  88. LastErrorCode := LSF_ERR_SHADER_PART_INTERNAL
  89. else if (aException is EengShaderPart ) then
  90. LastErrorCode := LSF_ERR_SHADER_PART
  91. else
  92. LastErrorCode := LSF_ERR_UNKNOWN;
  93. if (aException is EengShaderPart)
  94. then LastErrorTrace := (aException as EengShaderPart).PrintTrace
  95. else LastErrorTrace := '';
  96. LastErrorMsg := aException.Message;
  97. end;
  98. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  99. function CheckIfInitialized: Boolean;
  100. begin
  101. try
  102. result := Assigned(ShaderFiles);
  103. if not result then
  104. SetLastError(LSf_ERR_NOT_INIT, 'libShaderFile has not been initialized. call esf_init before using any other methods.');
  105. except
  106. on e: Exception do begin
  107. SetLastError(e);
  108. result := false;
  109. end;
  110. end;
  111. end;
  112. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  113. function CheckShaderFileHandle(const aHandle: TlsfShaderFileHandle): Boolean;
  114. begin
  115. try
  116. result := CheckIfInitialized;
  117. if result then begin
  118. result := ShaderFiles.Contains(TShaderFile(aHandle));
  119. if not result then
  120. SetLastError(LSF_ERR_INVALID_HANDLE_SHADER_FILE, Format('0x%x is not a valid shader file handle', [PtrUInt(aHandle)]));
  121. end;
  122. except
  123. on e: Exception do begin
  124. SetLastError(e);
  125. result := false;
  126. end;
  127. end;
  128. end;
  129. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  130. //ShaderFile////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  131. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  132. function lsf_ShaderFile_create: TlsfShaderFileHandle; stdcall;
  133. begin
  134. try
  135. result := nil;
  136. if not CheckIfInitialized then
  137. exit;
  138. result := TengShaderFile.Create;
  139. ShaderFiles.Add(TShaderFile(result));
  140. except
  141. on e: Exception do begin
  142. SetLastError(e);
  143. result := nil;
  144. end;
  145. end;
  146. end;
  147. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  148. function lsf_ShaderFile_setLogCallback(const aHandle: TlsfShaderFileHandle; const aCallback: TlsfShaderFileLogEvent): TlsfErrorCode; stdcall;
  149. begin
  150. try
  151. result := LSF_ERR_NONE;
  152. if not CheckShaderFileHandle(aHandle)
  153. then result := LastErrorCode
  154. else TShaderFile(aHandle).LogCallback := aCallback;
  155. except
  156. on e: Exception do begin
  157. SetLastError(e);
  158. result := LastErrorCode;
  159. end;
  160. end;
  161. end;
  162. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  163. function lsf_ShaderFile_loadFromFile(const aHandle: TlsfShaderFileHandle; const aFilename: PAnsiChar): TlsfErrorCode; stdcall;
  164. begin
  165. try
  166. result := LSF_ERR_NONE;
  167. if not CheckShaderFileHandle(aHandle)
  168. then result := LastErrorCode
  169. else TShaderFile(aHandle).LoadFromFile(aFilename);
  170. except
  171. on e: Exception do begin
  172. SetLastError(e);
  173. result := LastErrorCode;
  174. end;
  175. end;
  176. end;
  177. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  178. function lsf_ShaderFile_saveToFile(const aHandle: TlsfShaderFileHandle; const aFilename: PAnsiChar): TlsfErrorCode; stdcall;
  179. begin
  180. try
  181. result := LSF_ERR_NONE;
  182. if not CheckShaderFileHandle(aHandle)
  183. then result := LastErrorCode
  184. else TShaderFile(aHandle).SaveToFile(aFilename);
  185. except
  186. on e: Exception do begin
  187. SetLastError(e);
  188. result := LastErrorCode;
  189. end;
  190. end;
  191. end;
  192. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  193. function lsf_ShaderFile_destroy(const aHandle: TlsfShaderFileHandle): TlsfErrorCode; stdcall;
  194. begin
  195. try
  196. result := LSF_ERR_NONE;
  197. if not CheckShaderFileHandle(aHandle)
  198. then result := LastErrorCode
  199. else ShaderFiles.Remove(TShaderFile(aHandle));
  200. except
  201. on e: Exception do begin
  202. SetLastError(e);
  203. result := LastErrorCode;
  204. end;
  205. end;
  206. end;
  207. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  208. //Global////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  209. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  210. function lsf_init: TlsfErrorCode; stdcall;
  211. begin
  212. try
  213. result := LSF_ERR_NONE;
  214. ShaderFiles := TengShaderFiles.Create(true);
  215. except
  216. on e: Exception do begin
  217. SetLastError(e);
  218. result := LastErrorCode;
  219. end;
  220. end;
  221. end;
  222. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  223. function lsf_getLastErrorCode: TlsfErrorCode; stdcall;
  224. begin
  225. result := LastErrorCode;
  226. end;
  227. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  228. function lsf_getLastErrorMsg: PAnsiChar; stdcall;
  229. begin
  230. result := PAnsiChar(LastErrorMsg);
  231. end;
  232. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  233. function lsf_getLastErrorTrace: PAnsiChar; stdcall;
  234. begin
  235. result := PAnsiChar(LastErrorTrace);
  236. end;
  237. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  238. function lsf_finish: TlsfErrorCode; stdcall;
  239. begin
  240. try
  241. result := LSF_ERR_NONE;
  242. FreeAndNil(ShaderFiles);
  243. except
  244. on e: Exception do begin
  245. SetLastError(e);
  246. result := LastErrorCode;
  247. end;
  248. end;
  249. end;
  250. exports
  251. lsf_ShaderFile_create,
  252. lsf_ShaderFile_setLogCallback,
  253. lsf_ShaderFile_loadFromFile,
  254. lsf_ShaderFile_saveToFile,
  255. lsf_ShaderFile_destroy,
  256. lsf_init,
  257. lsf_getLastErrorCode,
  258. lsf_getLastErrorMsg,
  259. lsf_getLastErrorTrace,
  260. lsf_finish;
  261. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  262. //TShaderFile///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  263. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  264. procedure TShaderFile.LogMsgIntern(const aSender: TengShaderPart; const aLogLevel: TengShaderPartLogLevel; const aMsg: String);
  265. var
  266. tmp: TlsfShaderFileLogEvent;
  267. begin
  268. inherited LogMsgIntern(aSender, aLogLevel, aMsg);
  269. tmp := fLogCallback;
  270. if Assigned(tmp) then
  271. tmp(Cardinal(aLogLevel), PAnsiChar(aMsg));
  272. end;
  273. end.