1
0
mirror of synced 2024-11-05 02:59:16 +00:00

Added Logging methods for Lua scripts

Added exception handling
This commit is contained in:
Mark van Renswoude 2017-05-30 22:03:29 +02:00
parent f92d3e612b
commit 0e13417652
2 changed files with 212 additions and 31 deletions

View File

@ -265,7 +265,7 @@ end;
procedure TFSXLEDFunctionProvider.InitInterpreter; procedure TFSXLEDFunctionProvider.InitInterpreter;
var var
simConnectType: ILuaTable; simConnectDataType: ILuaTable;
dataType: TLuaSimConnectDataType; dataType: TLuaSimConnectDataType;
begin begin
@ -273,17 +273,22 @@ begin
Interpreter.RegisterFunctions(FScriptSimConnect, 'SimConnect'); Interpreter.RegisterFunctions(FScriptSimConnect, 'SimConnect');
simConnectType := TLuaTable.Create; simConnectDataType := TLuaTable.Create;
for dataType := Low(TLuaSimConnectDataType) to High(TLuaSimConnectDataType) do for dataType := Low(TLuaSimConnectDataType) to High(TLuaSimConnectDataType) do
simConnectType.SetValue(LuaSimConnectDataTypes[dataType], LuaSimConnectDataTypes[dataType]); simConnectDataType.SetValue(LuaSimConnectDataTypes[dataType], LuaSimConnectDataTypes[dataType]);
Interpreter.SetGlobalVariable('SimConnectType', simConnectType); Interpreter.SetGlobalVariable('SimConnectDataType', simConnectDataType);
end; end;
procedure TFSXLEDFunctionProvider.SetupWorker(AWorker: TFSXLEDFunctionWorker; AOnSetup: ILuaFunction); procedure TFSXLEDFunctionProvider.SetupWorker(AWorker: TFSXLEDFunctionWorker; AOnSetup: ILuaFunction);
begin begin
try
AOnSetup.Call([AWorker.UID]); AOnSetup.Call([AWorker.UID]);
except
on E:Exception do
TX2GlobalLog.Category('Lua').Exception(E);
end;
end; end;
@ -549,7 +554,12 @@ begin
end; end;
end; end;
try
OnData.Call([WorkerID, data]); OnData.Call([WorkerID, data]);
except
on E:Exception do
TX2GlobalLog.Category('Lua').Exception(E);
end;
end; end;

View File

@ -46,9 +46,13 @@ type
FInterpreter: TLua; FInterpreter: TLua;
FScriptFolders: TStringDynArray; FScriptFolders: TStringDynArray;
FWorkers: TDictionary<string, TCustomLuaLEDFunctionWorker>; FWorkers: TDictionary<string, TCustomLuaLEDFunctionWorker>;
FScriptLog: TObject;
protected protected
function CreateLuaLEDFunction(AInfo: ILuaTable; ASetup: ILuaFunction): TCustomLuaLEDFunction; virtual; abstract; function CreateLuaLEDFunction(AInfo: ILuaTable; ASetup: ILuaFunction): TCustomLuaLEDFunction; virtual; abstract;
procedure ScriptRegisterFunction(Context: ILuaContext);
procedure ScriptSetState(Context: ILuaContext);
procedure InitInterpreter; virtual; procedure InitInterpreter; virtual;
procedure RegisterFunctions; override; procedure RegisterFunctions; override;
@ -83,12 +87,38 @@ type
implementation implementation
uses uses
System.Classes,
System.IOUtils, System.IOUtils,
Lua.API,
X2Log.Intf,
X2Log.Global,
LEDColorIntf, LEDColorIntf,
LEDState; LEDState;
type
TLuaLog = class(TPersistent)
private
FInterpreter: TLua;
protected
procedure AppendVariable(ABuilder: TStringBuilder; AVariable: ILuaVariable);
procedure AppendTable(ABuilder: TStringBuilder; ATable: ILuaTable);
procedure Log(AContext: ILuaContext; ALevel: TX2LogLevel);
property Interpreter: TLua read FInterpreter;
public
constructor Create(AInterpreter: TLua);
published
procedure Verbose(Context: ILuaContext);
procedure Info(Context: ILuaContext);
procedure Warning(Context: ILuaContext);
procedure Error(Context: ILuaContext);
end;
const const
LuaLEDColors: array[TLEDColor] of string = LuaLEDColors: array[TLEDColor] of string =
( (
@ -98,6 +128,7 @@ const
'FlashingRedFast', 'FlashingRedNormal' 'FlashingRedFast', 'FlashingRedNormal'
); );
function GetLEDColor(const AValue: string; ADefault: TLEDColor = lcOff): TLEDColor; function GetLEDColor(const AValue: string; ADefault: TLEDColor = lcOff): TLEDColor;
var var
color: TLEDColor; color: TLEDColor;
@ -118,6 +149,7 @@ begin
FWorkers := TDictionary<string, TCustomLuaLEDFunctionWorker>.Create; FWorkers := TDictionary<string, TCustomLuaLEDFunctionWorker>.Create;
FInterpreter := TLua.Create; FInterpreter := TLua.Create;
FScriptFolders := AScriptFolders; FScriptFolders := AScriptFolders;
FScriptLog := TLuaLog.Create(FInterpreter);
InitInterpreter; InitInterpreter;
@ -128,6 +160,7 @@ end;
destructor TCustomLuaLEDFunctionProvider.Destroy; destructor TCustomLuaLEDFunctionProvider.Destroy;
begin begin
FreeAndNil(FInterpreter); FreeAndNil(FInterpreter);
FreeAndNil(FScriptLog);
FreeAndNil(FWorkers); FreeAndNil(FWorkers);
inherited Destroy; inherited Destroy;
@ -140,13 +173,28 @@ var
color: TLEDColor; color: TLEDColor;
begin begin
Interpreter.RegisterFunction('RegisterFunction', Interpreter.RegisterFunction('RegisterFunction', ScriptRegisterFunction);
procedure(Context: ILuaContext) Interpreter.RegisterFunction('SetState', ScriptSetState);
var
Interpreter.RegisterFunctions(FScriptLog, 'Log');
table := TLuaTable.Create;
for color := Low(TLEDColor) to High(TLEDColor) do
table.SetValue(LuaLEDColors[color], LuaLEDColors[color]);
Interpreter.SetGlobalVariable('LEDColor', table);
// #ToDo1 -oMvR: 29-5-2017: Timer
// #ToDo1 -oMvR: 29-5-2017: FindWindow / FindFSXWindow
end;
procedure TCustomLuaLEDFunctionProvider.ScriptRegisterFunction(Context: ILuaContext);
var
info: ILuaTable; info: ILuaTable;
setup: ILuaFunction; setup: ILuaFunction;
begin begin
if Context.Parameters.Count < 2 then if Context.Parameters.Count < 2 then
raise ELuaScriptError.Create('Not enough parameters for RegisterFunction'); raise ELuaScriptError.Create('Not enough parameters for RegisterFunction');
@ -163,16 +211,33 @@ begin
raise ELuaScriptError.Create('"uid" value is required for RegisterFunction parameter 1'); raise ELuaScriptError.Create('"uid" value is required for RegisterFunction parameter 1');
RegisterFunction(CreateLuaLEDFunction(info, setup)); RegisterFunction(CreateLuaLEDFunction(info, setup));
end); end;
table := TLuaTable.Create;
for color := Low(TLEDColor) to High(TLEDColor) do
table.SetValue(LuaLEDColors[color], LuaLEDColors[color]);
Interpreter.SetGlobalVariable('LEDColor', table); procedure TCustomLuaLEDFunctionProvider.ScriptSetState(Context: ILuaContext);
var
workerID: string;
worker: TCustomLuaLEDFunctionWorker;
stateUID: string;
// #ToDo1 -oMvR: 29-5-2017: Logging methods begin
// #ToDo1 -oMvR: 28-5-2017: SetState if Context.Parameters.Count < 2 then
raise ELuaScriptError.Create('Not enough parameters for SetState');
if Context.Parameters[0].VariableType <> VariableString then
raise ELuaScriptError.Create('Context expected for SetState parameter 1');
if Context.Parameters[1].VariableType <> VariableString then
raise ELuaScriptError.Create('State expected for SetState parameter 2');
workerID := Context.Parameters[0].AsString;
stateUID := Context.Parameters[1].AsString;
worker := FindWorker(workerID);
if not Assigned(worker) then
raise ELuaScriptError.Create('Context expected for SetState parameter 1');
worker.SetCurrentState(stateUID);
end; end;
@ -330,4 +395,110 @@ begin
end; end;
end; end;
{ TLuaLog }
constructor TLuaLog.Create(AInterpreter: TLua);
begin
inherited Create;
FInterpreter := AInterpreter;
end;
procedure TLuaLog.AppendVariable(ABuilder: TStringBuilder; AVariable: ILuaVariable);
begin
case AVariable.VariableType of
VariableBoolean:
if AVariable.AsBoolean then
ABuilder.Append('true')
else
ABuilder.Append('false');
VariableTable:
AppendTable(ABuilder, AVariable.AsTable);
else
ABuilder.Append(AVariable.AsString);
end;
end;
procedure TLuaLog.AppendTable(ABuilder: TStringBuilder; ATable: ILuaTable);
var
firstItem: Boolean;
item: TLuaKeyValuePair;
begin
ABuilder.Append('{ ');
firstItem := True;
for item in ATable do
begin
if firstItem then
firstItem := False
else
ABuilder.Append(', ');
AppendVariable(ABuilder, item.Key);
ABuilder.Append(' = ');
AppendVariable(ABuilder, item.Value);
end;
ABuilder.Append(' }');
end;
procedure TLuaLog.Log(AContext: ILuaContext; ALevel: TX2LogLevel);
var
debug: lua_Debug;
fileName: string;
msg: TStringBuilder;
parameter: ILuaVariable;
begin
fileName := 'Lua';
if Interpreter.HasState and (lua_getstack(Interpreter.State, 1, debug) <> 0) then
begin
lua_getinfo(Interpreter.State, 'Sl', debug);
fileName := fileName + ' - ' + string(debug.source)
end;
msg := TStringBuilder.Create;
try
for parameter in AContext.Parameters do
begin
AppendVariable(msg, parameter);
msg.Append(' ');
end;
TX2GlobalLog.Log(ALevel, msg.ToString, fileName);
finally
FreeAndNil(msg);
end;
end;
procedure TLuaLog.Verbose(Context: ILuaContext);
begin
Log(Context, TX2LogLevel.Verbose);
end;
procedure TLuaLog.Info(Context: ILuaContext);
begin
Log(Context, TX2LogLevel.Info);
end;
procedure TLuaLog.Warning(Context: ILuaContext);
begin
Log(Context, TX2LogLevel.Warning);
end;
procedure TLuaLog.Error(Context: ILuaContext);
begin
Log(Context, TX2LogLevel.Error);
end;
end. end.