Implemented basis for Lua scripting and registering FSX variables - incomplete and crashes on shutdown
This commit is contained in:
parent
b0613d6f5b
commit
54e7e36ee9
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
__history
|
||||
*.local
|
||||
*.dcu
|
||||
*.exe
|
||||
*.identcache
|
BIN
G940LEDControl/Bin/lua52.dll
Normal file
BIN
G940LEDControl/Bin/lua52.dll
Normal file
Binary file not shown.
767
G940LEDControl/DelphiLua/Lua.API.pas
Normal file
767
G940LEDControl/DelphiLua/Lua.API.pas
Normal file
@ -0,0 +1,767 @@
|
||||
{
|
||||
Header for Lua 5.2.1 Binaries DLL
|
||||
http://luabinaries.sourceforge.net/
|
||||
|
||||
Delphi conversion by M. van Renswoude, April 2014:
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
}
|
||||
unit Lua.API;
|
||||
|
||||
interface
|
||||
uses
|
||||
System.SysUtils;
|
||||
|
||||
|
||||
const
|
||||
LUA_VERSION_MAJOR = '5';
|
||||
LUA_VERSION_MINOR = '2';
|
||||
LUA_VERSION_NUM = 502;
|
||||
LUA_VERSION_RELEASE = '1';
|
||||
|
||||
LUA_VERSION_ = 'Lua ' + LUA_VERSION_MAJOR + '.' + LUA_VERSION_MINOR;
|
||||
LUA_RELEASE = LUA_VERSION_ + '.' + LUA_VERSION_RELEASE;
|
||||
LUA_COPYRIGHT = LUA_RELEASE + ' Copyright (C) 1994-2012 Lua.org, PUC-Rio';
|
||||
LUA_AUTHORS = 'R. Ierusalimschy, L. H. de Figueiredo, W. Celes';
|
||||
|
||||
|
||||
{ mark for precompiled code ('<esc>Lua') }
|
||||
LUA_SIGNATURE = #33'Lua';
|
||||
|
||||
{ option for multiple returns in 'lua_pcall' and 'lua_call' }
|
||||
LUA_MULTRET = -1;
|
||||
|
||||
{ reserve some space for error handling }
|
||||
LUAI_MAXSTACK = 1000000;
|
||||
LUAI_FIRSTPSEUDOIDX = (-LUAI_MAXSTACK - 1000);
|
||||
|
||||
{ pseudo-indices }
|
||||
LUA_REGISTRYINDEX = LUAI_FIRSTPSEUDOIDX;
|
||||
|
||||
function lua_upvalueindex(idx: Integer): Integer; inline;
|
||||
|
||||
const
|
||||
{ thread status }
|
||||
LUA_OK = 0;
|
||||
LUA_YIELD_ = 1;
|
||||
LUA_ERRRUN = 2;
|
||||
LUA_ERRSYNTAX = 3;
|
||||
LUA_ERRMEM = 4;
|
||||
LUA_ERRGCMM = 5;
|
||||
LUA_ERRERR = 6;
|
||||
|
||||
|
||||
type
|
||||
size_t = NativeUint;
|
||||
psize_t = ^size_t;
|
||||
|
||||
lua_State = type Pointer;
|
||||
lua_CFunction = function(L: lua_State): Integer; cdecl;
|
||||
|
||||
{ functions that read/write blocks when loading/dumping Lua chunks }
|
||||
lua_Reader = function(L: lua_State; ud: Pointer; var sz: size_t): PAnsiChar; cdecl;
|
||||
lua_Writer = function(L: lua_State; p: Pointer; sz: size_t; ud: Pointer): Integer; cdecl;
|
||||
|
||||
{ prototype for memory-allocation functions }
|
||||
lua_Alloc = function(ud, ptr: Pointer; osize, nsize: size_t): Pointer; cdecl;
|
||||
|
||||
const
|
||||
{ basic types }
|
||||
LUA_TNONE = (-1);
|
||||
|
||||
LUA_TNIL = 0;
|
||||
LUA_TBOOLEAN = 1;
|
||||
LUA_TLIGHTUSERDATA = 2;
|
||||
LUA_TNUMBER = 3;
|
||||
LUA_TSTRING = 4;
|
||||
LUA_TTABLE = 5;
|
||||
LUA_TFUNCTION = 6;
|
||||
LUA_TUSERDATA = 7;
|
||||
LUA_TTHREAD = 8;
|
||||
|
||||
LUA_NUMTAGS = 9;
|
||||
|
||||
{ minimum Lua stack available to a C function }
|
||||
LUA_MINSTACK = 20;
|
||||
|
||||
|
||||
{ predefined values in the registry }
|
||||
LUA_RIDX_MAINTHREAD = 1;
|
||||
LUA_RIDX_GLOBALS = 2;
|
||||
LUA_RIDX_LAST = LUA_RIDX_GLOBALS;
|
||||
|
||||
|
||||
type
|
||||
{ type of numbers in Lua }
|
||||
lua_Number = type Double;
|
||||
|
||||
{ type for integer functions }
|
||||
lua_Integer = type Integer;
|
||||
|
||||
{ unsigned integer type }
|
||||
lua_Unsigned = type Cardinal;
|
||||
|
||||
|
||||
var
|
||||
{ state manipulation }
|
||||
lua_newstate: function(f: lua_Alloc; ud: Pointer): lua_State; cdecl;
|
||||
lua_close: procedure(L: lua_State); cdecl;
|
||||
lua_newthread: function(L: lua_State): lua_State; cdecl;
|
||||
|
||||
lua_atpanic: function(L: lua_State; panicf: lua_CFunction): lua_CFunction; cdecl;
|
||||
lua_version: function(L: lua_State): lua_Number; cdecl;
|
||||
|
||||
{ basic stack manipulation }
|
||||
lua_absindex: function(L: lua_State; idx: Integer): Integer; cdecl;
|
||||
lua_gettop: function(L: lua_State): Integer; cdecl;
|
||||
|
||||
lua_settop: procedure(L: lua_State; idx: Integer); cdecl;
|
||||
lua_pushvalue: procedure(L: lua_State; idx: Integer); cdecl;
|
||||
lua_remove: procedure(L: lua_State; idx: Integer); cdecl;
|
||||
lua_insert: procedure(L: lua_State; idx: Integer); cdecl;
|
||||
lua_replace: procedure(L: lua_State; idx: Integer); cdecl;
|
||||
lua_copy: procedure(L: lua_State; fromidx, toidx: Integer); cdecl;
|
||||
lua_checkstack: function(L: lua_State; sz: Integer): Integer; cdecl;
|
||||
|
||||
lua_xmove: procedure(from: lua_State; _to: lua_State; n: Integer); cdecl;
|
||||
|
||||
{ access functions (stack -> C) }
|
||||
lua_isnumber: function (L: lua_State; idx: Integer): Integer; cdecl;
|
||||
lua_isstring: function (L: lua_State; idx: Integer): Integer; cdecl;
|
||||
lua_iscfunction: function (L: lua_State; idx: Integer): Integer; cdecl;
|
||||
lua_isuserdata: function (L: lua_State; idx: Integer): Integer; cdecl;
|
||||
lua_type: function (L: lua_State; idx: Integer): Integer; cdecl;
|
||||
lua_typename: function (L: lua_State; tp: Integer): PAnsiChar; cdecl;
|
||||
lua_tonumberx: function (L: lua_State; idx: Integer; isnum: PInteger): lua_Number; cdecl;
|
||||
lua_tointegerx: function (L: lua_State; idx: Integer; isnum: PInteger): lua_Integer; cdecl;
|
||||
lua_tounsignedx: function (L: lua_State; idx: Integer; isnum: PInteger): lua_Unsigned; cdecl;
|
||||
lua_toboolean: function (L: lua_State; idx: Integer): Integer; cdecl;
|
||||
lua_tolstring: function(L: lua_State; idx: Integer; len: psize_t): PAnsiChar; cdecl;
|
||||
lua_rawlen: function (L: lua_State; idx: Integer): size_t; cdecl;
|
||||
lua_tocfunction: function (L: lua_State; idx: Integer): lua_CFunction; cdecl;
|
||||
lua_touserdata: function (L: lua_State; idx: Integer): Pointer; cdecl;
|
||||
lua_tothread: function (L: lua_State; idx: Integer): lua_State; cdecl;
|
||||
lua_topointer: function (L: lua_State; idx: Integer): Pointer; cdecl;
|
||||
|
||||
|
||||
const
|
||||
{ Comparison and arithmetic functions }
|
||||
LUA_OPADD = 0; { ORDER TM }
|
||||
LUA_OPSUB = 1;
|
||||
LUA_OPMUL = 2;
|
||||
LUA_OPDIV = 3;
|
||||
LUA_OPMOD = 4;
|
||||
LUA_OPPOW = 5;
|
||||
LUA_OPUNM = 6;
|
||||
|
||||
|
||||
var
|
||||
lua_arith: procedure(L: lua_State; op: Integer); cdecl;
|
||||
|
||||
|
||||
const
|
||||
LUA_OPEQ = 0;
|
||||
LUA_OPLT = 1;
|
||||
LUA_OPLE = 2;
|
||||
|
||||
|
||||
var
|
||||
lua_rawequal: function(L: lua_State; idx1, idx2: Integer): Integer; cdecl;
|
||||
lua_compare: function(L: lua_State; idx1, idx2, op: Integer): Integer; cdecl;
|
||||
|
||||
|
||||
{ push functions (C -> stack) }
|
||||
lua_pushnil: procedure(L: lua_State); cdecl;
|
||||
lua_pushnumber: procedure(L: lua_State; n: lua_Number); cdecl;
|
||||
lua_pushinteger: procedure(L: lua_State; n: lua_Integer); cdecl;
|
||||
lua_pushunsigned: procedure(L: lua_State; n: lua_Unsigned); cdecl;
|
||||
lua_pushlstring: function (L: lua_State; s: PAnsiChar; l_: size_t): PAnsiChar; cdecl;
|
||||
lua_pushstring: function (L: lua_State; s: PAnsiChar): PAnsiChar; cdecl;
|
||||
lua_pushvfstring: function (L: lua_State; fmt: PAnsiChar; argp: Pointer): PAnsiChar; cdecl;
|
||||
lua_pushfstring: function (L: lua_State; fmt: PAnsiChar; argp: Pointer): PAnsiChar; cdecl;
|
||||
lua_pushcclosure: procedure(L: lua_State; fn: lua_CFunction; n: Integer); cdecl;
|
||||
lua_pushboolean: procedure(L: lua_State; b: Integer); cdecl;
|
||||
lua_pushlightuserdata: procedure(L: lua_State; p: Pointer); cdecl;
|
||||
lua_pushthread: function (L: lua_State): Integer; cdecl;
|
||||
|
||||
{ get functions (Lua -> stack) }
|
||||
lua_getglobal: procedure(L: lua_State; value: PAnsiChar); cdecl;
|
||||
lua_gettable: procedure(L: lua_State; idx: Integer); cdecl;
|
||||
lua_getfield: procedure(L: lua_State; idx: Integer; k: PAnsiChar); cdecl;
|
||||
lua_rawget: procedure(L: lua_State; idx: Integer); cdecl;
|
||||
lua_rawgeti: procedure(L: lua_State; idx, n: Integer); cdecl;
|
||||
lua_rawgetp: procedure(L: lua_State; idx: Integer; p: Pointer); cdecl;
|
||||
lua_createtable: procedure(L: lua_State; narr: Integer; nrec: Integer); cdecl;
|
||||
lua_newuserdata: procedure(L: lua_State; sz: size_t); cdecl;
|
||||
lua_getmetatable: function(L: lua_State; objindex: Integer): Integer; cdecl;
|
||||
lua_getuservalue: procedure(L: lua_State; idx: Integer); cdecl;
|
||||
|
||||
{ set functions (stack -> Lua) }
|
||||
lua_setglobal: procedure(L: lua_State; value: PAnsiChar); cdecl;
|
||||
lua_settable: procedure(L: lua_State; idx: Integer); cdecl;
|
||||
lua_setfield: procedure(L: lua_State; idx: Integer; k: PAnsiChar); cdecl;
|
||||
lua_rawset: procedure(L: lua_State; idx: Integer); cdecl;
|
||||
lua_rawseti: procedure(L: lua_State; idx, n: Integer); cdecl;
|
||||
lua_rawsetp: procedure(L: lua_State; idx: Integer; p: Pointer); cdecl;
|
||||
lua_setmetatable: function(L: lua_State; objindex: Integer): Integer; cdecl;
|
||||
lua_setuservalue: procedure(L: lua_State; idx: Integer); cdecl;
|
||||
|
||||
|
||||
{ 'load' and 'call' functions (load and run Lua code) }
|
||||
lua_callk: procedure(L: lua_State; nargs, nresults, ctx: Integer; k: lua_CFunction); cdecl;
|
||||
lua_getctx: function(L: lua_State; var ctx: Integer): Integer; cdecl;
|
||||
lua_pcallk: function(L: lua_State; nargs, nresults, errfunc, ctx: Integer; k: lua_CFunction): Integer; cdecl;
|
||||
|
||||
lua_load: function(L: lua_State; reader: lua_Reader; dt: Pointer; chunkname, mode: PAnsiChar): Integer; cdecl;
|
||||
lua_dump: function(L: lua_State; writer: lua_Writer; data: Pointer): Integer; cdecl;
|
||||
|
||||
|
||||
procedure lua_call(L: lua_State; nargs, nresults: Integer); inline;
|
||||
function lua_pcall(L: lua_State; nargs, nresults, errfunc: Integer): Integer; inline;
|
||||
|
||||
|
||||
var
|
||||
{ coroutine functions }
|
||||
lua_yieldk: function(L: lua_State; nresults, ctx: Integer; k: lua_CFunction): Integer; cdecl;
|
||||
lua_resume: function(L, from: lua_State; nargs: Integer): Integer; cdecl;
|
||||
lua_status: function(L: lua_State): Integer; cdecl;
|
||||
|
||||
function lua_yield(L: lua_State; nresults: Integer): Integer; inline;
|
||||
|
||||
|
||||
const
|
||||
{ garbage-collection function and options }
|
||||
LUA_GCSTOP = 0;
|
||||
LUA_GCRESTART = 1;
|
||||
LUA_GCCOLLECT = 2;
|
||||
LUA_GCCOUNT = 3;
|
||||
LUA_GCCOUNTB = 4;
|
||||
LUA_GCSTEP = 5;
|
||||
LUA_GCSETPAUSE = 6;
|
||||
LUA_GCSETSTEPMU = 7;
|
||||
LUA_GCSETMAJORIN = 8;
|
||||
LUA_GCISRUNNING = 9;
|
||||
LUA_GCGEN = 0;
|
||||
LUA_GCINC = 1;
|
||||
|
||||
var
|
||||
lua_gc: function(L: lua_State; what, data: Integer): Integer; cdecl;
|
||||
|
||||
|
||||
var
|
||||
{ miscellaneous functions }
|
||||
lua_error: function(L: lua_State): Integer; cdecl;
|
||||
lua_next: function(L: lua_State; idx: Integer): Integer; cdecl;
|
||||
|
||||
lua_concat: procedure(L: lua_State; n: Integer); cdecl;
|
||||
lua_len: procedure(L: lua_State; idx: Integer); cdecl;
|
||||
|
||||
lua_getallocf: function(L: lua_State; ud: Pointer): lua_Alloc; cdecl;
|
||||
lua_setallocf: procedure(L: lua_State; f: lua_Alloc; ud: Pointer); cdecl;
|
||||
|
||||
|
||||
{ some useful macros }
|
||||
function lua_tonumber(L: lua_State; idx: Integer): lua_Number; inline;
|
||||
function lua_tointeger(L: lua_State; idx: Integer): lua_Integer; inline;
|
||||
function lua_tounsigned(L: lua_State; idx: Integer): lua_Unsigned; inline;
|
||||
|
||||
procedure lua_pop(L: lua_State; n: Integer); inline;
|
||||
procedure lua_newtable(L: lua_State); inline;
|
||||
procedure lua_register(L: lua_State; name: PAnsiChar; f: lua_CFunction); inline;
|
||||
procedure lua_pushcfunction(L: lua_State; f: lua_CFunction); inline;
|
||||
|
||||
function lua_isfunction(L: lua_State; n: Integer): Boolean; inline;
|
||||
function lua_istable(L: lua_State; n: Integer): Boolean; inline;
|
||||
function lua_islightuserdata(L: lua_State; n: Integer): Boolean; inline;
|
||||
function lua_isnil(L: lua_State; n: Integer): Boolean; inline;
|
||||
function lua_isboolean(L: lua_State; n: Integer): Boolean; inline;
|
||||
function lua_isthread(L: lua_State; n: Integer): Boolean; inline;
|
||||
function lua_isnone(L: lua_State; n: Integer): Boolean; inline;
|
||||
function lua_isnoneornil(L: lua_State; n: Integer): Boolean; inline;
|
||||
function lua_pushliteral(L: lua_State; const s: AnsiString): PAnsiChar; inline;
|
||||
|
||||
procedure lua_pushglobaltable(L: lua_State); inline;
|
||||
function lua_tostring(L: lua_State; idx: Integer): PAnsiChar; inline;
|
||||
|
||||
|
||||
const
|
||||
{======================================================================
|
||||
Debug API
|
||||
=======================================================================}
|
||||
|
||||
{ Event codes }
|
||||
LUA_HOOKCALL = 0;
|
||||
LUA_HOOKRET = 1;
|
||||
LUA_HOOKLINE = 2;
|
||||
LUA_HOOKCOUNT = 3;
|
||||
LUA_HOOKTAILCALL = 4;
|
||||
|
||||
|
||||
{ Event masks }
|
||||
LUA_MASKCALL = (1 shl LUA_HOOKCALL);
|
||||
LUA_MASKRET = (1 shl LUA_HOOKRET);
|
||||
LUA_MASKLINE = (1 shl LUA_HOOKLINE);
|
||||
LUA_MASKCOUNT = (1 shl LUA_HOOKCOUNT);
|
||||
|
||||
|
||||
const
|
||||
LUA_IDSIZE = 60;
|
||||
|
||||
|
||||
type
|
||||
lua_Debug = record
|
||||
event: Integer;
|
||||
name: PAnsiChar;
|
||||
namewhat: PAnsiChar; // 'global', 'local', 'field', 'method'
|
||||
what: PAnsiChar; // 'Lua', 'C', 'main', 'tail'
|
||||
source: PAnsiChar;
|
||||
currentline: Integer;
|
||||
linedefined: Integer;
|
||||
lastlinedefined: Integer;
|
||||
nups: Byte;
|
||||
nparams: Byte;
|
||||
isvararg: Byte;
|
||||
istailcall: Byte;
|
||||
short_src: array[0..LUA_IDSIZE - 1] of AnsiChar;
|
||||
//struct CallInfo *i_ci; /* active function */
|
||||
end;
|
||||
|
||||
{ Functions to be called by the debugger in specific events }
|
||||
lua_Hook = procedure(L: lua_State; var ar: lua_Debug); cdecl;
|
||||
|
||||
|
||||
var
|
||||
lua_getstack: function(L: lua_State; level: Integer; var ar: lua_Debug): Integer; cdecl;
|
||||
lua_getinfo: function(L: lua_State; what: PAnsiChar; var ar: lua_Debug): Integer; cdecl;
|
||||
|
||||
lua_getlocal: function(L: lua_State; var ar: lua_Debug; n: Integer): PAnsiChar; cdecl;
|
||||
lua_setlocal: function(L: lua_State; var ar: lua_Debug; n: Integer): PAnsiChar; cdecl;
|
||||
lua_getupvalue: function(L: lua_State; funcindex, n: Integer): PAnsiChar; cdecl;
|
||||
lua_setupvalue: function(L: lua_State; funcindex, n: Integer): PAnsiChar; cdecl;
|
||||
|
||||
lua_upvalueid: function(L: lua_State; fidx, n: Integer): Pointer; cdecl;
|
||||
lua_upvaluejoin: procedure(L: lua_State; fidx1, n1, fidx2, n2: Integer);
|
||||
|
||||
lua_sethook: function(L: lua_State; func: lua_Hook; mask, count: Integer): Integer; cdecl;
|
||||
lua_gethook: function(L: lua_State): lua_Hook; cdecl;
|
||||
lua_gethookmask: function(L: lua_State): Integer; cdecl;
|
||||
lua_gethookcount: function(L: lua_State): Integer; cdecl;
|
||||
|
||||
{====================================================================== }
|
||||
|
||||
|
||||
const
|
||||
LUA_COLIBNAME = 'coroutine';
|
||||
LUA_TABLIBNAME = 'table';
|
||||
LUA_IOLIBNAME = 'io';
|
||||
LUA_OSLIBNAME = 'os';
|
||||
LUA_STRLIBNAME = 'string';
|
||||
LUA_BITLIBNAME = 'bit32';
|
||||
LUA_MATHLIBNAME = 'math';
|
||||
LUA_DBLIBNAME = 'debug';
|
||||
LUA_LOADLIBNAME = 'package';
|
||||
|
||||
|
||||
var
|
||||
{ lualib }
|
||||
luaopen_base: function(L: lua_State): Integer; cdecl;
|
||||
luaopen_coroutine: function(L: lua_State): Integer; cdecl;
|
||||
luaopen_table: function(L: lua_State): Integer; cdecl;
|
||||
luaopen_io: function(L: lua_State): Integer; cdecl;
|
||||
luaopen_os: function(L: lua_State): Integer; cdecl;
|
||||
luaopen_string: function(L: lua_State): Integer; cdecl;
|
||||
luaopen_bit32: function(L: lua_State): Integer; cdecl;
|
||||
luaopen_math: function(L: lua_State): Integer; cdecl;
|
||||
luaopen_debug: function(L: lua_State): Integer; cdecl;
|
||||
luaopen_package: function(L: lua_State): Integer; cdecl;
|
||||
|
||||
{ open all previous libraries }
|
||||
luaL_openlibs: procedure(L: lua_State); cdecl;
|
||||
luaL_requiref: procedure(L: lua_State; modname: PAnsiChar; openf: lua_CFunction; glb: Integer); cdecl;
|
||||
|
||||
|
||||
|
||||
type
|
||||
luaL_Reg = record
|
||||
name: PAnsiChar;
|
||||
func: lua_CFunction;
|
||||
end;
|
||||
PluaL_Reg = ^luaL_Reg;
|
||||
|
||||
var
|
||||
luaL_setfuncs: procedure(L: lua_State; luaL_Reg: PluaL_Reg; nup: Integer); cdecl;
|
||||
|
||||
procedure luaL_where(L: lua_State; level: Integer);
|
||||
function luaL_error(L: lua_State; fmt: PAnsiChar; argp: Pointer): Integer;
|
||||
|
||||
|
||||
|
||||
const
|
||||
DefaultLuaLibName = 'lua' + LUA_VERSION_MAJOR + LUA_VERSION_MINOR + '.dll';
|
||||
|
||||
procedure LoadLuaLib(const AFileName: string = DefaultLuaLibName);
|
||||
procedure UnloadLuaLib;
|
||||
|
||||
function LuaLibLoaded: Boolean;
|
||||
|
||||
function DefaultLuaAlloc(ud, ptr: Pointer; osize, nsize: size_t): Pointer; cdecl;
|
||||
|
||||
|
||||
implementation
|
||||
uses
|
||||
System.Generics.Collections,
|
||||
Winapi.Windows;
|
||||
|
||||
var
|
||||
LuaLibHandle: THandle;
|
||||
LuaFunctions: TList<PPointer>;
|
||||
|
||||
|
||||
function DefaultLuaAlloc(ud, ptr: Pointer; osize, nsize: size_t): Pointer;
|
||||
begin
|
||||
if (nsize = 0) then
|
||||
begin
|
||||
FreeMemory(ptr);
|
||||
Result := nil;
|
||||
end else
|
||||
Result := ReallocMemory(ptr, nsize);
|
||||
end;
|
||||
|
||||
|
||||
procedure LoadLuaLib(const AFileName: string = DefaultLuaLibName);
|
||||
|
||||
procedure Load(var AVariable: Pointer; const AName: string);
|
||||
begin
|
||||
AVariable := GetProcAddress(LuaLibHandle, PChar(AName));
|
||||
LuaFunctions.Add(@AVariable);
|
||||
end;
|
||||
|
||||
|
||||
begin
|
||||
UnloadLuaLib;
|
||||
|
||||
LuaLibHandle := SafeLoadLibrary(AFileName);
|
||||
if LuaLibHandle = 0 then
|
||||
RaiseLastOSError;
|
||||
|
||||
if not Assigned(LuaFunctions) then
|
||||
LuaFunctions := TList<PPointer>.Create();
|
||||
|
||||
Load(@lua_newstate, 'lua_newstate');
|
||||
Load(@lua_close, 'lua_close');
|
||||
Load(@lua_newthread, 'lua_newthread');
|
||||
|
||||
Load(@lua_atpanic, 'lua_atpanic');
|
||||
Load(@lua_version, 'lua_version');
|
||||
|
||||
Load(@lua_absindex, 'lua_absindex');
|
||||
Load(@lua_gettop, 'lua_gettop');
|
||||
Load(@lua_settop, 'lua_settop');
|
||||
Load(@lua_pushvalue, 'lua_pushvalue');
|
||||
Load(@lua_remove, 'lua_remove');
|
||||
Load(@lua_insert, 'lua_insert');
|
||||
Load(@lua_replace, 'lua_replace');
|
||||
Load(@lua_copy, 'lua_copy');
|
||||
Load(@lua_checkstack, 'lua_checkstack');
|
||||
Load(@lua_xmove, 'lua_xmove');
|
||||
|
||||
Load(@lua_isnumber, 'lua_isnumber');
|
||||
Load(@lua_isstring, 'lua_isstring');
|
||||
Load(@lua_iscfunction, 'lua_iscfunction');
|
||||
Load(@lua_isuserdata, 'lua_isuserdata');
|
||||
Load(@lua_type, 'lua_type');
|
||||
Load(@lua_typename, 'lua_typename');
|
||||
Load(@lua_tonumberx, 'lua_tonumberx');
|
||||
Load(@lua_tointegerx, 'lua_tointegerx');
|
||||
Load(@lua_tounsignedx, 'lua_tounsignedx');
|
||||
Load(@lua_toboolean, 'lua_toboolean');
|
||||
Load(@lua_tolstring, 'lua_tolstring');
|
||||
Load(@lua_rawlen, 'lua_rawlen');
|
||||
Load(@lua_tocfunction, 'lua_tocfunction');
|
||||
Load(@lua_touserdata, 'lua_touserdata');
|
||||
Load(@lua_tothread, 'lua_tothread');
|
||||
Load(@lua_topointer, 'lua_topointer');
|
||||
|
||||
Load(@lua_arith, 'lua_arith');
|
||||
Load(@lua_rawequal, 'lua_rawequal');
|
||||
Load(@lua_compare, 'lua_compare');
|
||||
|
||||
Load(@lua_pushnil, 'lua_pushnil');
|
||||
Load(@lua_pushnumber, 'lua_pushnumber');
|
||||
Load(@lua_pushinteger, 'lua_pushinteger');
|
||||
Load(@lua_pushunsigned, 'lua_pushunsigned');
|
||||
Load(@lua_pushlstring, 'lua_pushlstring');
|
||||
Load(@lua_pushstring, 'lua_pushstring');
|
||||
Load(@lua_pushvfstring, 'lua_pushvfstring');
|
||||
Load(@lua_pushfstring, 'lua_pushfstring');
|
||||
Load(@lua_pushcclosure, 'lua_pushcclosure');
|
||||
Load(@lua_pushboolean, 'lua_pushboolean');
|
||||
Load(@lua_pushlightuserdata, 'lua_pushlightuserdata');
|
||||
Load(@lua_pushthread, 'lua_pushthread');
|
||||
|
||||
Load(@lua_getglobal, 'lua_getglobal');
|
||||
Load(@lua_gettable, 'lua_gettable');
|
||||
Load(@lua_getfield, 'lua_getfield');
|
||||
Load(@lua_rawget, 'lua_rawget');
|
||||
Load(@lua_rawgeti, 'lua_rawgeti');
|
||||
Load(@lua_rawgetp, 'lua_rawgetp');
|
||||
Load(@lua_newuserdata, 'lua_newuserdata');
|
||||
Load(@lua_getmetatable, 'lua_getmetatable');
|
||||
Load(@lua_getuservalue, 'lua_getuservalue');
|
||||
|
||||
Load(@lua_createtable, 'lua_createtable');
|
||||
Load(@lua_setglobal, 'lua_setglobal');
|
||||
Load(@lua_settable, 'lua_settable');
|
||||
Load(@lua_setfield, 'lua_setfield');
|
||||
|
||||
Load(@lua_rawset, 'lua_rawset');
|
||||
Load(@lua_rawseti, 'lua_rawseti');
|
||||
Load(@lua_rawsetp, 'lua_rawsetp');
|
||||
Load(@lua_setmetatable, 'lua_setmetatable');
|
||||
Load(@lua_setuservalue, 'lua_setuservalue');
|
||||
|
||||
Load(@lua_callk, 'lua_callk');
|
||||
Load(@lua_getctx, 'lua_getctx');
|
||||
Load(@lua_pcallk, 'lua_pcallk');
|
||||
|
||||
Load(@lua_yieldk, 'lua_yieldk');
|
||||
Load(@lua_resume, 'lua_resume');
|
||||
Load(@lua_status, 'lua_status');
|
||||
|
||||
Load(@lua_gc, 'lua_gc');
|
||||
|
||||
Load(@lua_load, 'lua_load');
|
||||
Load(@lua_dump, 'lua_dump');
|
||||
|
||||
Load(@lua_error, 'lua_error');
|
||||
Load(@lua_next, 'lua_next');
|
||||
|
||||
Load(@lua_concat, 'lua_concat');
|
||||
Load(@lua_len, 'lua_len');
|
||||
|
||||
Load(@lua_getallocf, 'lua_getallocf');
|
||||
Load(@lua_setallocf, 'lua_setallocf');
|
||||
|
||||
|
||||
Load(@lua_getstack, 'lua_getstack');
|
||||
Load(@lua_getinfo, 'lua_getinfo');
|
||||
|
||||
Load(@lua_getlocal, 'lua_getlocal');
|
||||
Load(@lua_setlocal, 'lua_setlocal');
|
||||
Load(@lua_getupvalue, 'lua_getupvalue');
|
||||
Load(@lua_setupvalue, 'lua_setupvalue');
|
||||
|
||||
Load(@lua_upvalueid, 'lua_upvalueid');
|
||||
Load(@lua_upvaluejoin, 'lua_upvaluejoin');
|
||||
|
||||
Load(@lua_sethook, 'lua_sethook');
|
||||
Load(@lua_gethook, 'lua_gethook');
|
||||
Load(@lua_gethookmask, 'lua_gethookmask');
|
||||
Load(@lua_gethookcount, 'lua_gethookcount');
|
||||
|
||||
Load(@luaopen_base, 'luaopen_base');
|
||||
Load(@luaopen_coroutine, 'luaopen_coroutine');
|
||||
Load(@luaopen_table, 'luaopen_table');
|
||||
Load(@luaopen_io, 'luaopen_io');
|
||||
Load(@luaopen_os, 'luaopen_os');
|
||||
Load(@luaopen_string, 'luaopen_string');
|
||||
Load(@luaopen_bit32, 'luaopen_bit32');
|
||||
Load(@luaopen_math, 'luaopen_math');
|
||||
Load(@luaopen_debug, 'luaopen_debug');
|
||||
Load(@luaopen_package, 'luaopen_package');
|
||||
|
||||
Load(@luaL_openlibs, 'luaL_openlibs');
|
||||
Load(@luaL_requiref, 'luaL_requiref');
|
||||
|
||||
Load(@luaL_setfuncs, 'luaL_setfuncs');
|
||||
end;
|
||||
|
||||
|
||||
procedure UnloadLuaLib;
|
||||
var
|
||||
variable: PPointer;
|
||||
|
||||
begin
|
||||
if Assigned(LuaFunctions) then
|
||||
begin
|
||||
for variable in LuaFunctions do
|
||||
variable^ := nil;
|
||||
end;
|
||||
|
||||
if LuaLibLoaded then
|
||||
begin
|
||||
FreeLibrary(LuaLibHandle);
|
||||
LuaLibHandle := 0;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
function LuaLibLoaded: Boolean;
|
||||
begin
|
||||
Result := (LuaLibHandle <> 0);
|
||||
end;
|
||||
|
||||
|
||||
{ Macros }
|
||||
function lua_upvalueindex(idx: Integer): Integer;
|
||||
begin
|
||||
Result := (LUA_REGISTRYINDEX - idx);
|
||||
end;
|
||||
|
||||
procedure lua_call(L: lua_State; nargs, nresults: Integer);
|
||||
begin
|
||||
lua_callk(L, nargs, nresults, 0, nil);
|
||||
end;
|
||||
|
||||
function lua_pcall(L: lua_State; nargs, nresults, errfunc: Integer): Integer;
|
||||
begin
|
||||
Result := lua_pcallk(L, nargs, nresults, errfunc, 0, nil);
|
||||
end;
|
||||
|
||||
function lua_yield(L: lua_State; nresults: Integer): Integer;
|
||||
begin
|
||||
Result := lua_yieldk(L, nresults, 0, nil);
|
||||
end;
|
||||
|
||||
function lua_tonumber(L: lua_State; idx: Integer): lua_Number;
|
||||
begin
|
||||
Result := lua_tonumberx(L, idx, nil);
|
||||
end;
|
||||
|
||||
function lua_tointeger(L: lua_State; idx: Integer): lua_Integer;
|
||||
begin
|
||||
Result := lua_tointegerx(L, idx, nil);
|
||||
end;
|
||||
|
||||
function lua_tounsigned(L: lua_State; idx: Integer): lua_Unsigned;
|
||||
begin
|
||||
Result := lua_tounsignedx(L, idx, nil);
|
||||
end;
|
||||
|
||||
procedure lua_pop(L: lua_State; n: Integer);
|
||||
begin
|
||||
lua_settop(L, -(n) - 1);
|
||||
end;
|
||||
|
||||
procedure lua_newtable(L: lua_State); inline;
|
||||
begin
|
||||
lua_createtable(L, 0, 0);
|
||||
end;
|
||||
|
||||
procedure lua_register(L: lua_State; name: PAnsiChar; f: lua_CFunction); inline;
|
||||
begin
|
||||
lua_pushcfunction(L, f);
|
||||
lua_setglobal(L, name);
|
||||
end;
|
||||
|
||||
procedure lua_pushcfunction(L: lua_State; f: lua_CFunction);
|
||||
begin
|
||||
lua_pushcclosure(L, f, 0);
|
||||
end;
|
||||
|
||||
function lua_isfunction(L: lua_State; n: Integer): Boolean;
|
||||
begin
|
||||
Result := lua_type(L, n) = LUA_TFUNCTION;
|
||||
end;
|
||||
|
||||
function lua_istable(L: lua_State; n: Integer): Boolean;
|
||||
begin
|
||||
Result := lua_type(L, n) = LUA_TTABLE;
|
||||
end;
|
||||
|
||||
function lua_islightuserdata(L: lua_State; n: Integer): Boolean;
|
||||
begin
|
||||
Result := lua_type(L, n) = LUA_TLIGHTUSERDATA;
|
||||
end;
|
||||
|
||||
function lua_isnil(L: lua_State; n: Integer): Boolean;
|
||||
begin
|
||||
Result := lua_type(L, n) = LUA_TNIL;
|
||||
end;
|
||||
|
||||
function lua_isboolean(L: lua_State; n: Integer): Boolean;
|
||||
begin
|
||||
Result := lua_type(L, n) = LUA_TBOOLEAN;
|
||||
end;
|
||||
|
||||
function lua_isthread(L: lua_State; n: Integer): Boolean;
|
||||
begin
|
||||
Result := lua_type(L, n) = LUA_TTHREAD;
|
||||
end;
|
||||
|
||||
function lua_isnone(L: lua_State; n: Integer): Boolean;
|
||||
begin
|
||||
Result := lua_type(L, n) = LUA_TNONE;
|
||||
end;
|
||||
|
||||
function lua_isnoneornil(L: lua_State; n: Integer): Boolean;
|
||||
begin
|
||||
Result := lua_type(L, n) <= 0;
|
||||
end;
|
||||
|
||||
function lua_pushliteral(L: lua_State; const s: AnsiString): PAnsiChar;
|
||||
begin
|
||||
Result := lua_pushlstring(L, PAnsiChar(s), Length(s));
|
||||
end;
|
||||
|
||||
procedure lua_pushglobaltable(L: lua_State);
|
||||
begin
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS);
|
||||
end;
|
||||
|
||||
function lua_tostring(L: lua_State; idx: Integer): PAnsiChar;
|
||||
begin
|
||||
Result := lua_tolstring(L, idx, nil);
|
||||
end;
|
||||
|
||||
procedure luaL_where(L: lua_State; level: Integer);
|
||||
var
|
||||
ar: lua_Debug;
|
||||
msg: AnsiString;
|
||||
|
||||
begin
|
||||
if (lua_getstack(L, level, ar) <> 0) then // check function at level
|
||||
begin
|
||||
lua_getinfo(L, 'Sl', ar); // get info about it
|
||||
if (ar.currentline > 0) then // is there info?
|
||||
begin
|
||||
msg := AnsiString(Format('%s:%d: ', [ar.short_src, ar.currentline]));
|
||||
lua_pushlstring(L, PAnsiChar(msg), Length(msg));
|
||||
exit
|
||||
end;
|
||||
end;
|
||||
lua_pushliteral(L, ''); // else, no information available...
|
||||
end;
|
||||
|
||||
function luaL_error(L: lua_State; fmt: PAnsiChar; argp: Pointer): Integer;
|
||||
begin
|
||||
luaL_where(L, 1);
|
||||
lua_pushvfstring(L, fmt, argp);
|
||||
lua_concat(L, 2);
|
||||
Result := lua_error(L);
|
||||
end;
|
||||
|
||||
|
||||
initialization
|
||||
finalization
|
||||
UnloadLuaLib;
|
||||
FreeAndNil(LuaFunctions);
|
||||
|
||||
end.
|
2484
G940LEDControl/DelphiLua/Lua.pas
Normal file
2484
G940LEDControl/DelphiLua/Lua.pas
Normal file
File diff suppressed because it is too large
Load Diff
1
G940LEDControl/DelphiLua/readme.txt
Normal file
1
G940LEDControl/DelphiLua/readme.txt
Normal file
@ -0,0 +1 @@
|
||||
Source: https://git.x2software.net/delphi/delphilua
|
@ -375,6 +375,10 @@ object MainForm: TMainForm
|
||||
object tsConfiguration: TTabSheet
|
||||
Caption = ' Configuration '
|
||||
ImageIndex = 2
|
||||
ExplicitLeft = 0
|
||||
ExplicitTop = 0
|
||||
ExplicitWidth = 0
|
||||
ExplicitHeight = 0
|
||||
DesignSize = (
|
||||
442
|
||||
452)
|
||||
@ -529,6 +533,10 @@ object MainForm: TMainForm
|
||||
object tsAbout: TTabSheet
|
||||
Caption = 'About'
|
||||
ImageIndex = 1
|
||||
ExplicitLeft = 0
|
||||
ExplicitTop = 0
|
||||
ExplicitWidth = 0
|
||||
ExplicitHeight = 0
|
||||
object lblVersionCaption: TLabel
|
||||
Left = 16
|
||||
Top = 67
|
||||
|
@ -225,6 +225,7 @@ type
|
||||
implementation
|
||||
uses
|
||||
System.SysUtils,
|
||||
System.Types,
|
||||
System.Win.ComObj,
|
||||
Vcl.Dialogs,
|
||||
Vcl.Graphics,
|
||||
@ -241,6 +242,7 @@ uses
|
||||
ButtonFunctionFrm,
|
||||
ConfigConversion,
|
||||
FSXAutoLaunch,
|
||||
FSXLEDFunctionProvider,
|
||||
FSXLEDFunctionProviderIntf,
|
||||
FSXResources,
|
||||
FSXSimConnectStateMonitor,
|
||||
@ -248,6 +250,7 @@ uses
|
||||
LEDColorIntf,
|
||||
LEDFunctionIntf,
|
||||
LEDFunctionRegistry,
|
||||
StaticLEDFunction,
|
||||
StaticResources;
|
||||
|
||||
|
||||
@ -258,6 +261,9 @@ const
|
||||
DefaultProfileName = 'Default';
|
||||
ProfilePostfixModified = ' (modified)';
|
||||
|
||||
ScriptsPath = 'Scripts\';
|
||||
FSXScriptsPath = ScriptsPath + 'FSX\';
|
||||
|
||||
UserDataPath = 'G940LEDControl\';
|
||||
FilenameProfiles = UserDataPath + 'Profiles.xml';
|
||||
FilenameSettings = UserDataPath + 'Settings.xml';
|
||||
@ -302,6 +308,7 @@ procedure TMainForm.FormCreate(Sender: TObject);
|
||||
|
||||
var
|
||||
worker: IOmniWorker;
|
||||
scriptPaths: TStringDynArray;
|
||||
|
||||
begin
|
||||
FLog := TX2GlobalLog.Category('UI');
|
||||
@ -316,6 +323,16 @@ begin
|
||||
|
||||
SetFSXState(TextFSXDisconnected, False);
|
||||
|
||||
|
||||
TLEDFunctionRegistry.Register(TStaticLEDFunctionProvider.Create);
|
||||
|
||||
SetLength(scriptPaths, 2);
|
||||
scriptPaths[0] := App.Path + FSXScriptsPath;
|
||||
scriptPaths[1] := App.UserPath + UserDataPath + FSXScriptsPath;
|
||||
|
||||
TLEDFunctionRegistry.Register(TFSXLEDFunctionProvider.Create(scriptPaths));
|
||||
|
||||
|
||||
FEventMonitor := TOmniEventMonitor.Create(Self);
|
||||
|
||||
Log.Info('Starting G940 LED state consumer thread');
|
||||
|
@ -38,7 +38,10 @@ uses
|
||||
FSXLEDFunctionProviderIntf in 'Units\FSXLEDFunctionProviderIntf.pas',
|
||||
SimBaseDocumentXMLBinding in 'Units\SimBaseDocumentXMLBinding.pas',
|
||||
FSXAutoLaunch in 'Units\FSXAutoLaunch.pas',
|
||||
ControlIntf in 'Units\ControlIntf.pas';
|
||||
ControlIntf in 'Units\ControlIntf.pas',
|
||||
Lua.API in 'DelphiLua\Lua.API.pas',
|
||||
Lua in 'DelphiLua\Lua.pas',
|
||||
LuaLEDFunctionProvider in 'Units\LuaLEDFunctionProvider.pas';
|
||||
|
||||
{$R *.res}
|
||||
|
||||
@ -65,7 +68,6 @@ begin
|
||||
Application.ShowMainForm := not isRestarting;
|
||||
Application.Title := 'G940 LED Control';
|
||||
Application.CreateForm(TMainForm, MainForm);
|
||||
|
||||
if isRestarting then
|
||||
MainForm.Visible := True;
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
<FrameworkType>VCL</FrameworkType>
|
||||
<ProjectVersion>13.4</ProjectVersion>
|
||||
<Base>True</Base>
|
||||
<Config Condition="'$(Config)'==''">Release</Config>
|
||||
<Config Condition="'$(Config)'==''">Debug</Config>
|
||||
<Platform Condition="'$(Platform)'==''">Win32</Platform>
|
||||
<TargetedPlatforms>1</TargetedPlatforms>
|
||||
<AppType>Application</AppType>
|
||||
@ -142,6 +142,9 @@
|
||||
<DCCReference Include="Units\SimBaseDocumentXMLBinding.pas"/>
|
||||
<DCCReference Include="Units\FSXAutoLaunch.pas"/>
|
||||
<DCCReference Include="Units\ControlIntf.pas"/>
|
||||
<DCCReference Include="DelphiLua\Lua.API.pas"/>
|
||||
<DCCReference Include="DelphiLua\Lua.pas"/>
|
||||
<DCCReference Include="Units\LuaLEDFunctionProvider.pas"/>
|
||||
<BuildConfiguration Include="Debug">
|
||||
<Key>Cfg_2</Key>
|
||||
<CfgParent>Base</CfgParent>
|
||||
|
Binary file not shown.
@ -1,6 +1,7 @@
|
||||
unit FSXLEDFunction;
|
||||
|
||||
interface
|
||||
(*
|
||||
uses
|
||||
FSXLEDFunctionProvider,
|
||||
LEDFunction,
|
||||
@ -337,9 +338,11 @@ type
|
||||
|
||||
function GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass; override;
|
||||
end;
|
||||
*)
|
||||
|
||||
|
||||
implementation
|
||||
(*
|
||||
uses
|
||||
FSXLEDFunctionWorker,
|
||||
FSXResources,
|
||||
@ -1086,6 +1089,6 @@ end;
|
||||
function TFSXATCVisibilityFunction.GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass;
|
||||
begin
|
||||
Result := TFSXATCVisibilityFunctionWorker;
|
||||
end;
|
||||
end;*)
|
||||
|
||||
end.
|
||||
|
@ -4,79 +4,74 @@ interface
|
||||
uses
|
||||
Generics.Collections,
|
||||
System.SyncObjs,
|
||||
System.Types,
|
||||
|
||||
X2Log.Intf,
|
||||
Lua,
|
||||
|
||||
FSXLEDFunctionProviderIntf,
|
||||
FSXSimConnectIntf,
|
||||
LEDFunction,
|
||||
LEDFunctionIntf,
|
||||
LEDStateIntf;
|
||||
LEDStateIntf,
|
||||
LuaLEDFunctionProvider;
|
||||
|
||||
|
||||
type
|
||||
TCustomFSXFunction = class;
|
||||
TCustomFSXFunctionList = TObjectList<TCustomFSXFunction>;
|
||||
TFSXLEDFunctionWorker = class;
|
||||
|
||||
|
||||
TFSXLEDFunctionProvider = class(TCustomLEDFunctionProvider, IFSXLEDFunctionProvider, IFSXSimConnectObserver)
|
||||
TFSXLEDFunctionProvider = class(TCustomLuaLEDFunctionProvider, IFSXLEDFunctionProvider, IFSXSimConnectObserver)
|
||||
private
|
||||
FSimConnect: TInterfacedObject;
|
||||
FSimConnectLock: TCriticalSection;
|
||||
FProfileMenuSimConnect: IFSXSimConnectProfileMenu;
|
||||
FScriptSimConnect: TObject;
|
||||
protected
|
||||
procedure RegisterFunctions; override;
|
||||
|
||||
function GetUID: string; override;
|
||||
protected
|
||||
function CreateLuaLEDFunction(AInfo: ILuaTable; AOnSetup: ILuaFunction): TCustomLuaLEDFunction; override;
|
||||
|
||||
procedure InitInterpreter; override;
|
||||
procedure SetupWorker(AWorker: TFSXLEDFunctionWorker; AOnSetup: ILuaFunction);
|
||||
|
||||
{ IFSXSimConnectObserver }
|
||||
procedure ObserveDestroy(Sender: IFSXSimConnect);
|
||||
|
||||
{ IFSXLEDFunctionProvider }
|
||||
procedure SetProfileMenu(AEnabled: Boolean; ACascaded: Boolean);
|
||||
public
|
||||
constructor Create;
|
||||
constructor Create(const AScriptFolders: TStringDynArray);
|
||||
destructor Destroy; override;
|
||||
|
||||
function GetSimConnect: IFSXSimConnect;
|
||||
end;
|
||||
|
||||
|
||||
TCustomFSXFunction = class(TCustomMultiStateLEDFunction)
|
||||
TFSXLEDFunction = class(TCustomLuaLEDFunction)
|
||||
private
|
||||
FProvider: TFSXLEDFunctionProvider;
|
||||
FDisplayName: string;
|
||||
FUID: string;
|
||||
protected
|
||||
function GetDefaultCategoryName: string; override;
|
||||
|
||||
function GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass; override;
|
||||
procedure InitializeWorker(AWorker: TCustomLEDMultiStateFunctionWorker); override;
|
||||
|
||||
property Provider: TFSXLEDFunctionProvider read FProvider;
|
||||
protected
|
||||
function GetCategoryName: string; override;
|
||||
function GetDisplayName: string; override;
|
||||
function GetUID: string; override;
|
||||
public
|
||||
constructor Create(AProvider: TFSXLEDFunctionProvider; const ADisplayName, AUID: string);
|
||||
constructor Create(AProvider: TFSXLEDFunctionProvider; AInfo: ILuaTable; AOnSetup: ILuaFunction);
|
||||
end;
|
||||
|
||||
|
||||
TCustomFSXFunctionClass = class of TCustomFSXFunction;
|
||||
|
||||
|
||||
TCustomFSXFunctionWorker = class(TCustomLEDMultiStateFunctionWorker)
|
||||
TFSXLEDFunctionWorker = class(TCustomLuaLEDFunctionWorker)
|
||||
private
|
||||
FDataHandler: IFSXSimConnectDataHandler;
|
||||
FDefinitionID: Cardinal;
|
||||
FSimConnect: IFSXSimConnect;
|
||||
FDefinitionID: TList<Cardinal>;
|
||||
protected
|
||||
procedure RegisterVariables(ADefinition: IFSXSimConnectDefinition); virtual; abstract;
|
||||
|
||||
procedure SetSimConnect(const Value: IFSXSimConnect); virtual;
|
||||
|
||||
property DataHandler: IFSXSimConnectDataHandler read FDataHandler;
|
||||
property DefinitionID: Cardinal read FDefinitionID;
|
||||
property SimConnect: IFSXSimConnect read FSimConnect write SetSimConnect;
|
||||
property DefinitionID: TList<Cardinal> read FDefinitionID;
|
||||
protected
|
||||
procedure AddDefinition(ADefinition: IFSXSimConnectDefinition);
|
||||
|
||||
procedure HandleData(AData: Pointer); virtual; abstract;
|
||||
public
|
||||
constructor Create(const AProviderUID, AFunctionUID: string; AStates: ILEDMultiStateFunction; ASettings: ILEDFunctionWorkerSettings; const APreviousState: string = ''); override;
|
||||
@ -86,6 +81,7 @@ type
|
||||
|
||||
implementation
|
||||
uses
|
||||
System.Classes,
|
||||
System.SysUtils,
|
||||
|
||||
X2Log.Global,
|
||||
@ -100,37 +96,88 @@ uses
|
||||
type
|
||||
TCustomFSXFunctionWorkerDataHandler = class(TInterfacedObject, IFSXSimConnectDataHandler)
|
||||
private
|
||||
FWorker: TCustomFSXFunctionWorker;
|
||||
FWorker: TFSXLEDFunctionWorker;
|
||||
protected
|
||||
{ IFSXSimConnectDataHandler }
|
||||
procedure HandleData(AData: Pointer);
|
||||
|
||||
property Worker: TCustomFSXFunctionWorker read FWorker;
|
||||
property Worker: TFSXLEDFunctionWorker read FWorker;
|
||||
public
|
||||
constructor Create(AWorker: TCustomFSXFunctionWorker);
|
||||
constructor Create(AWorker: TFSXLEDFunctionWorker);
|
||||
end;
|
||||
|
||||
|
||||
TLuaSimConnect = class(TPersistent)
|
||||
private
|
||||
FProvider: TFSXLEDFunctionProvider;
|
||||
protected
|
||||
property Provider: TFSXLEDFunctionProvider read FProvider;
|
||||
public
|
||||
constructor Create(AProvider: TFSXLEDFunctionProvider);
|
||||
published
|
||||
procedure Monitor(Context: ILuaContext);
|
||||
end;
|
||||
|
||||
|
||||
type
|
||||
TLuaSimConnectType = record
|
||||
TypeName: string;
|
||||
Units: string;
|
||||
DataType: SIMCONNECT_DATAType;
|
||||
end;
|
||||
|
||||
const
|
||||
LuaSimConnectTypes: array[0..4] of TLuaSimConnectType =
|
||||
(
|
||||
( TypeName: 'Bool'; Units: FSX_UNIT_BOOL; DataType: SIMCONNECT_DATAType_INT32 ),
|
||||
( TypeName: 'Percent'; Units: FSX_UNIT_PERCENT; DataType: SIMCONNECT_DATAType_FLOAT64 ),
|
||||
( TypeName: 'Integer'; Units: FSX_UNIT_NUMBER; DataType: SIMCONNECT_DATAType_INT32 ),
|
||||
( TypeName: 'Float'; Units: FSX_UNIT_NUMBER; DataType: SIMCONNECT_DATAType_FLOAT64 ),
|
||||
( TypeName: 'Mask'; Units: FSX_UNIT_MASK; DataType: SIMCONNECT_DATATYPE_INT32 )
|
||||
);
|
||||
|
||||
|
||||
function GetUnits(const AType: string; out AUnits: string; out ADataType: SIMCONNECT_DATAType): Boolean;
|
||||
var
|
||||
typeIndex: Integer;
|
||||
|
||||
begin
|
||||
for typeIndex := Low(LuaSimConnectTypes) to High(LuaSimConnectTypes) do
|
||||
if SameText(AType, LuaSimConnectTypes[typeIndex].TypeName) then
|
||||
begin
|
||||
AUnits := LuaSimConnectTypes[typeIndex].Units;
|
||||
ADataType := LuaSimConnectTypes[typeIndex].DataType;
|
||||
Exit(True);
|
||||
end;
|
||||
|
||||
Result := False;
|
||||
end;
|
||||
|
||||
|
||||
{ TFSXLEDFunctionProvider }
|
||||
constructor TFSXLEDFunctionProvider.Create;
|
||||
constructor TFSXLEDFunctionProvider.Create(const AScriptFolders: TStringDynArray);
|
||||
begin
|
||||
inherited Create;
|
||||
|
||||
FSimConnectLock := TCriticalSection.Create;
|
||||
FScriptSimConnect := TLuaSimConnect.Create(Self);
|
||||
|
||||
inherited Create(AScriptFolders);
|
||||
end;
|
||||
|
||||
|
||||
destructor TFSXLEDFunctionProvider.Destroy;
|
||||
begin
|
||||
FreeAndNil(FScriptSimConnect);
|
||||
FreeAndNil(FSimConnectLock);
|
||||
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
|
||||
(*
|
||||
procedure TFSXLEDFunctionProvider.RegisterFunctions;
|
||||
begin
|
||||
inherited RegisterFunctions;
|
||||
|
||||
{ Systems }
|
||||
RegisterFunction(TFSXBatteryMasterFunction.Create( Self, FSXFunctionDisplayNameBatteryMaster, FSXFunctionUIDBatteryMaster));
|
||||
RegisterFunction(TFSXDeIceFunction.Create( Self, FSXFunctionDisplayNameDeIce, FSXFunctionUIDDeIce));
|
||||
@ -193,6 +240,36 @@ begin
|
||||
{ ATC }
|
||||
RegisterFunction(TFSXATCVisibilityFunction.Create(FSXProviderUID));
|
||||
end;
|
||||
*)
|
||||
|
||||
function TFSXLEDFunctionProvider.CreateLuaLEDFunction(AInfo: ILuaTable; AOnSetup: ILuaFunction): TCustomLuaLEDFunction;
|
||||
begin
|
||||
Result := TFSXLEDFunction.Create(Self, AInfo, AOnSetup);
|
||||
end;
|
||||
|
||||
|
||||
procedure TFSXLEDFunctionProvider.InitInterpreter;
|
||||
var
|
||||
simConnectType: ILuaTable;
|
||||
typeIndex: Integer;
|
||||
|
||||
begin
|
||||
inherited InitInterpreter;
|
||||
|
||||
Interpreter.RegisterFunctions(FScriptSimConnect, 'SimConnect');
|
||||
|
||||
simConnectType := TLuaTable.Create;
|
||||
for typeIndex := Low(LuaSimConnectTypes) to High(LuaSimConnectTypes) do
|
||||
simConnectType.SetValue(LuaSimConnectTypes[typeIndex].TypeName, LuaSimConnectTypes[typeIndex].TypeName);
|
||||
|
||||
Interpreter.SetGlobalVariable('SimConnectType', simConnectType);
|
||||
end;
|
||||
|
||||
|
||||
procedure TFSXLEDFunctionProvider.SetupWorker(AWorker: TFSXLEDFunctionWorker; AOnSetup: ILuaFunction);
|
||||
begin
|
||||
AOnSetup.Call([AWorker.UID]);
|
||||
end;
|
||||
|
||||
|
||||
function TFSXLEDFunctionProvider.GetUID: string;
|
||||
@ -245,81 +322,80 @@ end;
|
||||
|
||||
|
||||
|
||||
{ TCustomFSXFunction }
|
||||
constructor TCustomFSXFunction.Create(AProvider: TFSXLEDFunctionProvider; const ADisplayName, AUID: string);
|
||||
{ TFSXLEDFunction }
|
||||
constructor TFSXLEDFunction.Create(AProvider: TFSXLEDFunctionProvider; AInfo: ILuaTable; AOnSetup: ILuaFunction);
|
||||
begin
|
||||
inherited Create(AProvider.GetUID);
|
||||
inherited Create(AProvider, AInfo, AOnSetup);
|
||||
|
||||
FProvider := AProvider;
|
||||
FDisplayName := ADisplayName;
|
||||
FUID := AUID;
|
||||
end;
|
||||
|
||||
|
||||
procedure TCustomFSXFunction.InitializeWorker(AWorker: TCustomLEDMultiStateFunctionWorker);
|
||||
begin
|
||||
(AWorker as TCustomFSXFunctionWorker).SimConnect := Provider.GetSimConnect;
|
||||
end;
|
||||
|
||||
|
||||
function TCustomFSXFunction.GetCategoryName: string;
|
||||
function TFSXLEDFunction.GetDefaultCategoryName: string;
|
||||
begin
|
||||
Result := FSXCategory;
|
||||
end;
|
||||
|
||||
|
||||
function TCustomFSXFunction.GetDisplayName: string;
|
||||
function TFSXLEDFunction.GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass;
|
||||
begin
|
||||
Result := FDisplayName;
|
||||
Result := TFSXLEDFunctionWorker;
|
||||
end;
|
||||
|
||||
|
||||
function TCustomFSXFunction.GetUID: string;
|
||||
procedure TFSXLEDFunction.InitializeWorker(AWorker: TCustomLEDMultiStateFunctionWorker);
|
||||
var
|
||||
worker: TFSXLEDFunctionWorker;
|
||||
|
||||
begin
|
||||
Result := FUID;
|
||||
worker := (AWorker as TFSXLEDFunctionWorker);
|
||||
worker.Provider := Provider;
|
||||
|
||||
Provider.SetupWorker(worker, Setup);
|
||||
end;
|
||||
|
||||
|
||||
{ TCustomFSXFunctionWorker }
|
||||
constructor TCustomFSXFunctionWorker.Create(const AProviderUID, AFunctionUID: string; AStates: ILEDMultiStateFunction; ASettings: ILEDFunctionWorkerSettings; const APreviousState: string);
|
||||
{ TFSXLEDFunctionWorker }
|
||||
constructor TFSXLEDFunctionWorker.Create(const AProviderUID, AFunctionUID: string; AStates: ILEDMultiStateFunction; ASettings: ILEDFunctionWorkerSettings; const APreviousState: string);
|
||||
begin
|
||||
{ We can't pass ourselves as the Data Handler, as it would keep a reference to
|
||||
this worker from the SimConnect interface. That'd mean the worker never
|
||||
gets destroyed, and SimConnect never shuts down. Hence this proxy class. }
|
||||
FDataHandler := TCustomFSXFunctionWorkerDataHandler.Create(Self);
|
||||
FDefinitionID := TList<Cardinal>.Create;
|
||||
|
||||
inherited Create(AProviderUID, AFunctionUID, AStates, ASettings, APreviousState);
|
||||
end;
|
||||
|
||||
|
||||
destructor TCustomFSXFunctionWorker.Destroy;
|
||||
destructor TFSXLEDFunctionWorker.Destroy;
|
||||
var
|
||||
simConnect: IFSXSimConnect;
|
||||
id: Cardinal;
|
||||
|
||||
begin
|
||||
if DefinitionID <> 0 then
|
||||
SimConnect.RemoveDefinition(DefinitionID, DataHandler);
|
||||
if Assigned(Provider) and (DefinitionID.Count > 0) then
|
||||
begin
|
||||
simConnect := (Provider as TFSXLEDFunctionProvider).GetSimConnect;
|
||||
|
||||
for id in DefinitionID do
|
||||
simConnect.RemoveDefinition(id, DataHandler);
|
||||
end;
|
||||
|
||||
FreeAndNil(FDefinitionID);
|
||||
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
|
||||
procedure TCustomFSXFunctionWorker.SetSimConnect(const Value: IFSXSimConnect);
|
||||
var
|
||||
definition: IFSXSimConnectDefinition;
|
||||
|
||||
procedure TFSXLEDFunctionWorker.AddDefinition(ADefinition: IFSXSimConnectDefinition);
|
||||
begin
|
||||
FSimConnect := Value;
|
||||
|
||||
if Assigned(SimConnect) then
|
||||
begin
|
||||
definition := SimConnect.CreateDefinition;
|
||||
RegisterVariables(definition);
|
||||
|
||||
FDefinitionID := SimConnect.AddDefinition(definition, DataHandler);
|
||||
end;
|
||||
DefinitionID.Add((Provider as TFSXLEDFunctionProvider).GetSimConnect.AddDefinition(ADefinition, DataHandler));
|
||||
end;
|
||||
|
||||
|
||||
{ TCustomFSXFunctionWorkerDataHandler }
|
||||
constructor TCustomFSXFunctionWorkerDataHandler.Create(AWorker: TCustomFSXFunctionWorker);
|
||||
constructor TCustomFSXFunctionWorkerDataHandler.Create(AWorker: TFSXLEDFunctionWorker);
|
||||
begin
|
||||
inherited Create;
|
||||
|
||||
@ -333,7 +409,65 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
initialization
|
||||
TLEDFunctionRegistry.Register(TFSXLEDFunctionProvider.Create);
|
||||
{ TLuaSimConnect }
|
||||
constructor TLuaSimConnect.Create(AProvider: TFSXLEDFunctionProvider);
|
||||
begin
|
||||
inherited Create;
|
||||
|
||||
FProvider := AProvider;
|
||||
end;
|
||||
|
||||
|
||||
procedure TLuaSimConnect.Monitor(Context: ILuaContext);
|
||||
var
|
||||
workerID: string;
|
||||
variables: ILuaTable;
|
||||
onData: ILuaFunction;
|
||||
worker: TCustomLuaLEDFunctionWorker;
|
||||
definition: IFSXSimConnectDefinition;
|
||||
variable: TLuaKeyValuePair;
|
||||
info: ILuaTable;
|
||||
units: string;
|
||||
dataType: SIMCONNECT_DATAType;
|
||||
|
||||
begin
|
||||
if Context.Parameters.Count < 3 then
|
||||
raise ELuaScriptError.Create('Not enough parameters for SimConnect.Monitor');
|
||||
|
||||
if Context.Parameters[0].VariableType <> VariableString then
|
||||
raise ELuaScriptError.Create('Context expected for SimConnect.Monitor parameter 1');
|
||||
|
||||
if Context.Parameters[1].VariableType <> VariableTable then
|
||||
raise ELuaScriptError.Create('Table expected for SimConnect.Monitor parameter 2');
|
||||
|
||||
if Context.Parameters[2].VariableType <> VariableFunction then
|
||||
raise ELuaScriptError.Create('Function expected for SimConnect.Monitor parameter 3');
|
||||
|
||||
workerID := Context.Parameters[0].AsString;
|
||||
variables := Context.Parameters[1].AsTable;
|
||||
onData := Context.Parameters[2].AsFunction;
|
||||
|
||||
worker := Provider.FindWorker(workerID);
|
||||
if not Assigned(worker) then
|
||||
raise ELuaScriptError.Create('Context expected for SimConnect.Monitor parameter 1');
|
||||
|
||||
definition := Provider.GetSimConnect.CreateDefinition;
|
||||
|
||||
for variable in variables do
|
||||
begin
|
||||
if variable.Value.VariableType = VariableTable then
|
||||
begin
|
||||
info := variable.Value.AsTable;
|
||||
if info.HasValue('variable') and
|
||||
info.HasValue('type') and
|
||||
GetUnits(info.GetValue('type').AsString, units, dataType) then
|
||||
begin
|
||||
definition.AddVariable(info.GetValue('variable').AsString, units, dataType);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
(worker as TFSXLEDFunctionWorker).AddDefinition(definition);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
@ -1,6 +1,7 @@
|
||||
unit FSXLEDFunctionWorker;
|
||||
|
||||
interface
|
||||
(*
|
||||
uses
|
||||
OtlTaskControl,
|
||||
|
||||
@ -268,9 +269,10 @@ type
|
||||
constructor Create(const AProviderUID: string; const AFunctionUID: string; AStates: ILEDMultiStateFunction; ASettings: ILEDFunctionWorkerSettings; const APreviousState: string = ''); override;
|
||||
destructor Destroy; override;
|
||||
end;
|
||||
|
||||
*)
|
||||
|
||||
implementation
|
||||
(*
|
||||
uses
|
||||
System.Math,
|
||||
System.StrUtils,
|
||||
@ -1181,6 +1183,6 @@ begin
|
||||
FVisible := visible;
|
||||
FOnStateChanged(visible);
|
||||
end;
|
||||
end;
|
||||
end;*)
|
||||
|
||||
end.
|
||||
|
332
G940LEDControl/Units/LuaLEDFunctionProvider.pas
Normal file
332
G940LEDControl/Units/LuaLEDFunctionProvider.pas
Normal file
@ -0,0 +1,332 @@
|
||||
unit LuaLEDFunctionProvider;
|
||||
|
||||
interface
|
||||
uses
|
||||
System.Generics.Collections,
|
||||
System.SysUtils,
|
||||
System.Types,
|
||||
|
||||
LEDFunction,
|
||||
LEDFunctionIntf,
|
||||
LEDStateIntf,
|
||||
Lua;
|
||||
|
||||
type
|
||||
ELuaScriptError = class(Exception);
|
||||
|
||||
TCustomLuaLEDFunctionWorker = class;
|
||||
|
||||
|
||||
TCustomLuaLEDFunction = class(TCustomMultiStateLEDFunction)
|
||||
private
|
||||
FCategoryName: string;
|
||||
FDisplayName: string;
|
||||
FUID: string;
|
||||
FScriptStates: ILuaTable;
|
||||
FSetup: ILuaFunction;
|
||||
protected
|
||||
procedure RegisterStates; override;
|
||||
|
||||
function GetDefaultCategoryName: string; virtual;
|
||||
|
||||
{ ILEDFunction }
|
||||
function GetCategoryName: string; override;
|
||||
function GetDisplayName: string; override;
|
||||
function GetUID: string; override;
|
||||
|
||||
property ScriptStates: ILuaTable read FScriptStates;
|
||||
property Setup: ILuaFunction read FSetup;
|
||||
public
|
||||
constructor Create(AProvider: ILEDFunctionProvider; AInfo: ILuaTable; ASetup: ILuaFunction);
|
||||
end;
|
||||
|
||||
|
||||
TCustomLuaLEDFunctionProvider = class(TCustomLEDFunctionProvider)
|
||||
private
|
||||
FInterpreter: TLua;
|
||||
FScriptFolders: TStringDynArray;
|
||||
FWorkers: TDictionary<string, TCustomLuaLEDFunctionWorker>;
|
||||
protected
|
||||
function CreateLuaLEDFunction(AInfo: ILuaTable; ASetup: ILuaFunction): TCustomLuaLEDFunction; virtual; abstract;
|
||||
|
||||
procedure InitInterpreter; virtual;
|
||||
procedure RegisterFunctions; override;
|
||||
|
||||
procedure RegisterWorker(AWorker: TCustomLuaLEDFunctionWorker);
|
||||
procedure UnregisterWorker(AWorker: TCustomLuaLEDFunctionWorker);
|
||||
function FindWorker(const AUID: string): TCustomLuaLEDFunctionWorker;
|
||||
|
||||
property Interpreter: TLua read FInterpreter;
|
||||
property ScriptFolders: TStringDynArray read FScriptFolders;
|
||||
property Workers: TDictionary<string, TCustomLuaLEDFunctionWorker> read FWorkers;
|
||||
public
|
||||
constructor Create(const AScriptFolders: TStringDynArray);
|
||||
destructor Destroy; override;
|
||||
end;
|
||||
|
||||
|
||||
TCustomLuaLEDFunctionWorker = class(TCustomLEDMultiStateFunctionWorker)
|
||||
private
|
||||
FProvider: TCustomLuaLEDFunctionProvider;
|
||||
FUID: string;
|
||||
|
||||
procedure SetProvider(const Value: TCustomLuaLEDFunctionProvider);
|
||||
protected
|
||||
property Provider: TCustomLuaLEDFunctionProvider read FProvider write SetProvider;
|
||||
public
|
||||
constructor Create(const AProviderUID, AFunctionUID: string; AStates: ILEDMultiStateFunction; ASettings: ILEDFunctionWorkerSettings; const APreviousState: string = ''); override;
|
||||
destructor Destroy; override;
|
||||
|
||||
property UID: string read FUID;
|
||||
end;
|
||||
|
||||
|
||||
implementation
|
||||
uses
|
||||
System.IOUtils,
|
||||
|
||||
LEDColorIntf,
|
||||
LEDState;
|
||||
|
||||
|
||||
const
|
||||
LuaLEDColors: array[TLEDColor] of string =
|
||||
(
|
||||
'Off', 'Green', 'Amber', 'Red',
|
||||
'FlashingGreenFast', 'FlashingGreenNormal',
|
||||
'FlashingAmberFast', 'FlashingAmberNormal',
|
||||
'FlashingRedFast', 'FlashingRedNormal'
|
||||
);
|
||||
|
||||
function GetLEDColor(const AValue: string; ADefault: TLEDColor = lcOff): TLEDColor;
|
||||
var
|
||||
color: TLEDColor;
|
||||
|
||||
begin
|
||||
for color := Low(TLEDColor) to High(TLEDColor) do
|
||||
if SameText(AValue, LuaLEDColors[color]) then
|
||||
exit(color);
|
||||
|
||||
Result := ADefault;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
{ TCustomLuaLEDFunctionProvider }
|
||||
constructor TCustomLuaLEDFunctionProvider.Create(const AScriptFolders: TStringDynArray);
|
||||
begin
|
||||
FWorkers := TDictionary<string, TCustomLuaLEDFunctionWorker>.Create;
|
||||
FInterpreter := TLua.Create;
|
||||
FScriptFolders := AScriptFolders;
|
||||
|
||||
InitInterpreter;
|
||||
|
||||
inherited Create;
|
||||
end;
|
||||
|
||||
|
||||
destructor TCustomLuaLEDFunctionProvider.Destroy;
|
||||
begin
|
||||
FreeAndNil(FInterpreter);
|
||||
FreeAndNil(FWorkers);
|
||||
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
|
||||
procedure TCustomLuaLEDFunctionProvider.InitInterpreter;
|
||||
var
|
||||
table: ILuaTable;
|
||||
color: TLEDColor;
|
||||
|
||||
begin
|
||||
Interpreter.RegisterFunction('RegisterFunction',
|
||||
procedure(Context: ILuaContext)
|
||||
var
|
||||
info: ILuaTable;
|
||||
setup: ILuaFunction;
|
||||
|
||||
begin
|
||||
if Context.Parameters.Count < 2 then
|
||||
raise ELuaScriptError.Create('Not enough parameters for RegisterFunction');
|
||||
|
||||
if Context.Parameters[0].VariableType <> VariableTable then
|
||||
raise ELuaScriptError.Create('Table expected for RegisterFunction parameter 1');
|
||||
|
||||
if Context.Parameters[1].VariableType <> VariableFunction then
|
||||
raise ELuaScriptError.Create('Function expected for RegisterFunction parameter 2');
|
||||
|
||||
info := Context.Parameters[0].AsTable;
|
||||
setup := Context.Parameters[1].AsFunction;
|
||||
|
||||
if not info.HasValue('uid') then
|
||||
raise ELuaScriptError.Create('"uid" value is required for RegisterFunction parameter 1');
|
||||
|
||||
RegisterFunction(CreateLuaLEDFunction(info, setup));
|
||||
end);
|
||||
|
||||
table := TLuaTable.Create;
|
||||
for color := Low(TLEDColor) to High(TLEDColor) do
|
||||
table.SetValue(LuaLEDColors[color], LuaLEDColors[color]);
|
||||
|
||||
Interpreter.SetGlobalVariable('LEDColor', table);
|
||||
|
||||
// #ToDo1 -oMvR: 28-5-2017: SetState
|
||||
end;
|
||||
|
||||
|
||||
procedure TCustomLuaLEDFunctionProvider.RegisterFunctions;
|
||||
var
|
||||
scriptFolder: string;
|
||||
scriptFile: string;
|
||||
|
||||
begin
|
||||
for scriptFolder in ScriptFolders do
|
||||
if TDirectory.Exists(scriptFolder) then
|
||||
for scriptFile in TDirectory.GetFiles(ScriptFolder, '*.lua') do
|
||||
try
|
||||
Interpreter.LoadFromFile(scriptFile);
|
||||
except
|
||||
on E:Exception do
|
||||
Exception.RaiseOuterException(ELuaScriptError.CreateFmt('Error while loading script %s: %s', [scriptFile, E.Message]));
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure TCustomLuaLEDFunctionProvider.RegisterWorker(AWorker: TCustomLuaLEDFunctionWorker);
|
||||
begin
|
||||
Workers.Add(AWorker.UID, AWorker);
|
||||
end;
|
||||
|
||||
|
||||
procedure TCustomLuaLEDFunctionProvider.UnregisterWorker(AWorker: TCustomLuaLEDFunctionWorker);
|
||||
begin
|
||||
Workers.Remove(AWorker.UID);
|
||||
end;
|
||||
|
||||
|
||||
function TCustomLuaLEDFunctionProvider.FindWorker(const AUID: string): TCustomLuaLEDFunctionWorker;
|
||||
begin
|
||||
if not Workers.TryGetValue(AUID, Result) then
|
||||
Result := nil;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
{ TCustomLuaLEDFunction }
|
||||
constructor TCustomLuaLEDFunction.Create(AProvider: ILEDFunctionProvider; AInfo: ILuaTable; ASetup: ILuaFunction);
|
||||
begin
|
||||
FCategoryName := GetDefaultCategoryName;
|
||||
FDisplayName := 'Unknown function';
|
||||
FSetup := ASetup;
|
||||
|
||||
FUID := AInfo.GetValue('uid').AsString;
|
||||
|
||||
if AInfo.HasValue('category') then
|
||||
FCategoryName := AInfo.GetValue('category').AsString;
|
||||
|
||||
if AInfo.HasValue('displayName') then
|
||||
FDisplayName := AInfo.GetValue('displayName').AsString;
|
||||
|
||||
FScriptStates := nil;
|
||||
if AInfo.HasValue('states') then
|
||||
FScriptStates := AInfo.GetValue('states').AsTable;
|
||||
|
||||
// #ToDo1 -oMvR: 28-5-2017: application filter?
|
||||
|
||||
inherited Create(AProvider.GetUID);
|
||||
end;
|
||||
|
||||
|
||||
function TCustomLuaLEDFunction.GetCategoryName: string;
|
||||
begin
|
||||
Result := FCategoryName;
|
||||
end;
|
||||
|
||||
|
||||
function TCustomLuaLEDFunction.GetDisplayName: string;
|
||||
begin
|
||||
Result := FDisplayName;
|
||||
end;
|
||||
|
||||
|
||||
function TCustomLuaLEDFunction.GetUID: string;
|
||||
begin
|
||||
Result := FUID;
|
||||
end;
|
||||
|
||||
|
||||
procedure TCustomLuaLEDFunction.RegisterStates;
|
||||
var
|
||||
state: TLuaKeyValuePair;
|
||||
displayName: string;
|
||||
defaultColor: TLEDColor;
|
||||
info: ILuaTable;
|
||||
|
||||
begin
|
||||
if not Assigned(ScriptStates) then
|
||||
exit;
|
||||
|
||||
for state in ScriptStates do
|
||||
begin
|
||||
displayName := state.Key.AsString;
|
||||
defaultColor := lcOff;
|
||||
|
||||
if state.Value.VariableType = VariableTable then
|
||||
begin
|
||||
info := state.Value.AsTable;
|
||||
if info.HasValue('displayName') then
|
||||
displayName := info.GetValue('displayName').AsString;
|
||||
|
||||
if info.HasValue('default') then
|
||||
defaultColor := GetLEDColor(info.GetValue('default').AsString);
|
||||
end;
|
||||
|
||||
RegisterState(TLEDState.Create(state.Key.AsString, displayName, defaultColor));
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
function TCustomLuaLEDFunction.GetDefaultCategoryName: string;
|
||||
begin
|
||||
Result := 'Other';
|
||||
end;
|
||||
|
||||
|
||||
{ TCustomLuaLEDFunctionWorker }
|
||||
constructor TCustomLuaLEDFunctionWorker.Create(const AProviderUID, AFunctionUID: string; AStates: ILEDMultiStateFunction; ASettings: ILEDFunctionWorkerSettings; const APreviousState: string);
|
||||
var
|
||||
workerGUID: TGUID;
|
||||
|
||||
begin
|
||||
if CreateGUID(workerGUID) <> 0 then
|
||||
RaiseLastOSError;
|
||||
|
||||
FUID := GUIDToString(workerGUID);
|
||||
|
||||
inherited Create(AProviderUID, AFunctionUID, AStates, ASettings, APreviousState);
|
||||
end;
|
||||
|
||||
destructor TCustomLuaLEDFunctionWorker.Destroy;
|
||||
begin
|
||||
SetProvider(nil);
|
||||
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
|
||||
procedure TCustomLuaLEDFunctionWorker.SetProvider(const Value: TCustomLuaLEDFunctionProvider);
|
||||
begin
|
||||
if Value <> FProvider then
|
||||
begin
|
||||
if Assigned(FProvider) then
|
||||
FProvider.UnregisterWorker(Self);
|
||||
|
||||
FProvider := Value;
|
||||
|
||||
if Assigned(FProvider) then
|
||||
FProvider.RegisterWorker(Self);
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
@ -114,8 +114,4 @@ begin
|
||||
Result := FState;
|
||||
end;
|
||||
|
||||
|
||||
initialization
|
||||
TLEDFunctionRegistry.Register(TStaticLEDFunctionProvider.Create);
|
||||
|
||||
end.
|
||||
|
@ -1,2 +1,2 @@
|
||||
<?xml version="1.0"?>
|
||||
<DataBindingSettings xmlns="http://www.x2software.net/xsd/databinding/DataBindingSettings.xsd"><Output><OutputType>Single</OutputType><OutputSingle><FileName>F:\Development\G940\G940LEDControl\Units\SimBaseDocumentXMLBinding.pas</FileName></OutputSingle></Output></DataBindingSettings>
|
||||
<DataBindingSettings xmlns="http://www.x2software.net/xsd/databinding/DataBindingSettings.xsd"><Output><OutputType>Single</OutputType><OutputSingle><FileName>..\Units\SimBaseDocumentXMLBinding.pas</FileName></OutputSingle></Output></DataBindingSettings>
|
||||
|
@ -1,6 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- edited with XMLSpy v2015 rel. 3 (x64) (http://www.altova.com) by Mark van Renswoude (UnameIT we build IT B.V.) -->
|
||||
<!-- W3C Schema generated by XMLSpy v2015 rel. 3 (x64) (http://www.altova.com) -->
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<xs:element name="SimBase.Document">
|
||||
<xs:complexType>
|
||||
|
Loading…
Reference in New Issue
Block a user