diff --git a/G940LEDControl/Forms/MainFrm.dfm b/G940LEDControl/Forms/MainFrm.dfm index 2d46e27..637855c 100644 --- a/G940LEDControl/Forms/MainFrm.dfm +++ b/G940LEDControl/Forms/MainFrm.dfm @@ -1175,4 +1175,27 @@ object MainForm: TMainForm Left = 300 Top = 436 end + object ScriptErrorDialog: TTaskDialog + Buttons = < + item + Caption = '&Try again' + Default = True + CommandLinkHint = 'Reload all scripts' + ModalResult = 4 + end + item + Caption = '&Cancel' + CommandLinkHint = 'Exit G940LEDControl' + ModalResult = 8 + end> + CommonButtons = [] + ExpandedText = '' + Flags = [tfAllowDialogCancellation, tfUseCommandLinks, tfExpandedByDefault] + MainIcon = 2 + RadioButtons = <> + Text = '' + Title = 'Script error' + Left = 384 + Top = 376 + end end diff --git a/G940LEDControl/Forms/MainFrm.pas b/G940LEDControl/Forms/MainFrm.pas index ec7ae0c..1be8b08 100644 --- a/G940LEDControl/Forms/MainFrm.pas +++ b/G940LEDControl/Forms/MainFrm.pas @@ -29,7 +29,7 @@ uses LEDStateConsumer, Profile, ProfileManager, - Settings; + Settings, Vcl.Dialogs; const @@ -129,6 +129,7 @@ type TrayIcon: TTrayIcon; ApplicationEvents: TApplicationEvents; cbFSXSEAutoLaunch: TCheckBox; + ScriptErrorDialog: TTaskDialog; procedure FormCreate(Sender: TObject); procedure lblLinkLinkClick(Sender: TObject; const Link: string; LinkType: TSysLinkType); @@ -232,7 +233,6 @@ uses System.SysUtils, System.Types, System.Win.ComObj, - Vcl.Dialogs, Vcl.Graphics, Winapi.ShellAPI, @@ -254,6 +254,7 @@ uses G940LEDStateConsumer, LEDColorIntf, LEDFunctionIntf, + LuaLEDFunctionProvider, StaticLEDFunction, StaticResources; @@ -313,6 +314,7 @@ procedure TMainForm.FormCreate(Sender: TObject); var worker: IOmniWorker; scriptPaths: TStringDynArray; + provider: ILEDFunctionProvider; begin FLog := TX2GlobalLog.Category('UI'); @@ -341,8 +343,29 @@ begin scriptPaths[2] := TPath.GetFullPath(App.Path + '..\' + FSXScriptsPath); end; - FunctionRegistry.Register(TFSXLEDFunctionProvider.Create(scriptPaths)); + while True do + begin + try + provider := TFSXLEDFunctionProvider.Create(scriptPaths); + Break; + except + on E:ELuaScriptLoadError do + begin + ScriptErrorDialog.Caption := Self.Caption; + ScriptErrorDialog.Text := Format('One or more errors occured while trying to load "%s"', [E.Filename]); + ScriptErrorDialog.ExpandedText := E.Message; + ScriptErrorDialog.Execute; + if ScriptErrorDialog.ModalResult = mrClose then + begin + Application.Terminate; + Exit; + end; + end; + end; + end; + + FunctionRegistry.Register(provider); FEventMonitor := TOmniEventMonitor.Create(Self); diff --git a/G940LEDControl/Scripts/FSX/systems.lua b/G940LEDControl/Scripts/FSX/systems.lua index 9b202d4..0d4b623 100644 --- a/G940LEDControl/Scripts/FSX/systems.lua +++ b/G940LEDControl/Scripts/FSX/systems.lua @@ -131,10 +131,10 @@ RegisterFunction( displayName = 'Auto brake', states = { ['0'] = { displayName = 'Off / not available', default = LEDColor.Green, order = 1 }, - ['1'] = { displayName = '1', default = LEDColor.Amber, order = 2 }, - ['2'] = { displayName = '2', default = LEDColor.Amber, order = 3 }, - ['3'] = { displayName = '3', default = LEDColor.Amber, order = 4 }, - ['4'] = { displayName = '4', default = LEDColor.Red, order = 5 } + ['1'] = { displayName = '1', default = LEDColor.Amber, order = 2 }, + ['2'] = { displayName = '2', default = LEDColor.Amber, order = 3 }, + ['3'] = { displayName = '3', default = LEDColor.Amber, order = 4 }, + ['4'] = { displayName = '4', default = LEDColor.Red, order = 5 } } }, function(context) @@ -167,7 +167,136 @@ basefunctions.RegisterOnOffFunction({ -- Tail hook +RegisterFunction( + { + uid = 'tailHook', + category = strings.Category.FSX.Systems, + displayName = 'Tail hook', + states = { + retracted = { displayName = 'Retracted', default = LEDColor.Green, order = 1 }, + between = { displayName = 'Extending / retracting', default = LEDColor.Amber, order = 2 }, + extended = { displayName = 'Extended', default = LEDColor.Red, order = 3 } + } + }, + function(context) + SetState(context, 'retracted') + + OnSimConnect(context, + { + position = { variable = 'TAILHOOK POSITION', type = SimConnectDataType.Float64, units = 'percent' } + }, + function(context, data) + if data.position >= 0 and data.position <= 5 then + SetState(context, 'retracted') + elseif data.position >= 95 and data.position <= 100 then + SetState(context, 'extended') + else + SetState(context, 'between') + end + end) + end +) + + -- Tail wheel lock +basefunctions.RegisterOnOffFunction({ + category = strings.Category.FSX.Systems, + uid = 'tailWheelLock', + displayName = 'Tail wheel lock', + variable = 'TAILWHEEL LOCK ON' +}) + + -- Float (left) --- Float (right) --- Fuel level \ No newline at end of file +local function RegisterFloatFunction(functionUid, functionDisplayName, variableName) + RegisterFunction( + { + uid = functionUid, + category = strings.Category.FSX.Systems, + displayName = functionDisplayName, + states = { + retracted = { displayName = 'Retracted', default = LEDColor.Red, order = 1 }, + between = { displayName = 'Extending / retracting', default = LEDColor.Amber, order = 2 }, + extended = { displayName = 'Extended', default = LEDColor.Green, order = 3 } + } + }, + function(context) + SetState(context, 'retracted') + + OnSimConnect(context, + { + position = { variable = variableName, type = SimConnectDataType.Float64, units = 'percent' } + }, + function(context, data) + if data.position >= 0 and data.position <= 5 then + SetState(context, 'retracted') + elseif data.position >= 95 and data.position <= 100 then + SetState(context, 'extended') + else + SetState(context, 'between') + end + end) + end + ) +end + +RegisterFloatFunction('floatLeft', 'Float (left)', 'RETRACT LEFT FLOAT EXTENDED') +RegisterFloatFunction('floatRight', 'Float (right)', 'RETRACT RIGHT FLOAT EXTENDED') + + +-- Fuel level +RegisterFunction( + { + uid = 'fuelLevel', + category = strings.Category.FSX.Systems, + displayName = 'Fuel level', + states = { + ['notAvailable'] = { displayName = 'Not available', default = LEDColor.Off, order = 1 }, + ['empty'] = { displayName = 'Empty', default = LEDColor.FlashingRedFast, order = 2 }, + ['0To1'] = { displayName = '< 1%', default = LEDColor.FlashingRedNormal, order = 3 }, + ['1To2'] = { displayName = '< 2%', default = LEDColor.FlashingRedNormal, order = 4 }, + ['2To5'] = { displayName = '< 5%', default = LEDColor.Red, order = 5 }, + ['5To10'] = { displayName = '< 10%', default = LEDColor.Amber, order = 6 }, + ['10To20'] = { displayName = '< 20%', default = LEDColor.Amber, order = 7 }, + ['20To50'] = { displayName = '< 50%', default = LEDColor.Green, order = 8 }, + ['50To75'] = { displayName = '< 75%', default = LEDColor.Green, order = 9 }, + ['75To100'] = { displayName = '75% - Full', default = LEDColor.Green, order = 10 } + } + }, + function(context) + SetState(context, '75To100') + + OnSimConnect(context, + { + capacity = { variable = 'FUEL TOTAL CAPACITY', type = SimConnectDataType.Float64, units = 'number' }, + quantity = { variable = 'FUEL TOTAL QUANTITY', type = SimConnectDataType.Float64, units = 'number' } + }, + function(context, data) + if data.capacity > 0 then + local percentage = math.ceil(data.quantity / data.capacity * 100) + + if percentage == 0 then + SetState(context, 'empty') + elseif percentage == 1 then + SetState(context, '0To1') + elseif percentage == 2 then + SetState(context, '1To2') + elseif percentage >= 3 and percentage <= 5 then + SetState(context, '2To5') + elseif percentage >= 6 and percentage <= 10 then + SetState(context, '5To10') + elseif percentage >= 11 and percentage <= 20 then + SetState(context, '10To20') + elseif percentage >= 21 and percentage <= 50 then + SetState(context, '20To50') + elseif percentage >= 51 and percentage <= 75 then + SetState(context, '50To75') + else + SetState(context, '75To100') + end + else + SetState(context, 'notAvailable') + end + end) + end +) \ No newline at end of file diff --git a/G940LEDControl/Units/LuaLEDFunctionProvider.pas b/G940LEDControl/Units/LuaLEDFunctionProvider.pas index e711339..1bac8a6 100644 --- a/G940LEDControl/Units/LuaLEDFunctionProvider.pas +++ b/G940LEDControl/Units/LuaLEDFunctionProvider.pas @@ -18,6 +18,15 @@ uses type ELuaScriptError = class(Exception); + ELuaScriptLoadError = class(ELuaScriptError) + private + FFilename: string; + public + constructor Create(const AMessage, AFilename: string); + + property Filename: string read FFilename; + end; + TCustomLuaLEDFunctionWorker = class; @@ -490,7 +499,7 @@ begin Interpreter.LoadFromFile(scriptFile); except on E:Exception do - Exception.RaiseOuterException(ELuaScriptError.CreateFmt('Error while loading script %s: %s', [scriptFile, E.Message])); + Exception.RaiseOuterException(ELuaScriptLoadError.Create(E.Message, scriptFile)); end; end; @@ -732,4 +741,12 @@ begin FOnTimer(); end; +{ ELuaScriptLoadError } +constructor ELuaScriptLoadError.Create(const AMessage, AFilename: string); +begin + inherited Create(AMessage); + + FFilename := AFilename; +end; + end.