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;
var
simConnectType: ILuaTable;
simConnectDataType: ILuaTable;
dataType: TLuaSimConnectDataType;
begin
@ -273,17 +273,22 @@ begin
Interpreter.RegisterFunctions(FScriptSimConnect, 'SimConnect');
simConnectType := TLuaTable.Create;
simConnectDataType := TLuaTable.Create;
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;
procedure TFSXLEDFunctionProvider.SetupWorker(AWorker: TFSXLEDFunctionWorker; AOnSetup: ILuaFunction);
begin
AOnSetup.Call([AWorker.UID]);
try
AOnSetup.Call([AWorker.UID]);
except
on E:Exception do
TX2GlobalLog.Category('Lua').Exception(E);
end;
end;
@ -549,7 +554,12 @@ begin
end;
end;
OnData.Call([WorkerID, data]);
try
OnData.Call([WorkerID, data]);
except
on E:Exception do
TX2GlobalLog.Category('Lua').Exception(E);
end;
end;

View File

@ -46,9 +46,13 @@ type
FInterpreter: TLua;
FScriptFolders: TStringDynArray;
FWorkers: TDictionary<string, TCustomLuaLEDFunctionWorker>;
FScriptLog: TObject;
protected
function CreateLuaLEDFunction(AInfo: ILuaTable; ASetup: ILuaFunction): TCustomLuaLEDFunction; virtual; abstract;
procedure ScriptRegisterFunction(Context: ILuaContext);
procedure ScriptSetState(Context: ILuaContext);
procedure InitInterpreter; virtual;
procedure RegisterFunctions; override;
@ -83,12 +87,38 @@ type
implementation
uses
System.Classes,
System.IOUtils,
Lua.API,
X2Log.Intf,
X2Log.Global,
LEDColorIntf,
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
LuaLEDColors: array[TLEDColor] of string =
(
@ -98,6 +128,7 @@ const
'FlashingRedFast', 'FlashingRedNormal'
);
function GetLEDColor(const AValue: string; ADefault: TLEDColor = lcOff): TLEDColor;
var
color: TLEDColor;
@ -118,6 +149,7 @@ begin
FWorkers := TDictionary<string, TCustomLuaLEDFunctionWorker>.Create;
FInterpreter := TLua.Create;
FScriptFolders := AScriptFolders;
FScriptLog := TLuaLog.Create(FInterpreter);
InitInterpreter;
@ -128,6 +160,7 @@ end;
destructor TCustomLuaLEDFunctionProvider.Destroy;
begin
FreeAndNil(FInterpreter);
FreeAndNil(FScriptLog);
FreeAndNil(FWorkers);
inherited Destroy;
@ -140,30 +173,10 @@ var
color: TLEDColor;
begin
Interpreter.RegisterFunction('RegisterFunction',
procedure(Context: ILuaContext)
var
info: ILuaTable;
setup: ILuaFunction;
Interpreter.RegisterFunction('RegisterFunction', ScriptRegisterFunction);
Interpreter.RegisterFunction('SetState', ScriptSetState);
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);
Interpreter.RegisterFunctions(FScriptLog, 'Log');
table := TLuaTable.Create;
for color := Low(TLEDColor) to High(TLEDColor) do
@ -171,8 +184,60 @@ begin
Interpreter.SetGlobalVariable('LEDColor', table);
// #ToDo1 -oMvR: 29-5-2017: Logging methods
// #ToDo1 -oMvR: 28-5-2017: SetState
// #ToDo1 -oMvR: 29-5-2017: Timer
// #ToDo1 -oMvR: 29-5-2017: FindWindow / FindFSXWindow
end;
procedure TCustomLuaLEDFunctionProvider.ScriptRegisterFunction(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;
procedure TCustomLuaLEDFunctionProvider.ScriptSetState(Context: ILuaContext);
var
workerID: string;
worker: TCustomLuaLEDFunctionWorker;
stateUID: string;
begin
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;
@ -330,4 +395,110 @@ begin
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.