1
0
mirror of synced 2024-09-28 21:16:09 +00:00

Ready for beta 1.0!

Added: FSX state
Added: incremental search for functions
Added: converted all 0.6 functions
Fixed: state being forgotten when changing the profile
This commit is contained in:
Mark van Renswoude 2013-02-24 20:09:47 +00:00
parent 62fb8e1357
commit 50580144ac
26 changed files with 2232 additions and 1151 deletions

View File

@ -40,7 +40,7 @@ object ButtonFunctionForm: TButtonFunctionForm
Margins.Bottom = 0 Margins.Bottom = 0
Align = alBottom Align = alBottom
BevelOuter = bvNone BevelOuter = bvNone
TabOrder = 2 TabOrder = 3
DesignSize = ( DesignSize = (
692 692
43) 43)
@ -93,7 +93,8 @@ object ButtonFunctionForm: TButtonFunctionForm
Header.Font.Name = 'Tahoma' Header.Font.Name = 'Tahoma'
Header.Font.Style = [] Header.Font.Style = []
Header.Options = [hoAutoResize, hoColumnResize, hoDrag, hoShowSortGlyphs, hoVisible] Header.Options = [hoAutoResize, hoColumnResize, hoDrag, hoShowSortGlyphs, hoVisible]
TabOrder = 0 IncrementalSearch = isAll
TabOrder = 1
TreeOptions.AutoOptions = [toAutoDropExpand, toAutoScrollOnExpand, toAutoSort, toAutoTristateTracking, toAutoDeleteMovedNodes] TreeOptions.AutoOptions = [toAutoDropExpand, toAutoScrollOnExpand, toAutoSort, toAutoTristateTracking, toAutoDeleteMovedNodes]
TreeOptions.MiscOptions = [toAcceptOLEDrop, toFullRepaintOnResize, toInitOnSave, toWheelPanning, toEditOnClick] TreeOptions.MiscOptions = [toAcceptOLEDrop, toFullRepaintOnResize, toInitOnSave, toWheelPanning, toEditOnClick]
TreeOptions.PaintOptions = [toShowButtons, toShowDropmark, toShowTreeLines, toThemeAware, toUseBlendedImages] TreeOptions.PaintOptions = [toShowButtons, toShowDropmark, toShowTreeLines, toThemeAware, toUseBlendedImages]
@ -101,6 +102,7 @@ object ButtonFunctionForm: TButtonFunctionForm
OnFocusChanged = vstFunctionsFocusChanged OnFocusChanged = vstFunctionsFocusChanged
OnGetText = vstFunctionsGetText OnGetText = vstFunctionsGetText
OnPaintText = vstFunctionsPaintText OnPaintText = vstFunctionsPaintText
OnIncrementalSearch = vstFunctionsIncrementalSearch
Columns = < Columns = <
item item
Position = 0 Position = 0
@ -120,7 +122,7 @@ object ButtonFunctionForm: TButtonFunctionForm
Margins.Bottom = 0 Margins.Bottom = 0
Align = alClient Align = alClient
BevelOuter = bvNone BevelOuter = bvNone
TabOrder = 1 TabOrder = 2
object pnlName: TPanel object pnlName: TPanel
Left = 0 Left = 0
Top = 0 Top = 0
@ -203,7 +205,7 @@ object ButtonFunctionForm: TButtonFunctionForm
BevelOuter = bvNone BevelOuter = bvNone
Color = clWindow Color = clWindow
ParentBackground = False ParentBackground = False
TabOrder = 3 TabOrder = 0
DesignSize = ( DesignSize = (
692 692
50) 50)

View File

@ -49,6 +49,7 @@ type
procedure vstFunctionsGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string); procedure vstFunctionsGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
procedure vstFunctionsPaintText(Sender: TBaseVirtualTree; const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType); procedure vstFunctionsPaintText(Sender: TBaseVirtualTree; const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType);
procedure vstFunctionsFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex); procedure vstFunctionsFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex);
procedure vstFunctionsIncrementalSearch(Sender: TBaseVirtualTree; Node: PVirtualNode; const SearchText: string; var Result: Integer);
procedure btnOKClick(Sender: TObject); procedure btnOKClick(Sender: TObject);
private private
FProfile: TProfile; FProfile: TProfile;
@ -97,6 +98,7 @@ type
implementation implementation
uses uses
System.Math,
System.SysUtils, System.SysUtils,
Winapi.Windows, Winapi.Windows,
@ -377,6 +379,9 @@ var
color: TLEDColor; color: TLEDColor;
begin begin
if not Assigned(Button) then
FButton := Profile.Buttons[ButtonIndex];
Button.ProviderUID := SelectedProvider.GetUID; Button.ProviderUID := SelectedProvider.GetUID;
Button.FunctionUID := SelectedFunction.GetUID; Button.FunctionUID := SelectedFunction.GetUID;
@ -438,6 +443,24 @@ begin
end; end;
procedure TButtonFunctionForm.vstFunctionsIncrementalSearch(Sender: TBaseVirtualTree; Node: PVirtualNode;
const SearchText: string; var Result: Integer);
var
nodeData: PFunctionNodeData;
displayName: string;
begin
nodeData := Sender.GetNodeData(Node);
if nodeData^.NodeType = ntFunction then
begin
displayName := nodeData^.LEDFunction.GetDisplayName;
Result := StrLIComp(PChar(displayName), PChar(SearchText), Min(Length(displayName), Length(searchText)));
end else
Result := -1;
end;
procedure TButtonFunctionForm.vstFunctionsPaintText(Sender: TBaseVirtualTree; const TargetCanvas: TCanvas; procedure TButtonFunctionForm.vstFunctionsPaintText(Sender: TBaseVirtualTree; const TargetCanvas: TCanvas;
Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType); Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType);
var var

File diff suppressed because it is too large Load Diff

View File

@ -19,6 +19,7 @@ uses
pngimage, pngimage,
X2UtPersistIntf, X2UtPersistIntf,
FSXSimConnectIntf,
LEDStateConsumer, LEDStateConsumer,
Profile, Profile,
Settings; Settings;
@ -27,8 +28,9 @@ uses
const const
CM_ASKAUTOUPDATE = WM_APP + 1; CM_ASKAUTOUPDATE = WM_APP + 1;
MSG_UPDATE = 1; TM_UPDATE = 1;
MSG_NOUPDATE = 2; TM_NOUPDATE = 2;
TM_FSXSTATE = 3;
LED_COUNT = 8; LED_COUNT = 8;
@ -95,6 +97,12 @@ type
btnSaveProfile: TButton; btnSaveProfile: TButton;
btnDeleteProfile: TButton; btnDeleteProfile: TButton;
bvlProfiles: TBevel; bvlProfiles: TBevel;
pnlFSX: TPanel;
imgFSXStateNotConnected: TImage;
imgFSXStateConnected: TImage;
lblFSX: TLabel;
lblFSXState: TLabel;
pnlState: TPanel;
procedure FormCreate(Sender: TObject); procedure FormCreate(Sender: TObject);
procedure lblLinkLinkClick(Sender: TObject; const Link: string; LinkType: TSysLinkType); procedure lblLinkLinkClick(Sender: TObject; const Link: string; LinkType: TSysLinkType);
@ -103,6 +111,8 @@ type
procedure FormDestroy(Sender: TObject); procedure FormDestroy(Sender: TObject);
procedure cmbProfilesClick(Sender: TObject); procedure cmbProfilesClick(Sender: TObject);
procedure cbCheckUpdatesClick(Sender: TObject); procedure cbCheckUpdatesClick(Sender: TObject);
procedure btnSaveProfileClick(Sender: TObject);
procedure btnDeleteProfileClick(Sender: TObject);
private private
FLEDControls: array[0..LED_COUNT - 1] of TLEDControls; FLEDControls: array[0..LED_COUNT - 1] of TLEDControls;
FEventMonitor: TOmniEventMonitor; FEventMonitor: TOmniEventMonitor;
@ -110,7 +120,7 @@ type
FProfilesFilename: string; FProfilesFilename: string;
FProfiles: TProfileList; FProfiles: TProfileList;
FActiveProfile: TProfile; FActiveProfile: TProfile;
FLoadingProfiles: Boolean; FLockChangeProfile: Boolean;
FStateConsumerTask: IOmniTaskControl; FStateConsumerTask: IOmniTaskControl;
FDeviceNotification: Pointer; FDeviceNotification: Pointer;
@ -118,6 +128,8 @@ type
FSettingsFileName: string; FSettingsFileName: string;
FSettings: TSettings; FSettings: TSettings;
procedure SetActiveProfile(const Value: TProfile);
protected protected
procedure RegisterDeviceArrival; procedure RegisterDeviceArrival;
procedure UnregisterDeviceArrival; procedure UnregisterDeviceArrival;
@ -135,7 +147,12 @@ type
procedure LoadActiveProfile; procedure LoadActiveProfile;
procedure UpdateButton(AProfile: TProfile; AButtonIndex: Integer); procedure UpdateButton(AProfile: TProfile; AButtonIndex: Integer);
procedure AddProfile(AProfile: TProfile);
procedure UpdateProfile(AProfile: TProfile);
procedure DeleteProfile(AProfile: TProfile; ASetActiveProfile: Boolean);
procedure SetDeviceState(const AMessage: string; AFound: Boolean); procedure SetDeviceState(const AMessage: string; AFound: Boolean);
procedure SetFSXState(const AMessage: string; AConnected: Boolean);
// procedure SetFSXToggleZoomButton(const ADeviceGUID: TGUID; AButtonIndex: Integer; const ADisplayText: string); // procedure SetFSXToggleZoomButton(const ADeviceGUID: TGUID; AButtonIndex: Integer; const ADisplayText: string);
procedure CheckForUpdatesThread(const ATask: IOmniTask); procedure CheckForUpdatesThread(const ATask: IOmniTask);
@ -144,11 +161,12 @@ type
procedure EventMonitorMessage(const task: IOmniTaskControl; const msg: TOmniMessage); procedure EventMonitorMessage(const task: IOmniTaskControl; const msg: TOmniMessage);
procedure EventMonitorTerminated(const task: IOmniTaskControl); procedure EventMonitorTerminated(const task: IOmniTaskControl);
procedure HandleDeviceStateMessage(ATask: IOmniTaskControl; AMessage: TOmniMessage); procedure HandleDeviceStateMessage(AMessage: TOmniMessage);
procedure HandleFSXStateMessage(AMessage: TOmniMessage);
procedure CMAskAutoUpdate(var Msg: TMessage); message CM_ASKAUTOUPDATE; procedure CMAskAutoUpdate(var Msg: TMessage); message CM_ASKAUTOUPDATE;
property ActiveProfile: TProfile read FActiveProfile; property ActiveProfile: TProfile read FActiveProfile write SetActiveProfile;
property EventMonitor: TOmniEventMonitor read FEventMonitor; property EventMonitor: TOmniEventMonitor read FEventMonitor;
property Profiles: TProfileList read FProfiles; property Profiles: TProfileList read FProfiles;
property Settings: TSettings read FSettings; property Settings: TSettings read FSettings;
@ -158,11 +176,11 @@ type
implementation implementation
uses uses
ComObj, System.SysUtils,
Dialogs, System.Win.ComObj,
Graphics, Vcl.Dialogs,
ShellAPI, Vcl.Graphics,
SysUtils, Winapi.ShellAPI,
IdException, IdException,
IdHTTP, IdHTTP,
@ -172,6 +190,7 @@ uses
ButtonFunctionFrm, ButtonFunctionFrm,
ConfigConversion, ConfigConversion,
FSXSimConnectStateMonitor,
G940LEDStateConsumer, G940LEDStateConsumer,
LEDColorIntf, LEDColorIntf,
LEDFunctionIntf, LEDFunctionIntf,
@ -184,15 +203,31 @@ uses
const const
DefaultProfileName = 'Default'; DefaultProfileName = 'Default';
ProfilePostfixModified = ' (modified)';
FILENAME_PROFILES = 'G940LEDControl\Profiles.xml'; FilenameProfiles = 'G940LEDControl\Profiles.xml';
FILENAME_SETTINGS = 'G940LEDControl\Settings.xml'; FilenameSettings = 'G940LEDControl\Settings.xml';
SPECIAL_CATEGORY = -1; TextStateSearching = 'Searching...';
TextStateNotFound = 'Not found';
TextStateFound = 'Connected';
TEXT_STATE_SEARCHING = 'Searching...'; TextFSXConnected = 'Connected';
TEXT_STATE_NOTFOUND = 'Not found'; TextFSXDisconnected = 'Not connected';
TEXT_STATE_FOUND = 'Connected'; TextFSXFailed = 'Failed to connect';
type
TFSXStateMonitorWorker = class(TOmniWorker, IFSXSimConnectStateObserver)
protected
function Initialize: Boolean; override;
procedure Cleanup; override;
{ IFSXSimConnectStateObserver }
procedure ObserverStateUpdate(ANewState: TFSXSimConnectState);
end;
@ -200,7 +235,7 @@ const
{ TMainForm } { TMainForm }
procedure TMainForm.FormCreate(Sender: TObject); procedure TMainForm.FormCreate(Sender: TObject);
var var
consumer: IOmniWorker; worker: IOmniWorker;
begin begin
lblVersion.Caption := App.Version.FormatVersion(False); lblVersion.Caption := App.Version.FormatVersion(False);
@ -209,25 +244,25 @@ begin
FEventMonitor := TOmniEventMonitor.Create(Self); FEventMonitor := TOmniEventMonitor.Create(Self);
consumer := TG940LEDStateConsumer.Create; worker := TG940LEDStateConsumer.Create;
FStateConsumerTask := FEventMonitor.Monitor(CreateTask(consumer)).MsgWait; FStateConsumerTask := EventMonitor.Monitor(CreateTask(worker)).MsgWait;
EventMonitor.OnTaskMessage := EventMonitorMessage; EventMonitor.OnTaskMessage := EventMonitorMessage;
EventMonitor.OnTaskTerminated := EventMonitorTerminated; EventMonitor.OnTaskTerminated := EventMonitorTerminated;
StateConsumerTask.Run; StateConsumerTask.Run;
worker := TFSXStateMonitorWorker.Create;
EventMonitor.Monitor(CreateTask(worker)).Run;
FindLEDControls; FindLEDControls;
FProfilesFilename := App.UserPath + FILENAME_PROFILES; FProfilesFilename := App.UserPath + FilenameProfiles;
FProfiles := TProfileList.Create(True); FProfiles := TProfileList.Create(True);
LoadProfiles; LoadProfiles;
FSettingsFileName := App.UserPath + FILENAME_SETTINGS; FSettingsFileName := App.UserPath + FilenameSettings;
LoadSettings; LoadSettings;
// #ToDo1 -oMvR: 22-2-2013: implement profile changing properly
FStateConsumerTask.Comm.Send(TM_LOADPROFILE, ActiveProfile);
RegisterDeviceArrival; RegisterDeviceArrival;
end; end;
@ -336,13 +371,15 @@ begin
defaultProfile := ConfigConversion.ConvertProfile0To1; defaultProfile := ConfigConversion.ConvertProfile0To1;
if not Assigned(defaultProfile) then if not Assigned(defaultProfile) then
defaultProfile := CreateDefaultProfile; defaultProfile := CreateDefaultProfile
else
if Assigned(defaultProfile) then
begin begin
defaultProfile.Name := DefaultProfileName; defaultProfile.Name := DefaultProfileName;
Profiles.Add(defaultProfile); defaultProfile.IsTemporary := True;
end; end;
if Assigned(defaultProfile) then
Profiles.Add(defaultProfile);
end else end else
begin begin
persistXML := TX2UtPersistXML.Create; persistXML := TX2UtPersistXML.Create;
@ -354,7 +391,11 @@ begin
end; end;
end; end;
FLoadingProfiles := True; { Make sure we always have a profile }
if Profiles.Count = 0 then
Profiles.Add(CreateDefaultProfile);
FLockChangeProfile := True;
try try
cmbProfiles.Items.BeginUpdate; cmbProfiles.Items.BeginUpdate;
try try
@ -364,17 +405,9 @@ begin
cmbProfiles.Items.AddObject(profile.Name, profile); cmbProfiles.Items.AddObject(profile.Name, profile);
finally finally
cmbProfiles.Items.EndUpdate; cmbProfiles.Items.EndUpdate;
if cmbProfiles.Items.Count > 0 then
begin
cmbProfiles.ItemIndex := 0;
FActiveProfile := TProfile(cmbProfiles.Items.Objects[0]);
LoadActiveProfile;
end;
end; end;
finally finally
FLoadingProfiles := False; FLockChangeProfile := False;
end; end;
end; end;
@ -397,6 +430,7 @@ end;
procedure TMainForm.LoadSettings; procedure TMainForm.LoadSettings;
var var
persistXML: TX2UtPersistXML; persistXML: TX2UtPersistXML;
profile: TProfile;
begin begin
if not FileExists(FSettingsFileName) then if not FileExists(FSettingsFileName) then
@ -419,6 +453,18 @@ begin
end; end;
end; end;
{ Default profile }
profile := nil;
if Length(Settings.ActiveProfile) > 0 then
profile := Profiles.Find(Settings.ActiveProfile);
{ LoadProfiles ensures there's always at least 1 profile }
if (not Assigned(profile)) and (Profiles.Count > 0) then
profile := Profiles[0];
SetActiveProfile(profile);
{ Auto-update }
cbCheckUpdates.Checked := Settings.CheckUpdates; cbCheckUpdates.Checked := Settings.CheckUpdates;
if not Settings.HasCheckUpdates then if not Settings.HasCheckUpdates then
@ -447,6 +493,8 @@ function TMainForm.CreateDefaultProfile: TProfile;
begin begin
{ Default button functions are assigned during UpdateButton } { Default button functions are assigned during UpdateButton }
Result := TProfile.Create; Result := TProfile.Create;
Result.Name := DefaultProfileName;
Result.IsTemporary := True;
end; end;
@ -460,6 +508,9 @@ begin
for buttonIndex := 0 to Pred(LED_COUNT) do for buttonIndex := 0 to Pred(LED_COUNT) do
UpdateButton(ActiveProfile, buttonIndex); UpdateButton(ActiveProfile, buttonIndex);
if Assigned(StateConsumerTask) then
StateConsumerTask.Comm.Send(TM_LOADPROFILE, ActiveProfile);
end; end;
@ -496,16 +547,75 @@ begin
end; end;
procedure TMainForm.AddProfile(AProfile: TProfile);
begin
Profiles.Add(AProfile);
cmbProfiles.Items.AddObject(AProfile.Name, AProfile);
SetActiveProfile(AProfile);
end;
procedure TMainForm.UpdateProfile(AProfile: TProfile);
var
itemIndex: Integer;
oldItemIndex: Integer;
begin
itemIndex := cmbProfiles.Items.IndexOfObject(AProfile);
if itemIndex > -1 then
begin
oldItemIndex := cmbProfiles.ItemIndex;
FLockChangeProfile := True;
try
cmbProfiles.Items[itemIndex] := AProfile.Name;
cmbProfiles.ItemIndex := oldItemIndex;
finally
FLockChangeProfile := False;
end;
end;
end;
procedure TMainForm.DeleteProfile(AProfile: TProfile; ASetActiveProfile: Boolean);
var
itemIndex: Integer;
begin
if AProfile = ActiveProfile then
FActiveProfile := nil;
itemIndex := cmbProfiles.Items.IndexOfObject(AProfile);
if itemIndex > -1 then
begin
Profiles.Remove(AProfile);
cmbProfiles.Items.Delete(itemIndex);
if Profiles.Count = 0 then
AddProfile(CreateDefaultProfile);
if ASetActiveProfile then
begin
if itemIndex >= Profiles.Count then
itemIndex := Pred(Profiles.Count);
FLockChangeProfile := True;
try
cmbProfiles.ItemIndex := itemIndex;
SetActiveProfile(TProfile(cmbProfiles.Items.Objects[itemIndex]));
finally
FLockChangeProfile := False;
end;
end;
end;
end;
procedure TMainForm.cmbProfilesClick(Sender: TObject); procedure TMainForm.cmbProfilesClick(Sender: TObject);
begin begin
if not FLoadingProfiles then if not FLockChangeProfile then
begin begin
if cmbProfiles.ItemIndex > -1 then if cmbProfiles.ItemIndex > -1 then
FActiveProfile := TProfile(cmbProfiles.Items.Objects[cmbProfiles.ItemIndex]) SetActiveProfile(TProfile(cmbProfiles.Items.Objects[cmbProfiles.ItemIndex]));
else
FActiveProfile := nil;
LoadActiveProfile;
end; end;
end; end;
@ -525,6 +635,33 @@ begin
end; end;
procedure TMainForm.SetActiveProfile(const Value: TProfile);
begin
if Value <> FActiveProfile then
begin
FActiveProfile := Value;
if Assigned(ActiveProfile) then
begin
if Settings.ActiveProfile <> ActiveProfile.Name then
begin
Settings.ActiveProfile := ActiveProfile.Name;
SaveSettings;
end;
FLockChangeProfile := True;
try
cmbProfiles.ItemIndex := cmbProfiles.Items.IndexOfObject(ActiveProfile);
finally
FLockChangeProfile := False;
end;
LoadActiveProfile;
end;
end;
end;
procedure TMainForm.SetDeviceState(const AMessage: string; AFound: Boolean); procedure TMainForm.SetDeviceState(const AMessage: string; AFound: Boolean);
begin begin
lblG940ThrottleState.Caption := AMessage; lblG940ThrottleState.Caption := AMessage;
@ -537,20 +674,74 @@ begin
end; end;
procedure TMainForm.SetFSXState(const AMessage: string; AConnected: Boolean);
begin
lblFSXState.Caption := AMessage;
lblFSXState.Update;
imgFSXStateConnected.Visible := AConnected;
imgFSXStateNotConnected.Visible := not AConnected;
end;
procedure TMainForm.LEDButtonClick(Sender: TObject); procedure TMainForm.LEDButtonClick(Sender: TObject);
function GetUniqueProfileName(const AName: string): string;
var
counter: Integer;
begin
Result := AName;
counter := 0;
while Assigned(Profiles.Find(Result)) do
begin
Inc(counter);
Result := Format('%s (%d)', [AName, counter]);
end;
end;
var var
buttonIndex: NativeInt; buttonIndex: NativeInt;
profile: TProfile;
newProfile: Boolean;
begin begin
if not Assigned(ActiveProfile) then if not Assigned(ActiveProfile) then
exit; exit;
buttonIndex := (Sender as TComponent).Tag; { Behaviour similar to the Windows System Sounds control panel;
if TButtonFunctionForm.Execute(ActiveProfile, buttonIndex) then when a change occurs, create a temporary profile "(modified)"
so the original profile can still be selected }
if not ActiveProfile.IsTemporary then
begin begin
UpdateButton(ActiveProfile, buttonIndex); profile := TProfile.Create;
FStateConsumerTask.Comm.Send(TM_LOADPROFILE, ActiveProfile); profile.Assign(ActiveProfile);
profile.Name := GetUniqueProfileName(profile.Name + ProfilePostfixModified);
profile.IsTemporary := True;
newProfile := True;
end else
begin
profile := ActiveProfile;
newProfile := False;
end;
buttonIndex := (Sender as TComponent).Tag;
if TButtonFunctionForm.Execute(profile, buttonIndex) then
begin
if newProfile then
AddProfile(profile);
SaveProfiles; SaveProfiles;
UpdateButton(profile, buttonIndex);
if Assigned(StateConsumerTask) then
StateConsumerTask.Comm.Send(TM_LOADPROFILE, profile);
end else
begin
if newProfile then
FreeAndNil(profile);
end; end;
end; end;
@ -622,11 +813,11 @@ begin
try try
latestVersion := httpClient.Get('http://g940.x2software.net/version'); latestVersion := httpClient.Get('http://g940.x2software.net/version');
if VersionIsNewer(Format('%d.%d.%d', [App.Version.Major, App.Version.Minor, App.Version.Release]), latestVersion) then if VersionIsNewer(Format('%d.%d.%d', [App.Version.Major, App.Version.Minor, App.Version.Release]), latestVersion) then
ATask.Comm.Send(MSG_UPDATE, latestVersion) ATask.Comm.Send(TM_UPDATE, latestVersion)
else else
begin begin
if ATask.Param.ByName('ReportNoUpdates').AsBoolean then if ATask.Param.ByName('ReportNoUpdates').AsBoolean then
ATask.Comm.Send(MSG_NOUPDATE, True); ATask.Comm.Send(TM_NOUPDATE, True);
end; end;
msgSent := True; msgSent := True;
@ -638,7 +829,82 @@ begin
on E:Exception do on E:Exception do
begin begin
if not msgSent then if not msgSent then
ATask.Comm.Send(MSG_NOUPDATE, False); ATask.Comm.Send(TM_NOUPDATE, False);
end;
end;
end;
procedure TMainForm.btnSaveProfileClick(Sender: TObject);
var
name: string;
profile: TProfile;
existingProfile: TProfile;
newProfile: TProfile;
begin
name := '';
profile := ActiveProfile;
existingProfile := nil;
repeat
if InputQuery('Save profile as', 'Save this profile as:', name) then
begin
existingProfile := Profiles.Find(name);
if Assigned(existingProfile) then
begin
case MessageBox(Self.Handle, PChar(Format('A profile named "%s" exists, do you want to overwrite it?', [name])),
'Save profile as', MB_ICONQUESTION or MB_YESNOCANCEL) of
ID_YES:
break;
ID_CANCEL:
exit;
end;
end else
break;
end else
exit;
until False;
if Assigned(existingProfile) then
begin
existingProfile.Assign(profile);
existingProfile.Name := name;
UpdateProfile(existingProfile);
SetActiveProfile(existingProfile);
if profile.IsTemporary then
DeleteProfile(profile, False);
end else
begin
if profile.IsTemporary then
begin
profile.Name := name;
profile.IsTemporary := False;
UpdateProfile(profile);
end else
begin
newProfile := TProfile.Create;
newProfile.Assign(profile);
newProfile.Name := name;
AddProfile(newProfile);
end;
end;
SaveProfiles;
end;
procedure TMainForm.btnDeleteProfileClick(Sender: TObject);
begin
if Assigned(ActiveProfile) then
begin
if MessageBox(Self.Handle, PChar(Format('Do you want to remove the profile named "%s"?', [ActiveProfile.Name])),
'Remove profile', MB_ICONQUESTION or MB_YESNO) = ID_YES then
begin
DeleteProfile(ActiveProfile, True);
SaveProfiles;
end; end;
end; end;
end; end;
@ -666,15 +932,18 @@ procedure TMainForm.EventMonitorMessage(const task: IOmniTaskControl; const msg:
begin begin
case msg.MsgID of case msg.MsgID of
TM_NOTIFY_DEVICESTATE: TM_NOTIFY_DEVICESTATE:
HandleDeviceStateMessage(task, msg); HandleDeviceStateMessage(msg);
MSG_UPDATE: TM_FSXSTATE:
HandleFSXStateMessage(msg);
TM_UPDATE:
if MessageBox(Self.Handle, PChar('Version ' + msg.MsgData + ' is available on the G940 LED Control website.'#13#10 + if MessageBox(Self.Handle, PChar('Version ' + msg.MsgData + ' is available on the G940 LED Control website.'#13#10 +
'Do you want to open the website now?'), 'Update available', 'Do you want to open the website now?'), 'Update available',
MB_YESNO or MB_ICONINFORMATION) = ID_YES then MB_YESNO or MB_ICONINFORMATION) = ID_YES then
ShellExecute(Self.Handle, 'open', PChar('http://g940.x2software.net/category/releases/'), nil, nil, SW_SHOWNORMAL); ShellExecute(Self.Handle, 'open', PChar('http://g940.x2software.net/category/releases/'), nil, nil, SW_SHOWNORMAL);
MSG_NOUPDATE: TM_NOUPDATE:
if msg.MsgData.AsBoolean then if msg.MsgData.AsBoolean then
MessageBox(Self.Handle, 'You are using the latest version.', 'No update available', MB_OK or MB_ICONINFORMATION) MessageBox(Self.Handle, 'You are using the latest version.', 'No update available', MB_OK or MB_ICONINFORMATION)
else else
@ -694,17 +963,37 @@ begin
end; end;
procedure TMainForm.HandleDeviceStateMessage(ATask: IOmniTaskControl; AMessage: TOmniMessage); procedure TMainForm.HandleDeviceStateMessage(AMessage: TOmniMessage);
begin begin
case AMessage.MsgData.AsInteger of case AMessage.MsgData.AsInteger of
DEVICESTATE_SEARCHING: DEVICESTATE_SEARCHING:
SetDeviceState(TEXT_STATE_SEARCHING, False); SetDeviceState(TextStateSearching, False);
DEVICESTATE_FOUND: DEVICESTATE_FOUND:
SetDeviceState(TEXT_STATE_FOUND, True); SetDeviceState(TextStateFound, True);
DEVICESTATE_NOTFOUND: DEVICESTATE_NOTFOUND:
SetDeviceState(TEXT_STATE_NOTFOUND, False); SetDeviceState(TextStateNotFound, False);
end;
end;
procedure TMainForm.HandleFSXStateMessage(AMessage: TOmniMessage);
var
state: TFSXSimConnectState;
begin
state := TFSXSimConnectState(AMessage.MsgData.AsInteger);
case state of
scsDisconnected:
SetFSXState(TextFSXDisconnected, False);
scsConnected:
SetFSXState(TextFSXConnected, True);
scsFailed:
SetFSXState(TextFSXFailed, False);
end; end;
end; end;
@ -720,4 +1009,27 @@ begin
ShellExecute(Self.Handle, 'open', PChar(Link), nil, nil, SW_SHOWNORMAL); ShellExecute(Self.Handle, 'open', PChar(Link), nil, nil, SW_SHOWNORMAL);
end; end;
{ TFSXStateMonitorWorker }
function TFSXStateMonitorWorker.Initialize: Boolean;
begin
Result := inherited Initialize;
if Result then
TFSXSimConnectStateMonitor.Instance.Attach(Self);
end;
procedure TFSXStateMonitorWorker.Cleanup;
begin
TFSXSimConnectStateMonitor.Instance.Detach(Self);
inherited Cleanup;
end;
procedure TFSXStateMonitorWorker.ObserverStateUpdate(ANewState: TFSXSimConnectState);
begin
Task.Comm.Send(TM_FSXSTATE, Integer(ANewState));
end;
end. end.

View File

@ -29,7 +29,8 @@ uses
FSXLEDFunction in 'Units\FSXLEDFunction.pas', FSXLEDFunction in 'Units\FSXLEDFunction.pas',
LEDResources in 'Units\LEDResources.pas', LEDResources in 'Units\LEDResources.pas',
Settings in 'Units\Settings.pas', Settings in 'Units\Settings.pas',
FSXLEDFunctionWorker in 'Units\FSXLEDFunctionWorker.pas'; FSXLEDFunctionWorker in 'Units\FSXLEDFunctionWorker.pas',
FSXSimConnectStateMonitor in 'Units\FSXSimConnectStateMonitor.pas';
{$R *.res} {$R *.res}

View File

@ -8,7 +8,7 @@
<FrameworkType>VCL</FrameworkType> <FrameworkType>VCL</FrameworkType>
<ProjectVersion>13.4</ProjectVersion> <ProjectVersion>13.4</ProjectVersion>
<Base>True</Base> <Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config> <Config Condition="'$(Config)'==''">Release</Config>
<Platform Condition="'$(Platform)'==''">Win32</Platform> <Platform Condition="'$(Platform)'==''">Win32</Platform>
<TargetedPlatforms>1</TargetedPlatforms> <TargetedPlatforms>1</TargetedPlatforms>
<AppType>Application</AppType> <AppType>Application</AppType>
@ -49,6 +49,7 @@
<Base>true</Base> <Base>true</Base>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''"> <PropertyGroup Condition="'$(Base)'!=''">
<DCC_UsePackage>rtl;dbrtl;$(DCC_UsePackage)</DCC_UsePackage>
<DCC_DcuOutput>Lib</DCC_DcuOutput> <DCC_DcuOutput>Lib</DCC_DcuOutput>
<VerInfo_MajorVer>0</VerInfo_MajorVer> <VerInfo_MajorVer>0</VerInfo_MajorVer>
<DCC_ExeOutput>Bin</DCC_ExeOutput> <DCC_ExeOutput>Bin</DCC_ExeOutput>
@ -81,8 +82,9 @@
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define> <DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''"> <PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
<VerInfo_MinorVer>6</VerInfo_MinorVer> <VerInfo_MajorVer>1</VerInfo_MajorVer>
<VerInfo_Keys>CompanyName=X²Software;FileDescription=G940 LED Control;FileVersion=0.6.0.0;InternalName=;LegalCopyright=© 2011 X²Software;LegalTrademarks=;OriginalFilename=G940LEDControl.exe;ProductName=G940 LED Control;ProductVersion=0.6;Comments=</VerInfo_Keys> <VerInfo_MinorVer>0</VerInfo_MinorVer>
<VerInfo_Keys>CompanyName=X²Software;FileDescription=G940 LED Control;FileVersion=1.0.0.0;InternalName=;LegalCopyright=© 2011 X²Software;LegalTrademarks=;OriginalFilename=G940LEDControl.exe;ProductName=G940 LED Control;ProductVersion=1.0;Comments=</VerInfo_Keys>
<VerInfo_Locale>1033</VerInfo_Locale> <VerInfo_Locale>1033</VerInfo_Locale>
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File> <Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
</PropertyGroup> </PropertyGroup>
@ -144,6 +146,110 @@
<Source Name="MainSource">G940LEDControl.dpr</Source> <Source Name="MainSource">G940LEDControl.dpr</Source>
</Source> </Source>
<Excluded_Packages> <Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxCoreD16.bpl">ExpressCoreLibrary by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dclcxLibraryD16.bpl">Express Cross Platform Library by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dclcxPageControlD16.bpl">ExpressPageControl by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dclcxEditorsD16.bpl">ExpressEditors Library by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxBarD16.bpl">ExpressBars by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxRibbonD16.bpl">ExpressBars Ribbon controls by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dclcxSchedulerD16.bpl">ExpressScheduler by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxSkinsCoreD16.bpl">ExpressSkins Library by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxPSCoreD16.bpl">ExpressPrinting System by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dclcxPivotGridD16.bpl">ExpressPivotGrid by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxorgcD16.bpl">ExpressOrgChart by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxSkinsDesignHelperD16.bpl">ExpressSkins Library Uses Clause Auto Fill Helper by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinscxPCPainterD16.bpl">ExpressSkins Library Painter for PageControl by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinscxSchedulerPainterD16.bpl">ExpressSkins Library Painter for Scheduler by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinsdxBarPainterD16.bpl">ExpressSkins Library Painter for Bars by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinsdxNavBarPainterD16.bpl">ExpressSkins Library Painter for NavBar by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinsdxRibbonPainterD16.bpl">ExpressSkins Library Painter for Ribbon by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinsdxDLPainterD16.bpl">ExpressSkins Library Painter for Docking Library by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxPSdxLCLnkD16.bpl">ExpressPrinting System ReportLink for ExpressLayoutControl by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dclcxEditorFieldLinkD16.bpl">ExpressEditors FieldLink by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxBarDBNavD16.bpl">ExpressBars DBNavigator by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxBarExtDBItemsD16.bpl">ExpressBars extended DB items by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxBarExtItemsD16.bpl">ExpressBars extended items by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxTabbedMDID16.bpl">ExpressBars Tabbed MDI by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxLayoutControlD16.bpl">ExpressLayout Control by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dclcxTreeListD16.bpl">ExpressQuantumTreeList 5 by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dclcxGridD16.bpl">ExpressQuantumGrid by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dclcxVerticalGridD16.bpl">ExpressVerticalGrid by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxmdsD16.bpl">ExpressMemData by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxSpellCheckerD16.bpl">ExpressSpellChecker 2 by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dclcxSpreadSheetD16.bpl">ExpressSpreadSheet by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxDockingD16.bpl">ExpressDocking Library by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxNavBarD16.bpl">ExpressNavBar by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinBlackD16.bpl">ExpressSkins - Black Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinBlueD16.bpl">ExpressSkins - Blue Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinBlueprintD16.bpl">ExpressSkins - Blueprint Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinCaramelD16.bpl">ExpressSkins - Caramel Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinCoffeeD16.bpl">ExpressSkins - Coffee Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinDarkRoomD16.bpl">ExpressSkins - Darkroom Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinDarkSideD16.bpl">ExpressSkins - DarkSide Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinDevExpressDarkStyleD16.bpl">ExpressSkins - DevExpressDarkStyle Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinDevExpressStyleD16.bpl">ExpressSkins - DevExpressStyle Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinFoggyD16.bpl">ExpressSkins - Foggy Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinGlassOceansD16.bpl">ExpressSkins - GlassOceans Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinHighContrastD16.bpl">ExpressSkins - HighContrast Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkiniMaginaryD16.bpl">ExpressSkins - iMaginary Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinLilianD16.bpl">ExpressSkins - Lilian Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinLiquidSkyD16.bpl">ExpressSkins - LiquidSky Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinLondonLiquidSkyD16.bpl">ExpressSkins - LondonLiquidSky Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinMcSkinD16.bpl">ExpressSkins - McSkin Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinMoneyTwinsD16.bpl">ExpressSkins - MoneyTwins Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinOffice2007BlackD16.bpl">ExpressSkins - Office2007Black Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinOffice2007BlueD16.bpl">ExpressSkins - Office2007Blue Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinOffice2007GreenD16.bpl">ExpressSkins - Office2007Green Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinOffice2007PinkD16.bpl">ExpressSkins - Office2007Pink Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinOffice2007SilverD16.bpl">ExpressSkins - Office2007Silver Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinOffice2010BlackD16.bpl">ExpressSkins - Office2010Black Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinOffice2010BlueD16.bpl">ExpressSkins - Office2010Blue Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinOffice2010SilverD16.bpl">ExpressSkins - Office2010Silver Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinPumpkinD16.bpl">ExpressSkins - Pumpkin Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinSevenClassicD16.bpl">ExpressSkins - SevenClassic Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinSevenD16.bpl">ExpressSkins - Seven Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinSharpD16.bpl">ExpressSkins - Sharp Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinSharpPlusD16.bpl">ExpressSkins - SharpPlus Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinSilverD16.bpl">ExpressSkins - Silver Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinSpringTimeD16.bpl">ExpressSkins - Springtime Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinStardustD16.bpl">ExpressSkins - Stardust Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinSummer2008D16.bpl">ExpressSkins - Summer2008 Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinTheAsphaltWorldD16.bpl">ExpressSkins - TheAsphaltWorld Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinValentineD16.bpl">ExpressSkins - Valentine Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinVS2010D16.bpl">ExpressSkins - VS2010 Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinWhiteprintD16.bpl">ExpressSkins - Whiteprint Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinXmas2008BlueD16.bpl">ExpressSkins - Xmas2008Blue Skin by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxPSLnksD16.bpl">ExpressPrinting System ReportLinks (Standard) by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxPScxPCProdD16.bpl">ExpressPrinting System ContainerProducer for ExpressPageControl by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxdbtrD16.bpl">ExpressDBTree by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxtrmdD16.bpl">ExpressTreePrintedDataSet by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxDBOrD16.bpl">ExpressDBOrgChart by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxFlowChartD16.bpl">ExpressFlowChart by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dclcxPageControldxBarPopupMenuD16.bpl">ExpressPageControl dxBar Popup Menu by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dclcxBarEditItemD16.bpl">ExpressBars cxEditor item by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dclcxSchedulerGridD16.bpl">ExpressScheduler connection to ExpressQuantumGrid by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dclcxTreeListdxBarPopupMenuD16.bpl">ExpressQuantumTreeList 5 dxBar Built-In Menu by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxSkinscxEditorsHelperD16.bpl">ExpressSkins Library Uses Clause Auto Fill Helper for ExpressEditors by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxSkinscxPCPainterD16.bpl">ExpressSkins Library Uses Clause Auto Fill Helper for PageControl Painter by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxSkinscxSchedulerPainterD16.bpl">ExpressSkins Library Uses Clause Auto Fill Helper for Scheduler Painter by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxSkinsdxBarsPaintersD16.bpl">ExpressSkins Library Uses Clause Auto Fill Helper for Bars Painters by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxSkinsdxNavBarPainterD16.bpl">ExpressSkins Library Uses Clause Auto Fill Helper for NavBar Painter by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxSkinsdxRibbonPaintersD16.bpl">ExpressSkins Library Uses Clause Auto Fill Helper for Ribbon Painters by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxPScxCommonD16.bpl">ExpressPrinting System Cross Platform Library by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxPScxExtCommonD16.bpl">ExpressPrinting System Extended Cross Platform Library by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxPScxPivotGridLnkD16.bpl">ExpressPrinting System ReportLink for ExpressPivotGrid by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxPScxSchedulerLnkD16.bpl">ExpressPrinting System ReportLink for ExpressScheduler by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxPScxSSLnkD16.bpl">ExpressPrinting System ReportLink for ExpressSpreadSheet by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxPScxTLLnkD16.bpl">ExpressPrinting System ReportLink for ExpressQuantumTreeList by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxPScxVGridLnkD16.bpl">ExpressPrinting System ReportLink for ExpressVerticalGrid by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxPSdxDBOCLnkD16.bpl">ExpressPrinting System ReportLinks for ExpressDBOrgChart by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxPSdxDBTVLnkD16.bpl">ExpressPrinting System ReportLink for ExpressDBTree by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxPSdxFCLnkD16.bpl">ExpressPrinting System ReportLinks for ExpressFlowChart by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxPScxGridLnkD16.bpl">ExpressPrinting System ReportLink for ExpressQuantumGrid by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxPSdxOCLnkD16.bpl">ExpressPrinting System ReportLinks for ExpressOrgChart by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxPSPrVwAdvD16.bpl">ExpressPrinting System Advanced Preview Window by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxPSPrVwRibbonD16.bpl">ExpressPrinting System Ribbon Preview Window by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dclcxPivotGridChartD16.bpl">ExpressPivotGrid 2 connection to ExpressQuantumGrid Chart View by Developer Express Inc.</Excluded_Packages>
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dclcxPivotGridOLAPD16.bpl">ExpressPivotGrid 2 OLAP by Developer Express Inc.</Excluded_Packages> <Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dclcxPivotGridOLAPD16.bpl">ExpressPivotGrid 2 OLAP by Developer Express Inc.</Excluded_Packages>
</Excluded_Packages> </Excluded_Packages>
</Delphi.Personality> </Delphi.Personality>
@ -192,6 +298,7 @@
<DCCReference Include="Units\LEDResources.pas"/> <DCCReference Include="Units\LEDResources.pas"/>
<DCCReference Include="Units\Settings.pas"/> <DCCReference Include="Units\Settings.pas"/>
<DCCReference Include="Units\FSXLEDFunctionWorker.pas"/> <DCCReference Include="Units\FSXLEDFunctionWorker.pas"/>
<DCCReference Include="Units\FSXSimConnectStateMonitor.pas"/>
<BuildConfiguration Include="Debug"> <BuildConfiguration Include="Debug">
<Key>Cfg_2</Key> <Key>Cfg_2</Key>
<CfgParent>Base</CfgParent> <CfgParent>Base</CfgParent>

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@ -106,20 +106,61 @@ begin
V0_FUNCTIONFSX_ENGINEANTIICE: SetButton(FSXProviderUID, FSXFunctionUIDEngineAntiIce); V0_FUNCTIONFSX_ENGINEANTIICE: SetButton(FSXProviderUID, FSXFunctionUIDEngineAntiIce);
V0_FUNCTIONFSX_AUTOPILOT: V0_FUNCTIONFSX_AUTOPILOT:
begin begin
{ The only exception regarding states; the new default is Amber / Off } { The new default is Green / Off }
SetButton(FSXProviderUID, FSXFunctionUIDAutoPilot); SetButton(FSXProviderUID, FSXFunctionUIDAutoPilot);
AButton.SetStateColor(FSXStateUIDOn, lcGreen); AButton.SetStateColor(FSXStateUIDOn, lcGreen);
AButton.SetStateColor(FSXStateUIDOff, lcRed); AButton.SetStateColor(FSXStateUIDOff, lcRed);
end; end;
V0_FUNCTIONFSX_FUELPUMP: SetButton(FSXProviderUID, FSXFunctionUIDFuelPump);
V0_FUNCTIONFSX_TAILHOOK: SetButton(FSXProviderUID, FSXFunctionUIDTailHook); V0_FUNCTIONFSX_TAILHOOK: SetButton(FSXProviderUID, FSXFunctionUIDTailHook);
V0_FUNCTIONFSX_AUTOPILOT_AMBER: SetButton(FSXProviderUID, FSXFunctionUIDAutoPilot); V0_FUNCTIONFSX_AUTOPILOT_AMBER:
V0_FUNCTIONFSX_AUTOPILOT_HEADING: SetButton(FSXProviderUID, FSXFunctionUIDAutoPilotHeading); begin
V0_FUNCTIONFSX_AUTOPILOT_APPROACH: SetButton(FSXProviderUID, FSXFunctionUIDAutoPilotApproach); { The new default is Green / Off }
V0_FUNCTIONFSX_AUTOPILOT_BACKCOURSE: SetButton(FSXProviderUID, FSXFunctionUIDAutoPilotBackcourse); SetButton(FSXProviderUID, FSXFunctionUIDAutoPilot);
V0_FUNCTIONFSX_AUTOPILOT_ALTITUDE: SetButton(FSXProviderUID, FSXFunctionUIDAutoPilotAltitude); AButton.SetStateColor(FSXStateUIDOn, lcAmber);
V0_FUNCTIONFSX_AUTOPILOT_NAV: SetButton(FSXProviderUID, FSXFunctionUIDAutoPilotNav); AButton.SetStateColor(FSXStateUIDOff, lcOff);
end;
V0_FUNCTIONFSX_AUTOPILOT_HEADING:
begin
{ The new default is Green / Off }
SetButton(FSXProviderUID, FSXFunctionUIDAutoPilotHeading);
AButton.SetStateColor(FSXStateUIDOn, lcAmber);
AButton.SetStateColor(FSXStateUIDOff, lcOff);
end;
V0_FUNCTIONFSX_AUTOPILOT_APPROACH:
begin
{ The new default is Green / Off }
SetButton(FSXProviderUID, FSXFunctionUIDAutoPilotApproach);
AButton.SetStateColor(FSXStateUIDOn, lcAmber);
AButton.SetStateColor(FSXStateUIDOff, lcOff);
end;
V0_FUNCTIONFSX_AUTOPILOT_BACKCOURSE:
begin
{ The new default is Green / Off }
SetButton(FSXProviderUID, FSXFunctionUIDAutoPilotBackcourse);
AButton.SetStateColor(FSXStateUIDOn, lcAmber);
AButton.SetStateColor(FSXStateUIDOff, lcOff);
end;
V0_FUNCTIONFSX_AUTOPILOT_ALTITUDE:
begin
{ The new default is Green / Off }
SetButton(FSXProviderUID, FSXFunctionUIDAutoPilotAltitude);
AButton.SetStateColor(FSXStateUIDOn, lcAmber);
AButton.SetStateColor(FSXStateUIDOff, lcOff);
end;
V0_FUNCTIONFSX_AUTOPILOT_NAV:
begin
{ The new default is Green / Off }
SetButton(FSXProviderUID, FSXFunctionUIDAutoPilotNav);
AButton.SetStateColor(FSXStateUIDOn, lcAmber);
AButton.SetStateColor(FSXStateUIDOff, lcOff);
end;
V0_FUNCTIONFSX_TAXILIGHTS: SetButton(FSXProviderUID, FSXFunctionUIDTaxiLights); V0_FUNCTIONFSX_TAXILIGHTS: SetButton(FSXProviderUID, FSXFunctionUIDTaxiLights);
V0_FUNCTIONFSX_RECOGNITIONLIGHTS: SetButton(FSXProviderUID, FSXFunctionUIDRecognitionLights); V0_FUNCTIONFSX_RECOGNITIONLIGHTS: SetButton(FSXProviderUID, FSXFunctionUIDRecognitionLights);
V0_FUNCTIONFSX_DEICE: SetButton(FSXProviderUID, FSXFunctionUIDDeIce); V0_FUNCTIONFSX_DEICE: SetButton(FSXProviderUID, FSXFunctionUIDDeIce);

View File

@ -13,83 +13,89 @@ type
procedure RegisterStates; override; procedure RegisterStates; override;
end; end;
TCustomFSXInvertedOnOffFunction = class(TCustomFSXFunction)
protected
procedure RegisterStates; override;
end;
{ Systems }
TCustomFSXSystemsFunction = class(TCustomFSXFunction)
protected
function GetCategoryName: string; override;
end;
TFSXBatteryMasterFunction = class(TCustomFSXOnOffFunction)
protected
function GetCategoryName: string; override;
function GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass; override;
end;
TFSXDeIceFunction = class(TCustomFSXInvertedOnOffFunction)
protected
function GetCategoryName: string; override;
function GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass; override;
end;
TFSXExitDoorFunction = class(TCustomFSXSystemsFunction)
protected
procedure RegisterStates; override;
function GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass; override;
end;
TFSXGearFunction = class(TCustomFSXSystemsFunction)
protected
procedure RegisterStates; override;
function GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass; override;
end;
TFSXParkingBrakeFunction = class(TCustomFSXInvertedOnOffFunction)
protected
function GetCategoryName: string; override;
function GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass; override;
end;
TFSXPressDumpSwitchFunction = class(TCustomFSXInvertedOnOffFunction)
protected
function GetCategoryName: string; override;
function GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass; override;
end;
TFSXTailHookFunction = class(TCustomFSXSystemsFunction)
protected
procedure RegisterStates; override;
function GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass; override;
end;
{ Engines }
TFSXEngineAntiIceFunction = class(TCustomFSXFunction)
protected
function GetCategoryName: string; override;
procedure RegisterStates; override;
function GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass; override;
end;
{ Misc }
TFSXEngineFunction = class(TCustomFSXFunction) TFSXEngineFunction = class(TCustomFSXFunction)
protected protected
function GetCategoryName: string; override;
procedure RegisterStates; override; procedure RegisterStates; override;
function GetWorkerClass: TCustomLEDFunctionWorkerClass; override; function GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass; override;
end; end;
TFSXGearFunction = class(TCustomFSXFunction)
protected
procedure RegisterStates; override;
function GetWorkerClass: TCustomLEDFunctionWorkerClass; override;
end;
TFSXParkingBrakeFunction = class(TCustomFSXOnOffFunction)
protected
function GetWorkerClass: TCustomLEDFunctionWorkerClass; override;
end;
TFSXExitDoorFunction = class(TCustomFSXFunction)
protected
procedure RegisterStates; override;
function GetWorkerClass: TCustomLEDFunctionWorkerClass; override;
end;
TFSXTailHookFunction = class(TCustomFSXFunction)
protected
procedure RegisterStates; override;
function GetWorkerClass: TCustomLEDFunctionWorkerClass; override;
end;
{ Control surfaces }
TFSXFlapsFunction = class(TCustomFSXFunction) TFSXFlapsFunction = class(TCustomFSXFunction)
protected protected
function GetCategoryName: string; override;
procedure RegisterStates; override; procedure RegisterStates; override;
function GetWorkerClass: TCustomLEDFunctionWorkerClass; override; function GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass; override;
end; end;
TFSXSpoilersFunction = class(TCustomFSXFunction) TFSXSpoilersFunction = class(TCustomFSXFunction)
protected protected
function GetCategoryName: string; override;
procedure RegisterStates; override; procedure RegisterStates; override;
function GetWorkerClass: TCustomLEDFunctionWorkerClass; override; function GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass; override;
end;
TFSXBatteryMasterFunction = class(TCustomFSXFunction)
protected
procedure RegisterStates; override;
function GetWorkerClass: TCustomLEDFunctionWorkerClass; override;
end;
TFSXAvionicsMasterFunction = class(TCustomFSXFunction)
protected
procedure RegisterStates; override;
function GetWorkerClass: TCustomLEDFunctionWorkerClass; override;
end;
TFSXPressDumpSwitchFunction = class(TCustomFSXFunction)
protected
procedure RegisterStates; override;
function GetWorkerClass: TCustomLEDFunctionWorkerClass; override;
end;
TFSXEngineAntiIceFunction = class(TCustomFSXFunction)
protected
procedure RegisterStates; override;
function GetWorkerClass: TCustomLEDFunctionWorkerClass; override;
end;
TFSXFuelPumpFunction = class(TCustomFSXFunction)
protected
procedure RegisterStates; override;
function GetWorkerClass: TCustomLEDFunctionWorkerClass; override;
end;
TFSXDeIceFunction = class(TCustomFSXFunction)
protected
procedure RegisterStates; override;
function GetWorkerClass: TCustomLEDFunctionWorkerClass; override;
end; end;
@ -98,8 +104,8 @@ type
protected protected
function GetCategoryName: string; override; function GetCategoryName: string; override;
function GetWorkerClass: TCustomLEDFunctionWorkerClass; override; function GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass; override;
function DoCreateWorker(ASettings: ILEDFunctionWorkerSettings): TCustomLEDFunctionWorker; override; function DoCreateWorker(ASettings: ILEDFunctionWorkerSettings; const APreviousState: string = ''): TCustomLEDFunctionWorker; override;
protected protected
function GetLightMask: Integer; virtual; abstract; function GetLightMask: Integer; virtual; abstract;
end; end;
@ -143,43 +149,46 @@ type
{ Autopilot } { Autopilot }
TCustomFSXAutoPilotFunction = class(TCustomFSXFunction) TCustomFSXAutoPilotFunction = class(TCustomFSXFunction)
protected protected
procedure RegisterStates; override;
function GetCategoryName: string; override; function GetCategoryName: string; override;
end; end;
TFSXAutoPilotFunction = class(TCustomFSXAutoPilotFunction) TFSXAutoPilotFunction = class(TCustomFSXAutoPilotFunction)
protected protected
procedure RegisterStates; override; function GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass; override;
function GetWorkerClass: TCustomLEDFunctionWorkerClass; override;
end; end;
TFSXAutoPilotHeadingFunction = class(TCustomFSXAutoPilotFunction) TFSXAutoPilotHeadingFunction = class(TCustomFSXAutoPilotFunction)
protected protected
procedure RegisterStates; override; function GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass; override;
function GetWorkerClass: TCustomLEDFunctionWorkerClass; override;
end; end;
TFSXAutoPilotApproachFunction = class(TCustomFSXAutoPilotFunction) TFSXAutoPilotApproachFunction = class(TCustomFSXAutoPilotFunction)
protected protected
procedure RegisterStates; override; function GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass; override;
function GetWorkerClass: TCustomLEDFunctionWorkerClass; override;
end; end;
TFSXAutoPilotBackcourseFunction = class(TCustomFSXAutoPilotFunction) TFSXAutoPilotBackcourseFunction = class(TCustomFSXAutoPilotFunction)
protected protected
procedure RegisterStates; override; function GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass; override;
function GetWorkerClass: TCustomLEDFunctionWorkerClass; override;
end; end;
TFSXAutoPilotAltitudeFunction = class(TCustomFSXAutoPilotFunction) TFSXAutoPilotAltitudeFunction = class(TCustomFSXAutoPilotFunction)
protected protected
procedure RegisterStates; override; function GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass; override;
function GetWorkerClass: TCustomLEDFunctionWorkerClass; override;
end; end;
TFSXAutoPilotNavFunction = class(TCustomFSXAutoPilotFunction) TFSXAutoPilotNavFunction = class(TCustomFSXAutoPilotFunction)
protected protected
procedure RegisterStates; override; function GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass; override;
function GetWorkerClass: TCustomLEDFunctionWorkerClass; override; end;
{ Radios }
TFSXAvionicsMasterFunction = class(TCustomFSXOnOffFunction)
protected
function GetCategoryName: string; override;
function GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass; override;
end; end;
@ -200,21 +209,59 @@ begin
end; end;
{ TFSXEngineFunction } { TCustomFSXInvertedOnOffFunction }
procedure TFSXEngineFunction.RegisterStates; procedure TCustomFSXInvertedOnOffFunction.RegisterStates;
begin begin
RegisterState(TLEDState.Create(FSXStateUIDEngineNoEngines, FSXStateDisplayNameEngineNoEngines, lcOff)); RegisterState(TLEDState.Create(FSXStateUIDOn, FSXStateDisplayNameOn, lcRed));
RegisterState(TLEDState.Create(FSXStateUIDEngineAllRunning, FSXStateDisplayNameEngineAllRunning, lcGreen)); RegisterState(TLEDState.Create(FSXStateUIDOff, FSXStateDisplayNameOff, lcGreen));
RegisterState(TLEDState.Create(FSXStateUIDEnginePartiallyRunning, FSXStateDisplayNameEnginePartiallyRunning, lcAmber));
RegisterState(TLEDState.Create(FSXStateUIDEngineAllOff, FSXStateDisplayNameEngineAllOff, lcRed));
RegisterState(TLEDState.Create(FSXStateUIDEngineFailed, FSXStateDisplayNameEngineFailed, lcFlashingRedNormal));
RegisterState(TLEDState.Create(FSXStateUIDEngineOnFire, FSXStateDisplayNameEngineOnFire, lcFlashingRedFast));
end; end;
function TFSXEngineFunction.GetWorkerClass: TCustomLEDFunctionWorkerClass; { TCustomFSXSystemsFunction }
function TCustomFSXSystemsFunction.GetCategoryName: string;
begin begin
Result := TFSXEngineFunctionWorker; Result := FSXCategorySystems;
end;
{ TFSXBatteryMasterFunction }
function TFSXBatteryMasterFunction.GetCategoryName: string;
begin
Result := FSXCategorySystems;
end;
function TFSXBatteryMasterFunction.GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass;
begin
Result := TFSXBatteryMasterFunctionWorker;
end;
{ TFSXDeIceFunction }
function TFSXDeIceFunction.GetCategoryName: string;
begin
Result := FSXCategorySystems;
end;
function TFSXDeIceFunction.GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass;
begin
Result := TFSXDeIceFunctionWorker;
end;
{ TFSXExitDoorFunction }
procedure TFSXExitDoorFunction.RegisterStates;
begin
RegisterState(TLEDState.Create(FSXStateUIDExitDoorClosed, FSXStateDisplayNameExitDoorClosed, lcGreen));
RegisterState(TLEDState.Create(FSXStateUIDExitDoorBetween, FSXStateDisplayNameExitDoorBetween, lcAmber));
RegisterState(TLEDState.Create(FSXStateUIDExitDoorOpen, FSXStateDisplayNameExitDoorOpen, lcRed));
end;
function TFSXExitDoorFunction.GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass;
begin
Result := TFSXExitDoorFunctionWorker;
end; end;
@ -230,31 +277,33 @@ begin
end; end;
function TFSXGearFunction.GetWorkerClass: TCustomLEDFunctionWorkerClass; function TFSXGearFunction.GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass;
begin begin
Result := TFSXGearFunctionWorker; Result := TFSXGearFunctionWorker;
end; end;
{ TFSXParkingBrakeFunction } { TFSXParkingBrakeFunction }
function TFSXParkingBrakeFunction.GetWorkerClass: TCustomLEDFunctionWorkerClass; function TFSXParkingBrakeFunction.GetCategoryName: string;
begin
Result := FSXCategorySystems;
end;
function TFSXParkingBrakeFunction.GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass;
begin begin
Result := TFSXParkingBrakeFunctionWorker; Result := TFSXParkingBrakeFunctionWorker;
end; end;
{ TFSXExitDoorFunction } { TFSXPressDumpSwitchFunction }
procedure TFSXExitDoorFunction.RegisterStates; function TFSXPressDumpSwitchFunction.GetCategoryName: string;
begin begin
RegisterState(TLEDState.Create(FSXStateUIDExitDoorClosed, FSXStateDisplayNameExitDoorClosed, lcGreen)); Result := FSXCategorySystems;
RegisterState(TLEDState.Create(FSXStateUIDExitDoorBetween, FSXStateDisplayNameExitDoorBetween, lcAmber));
RegisterState(TLEDState.Create(FSXStateUIDExitDoorOpen, FSXStateDisplayNameExitDoorOpen, lcRed));
end; end;
function TFSXPressDumpSwitchFunction.GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass;
function TFSXExitDoorFunction.GetWorkerClass: TCustomLEDFunctionWorkerClass;
begin begin
Result := TFSXExitDoorFunctionWorker; Result := TFSXPressDumpSwitchFunctionWorker;
end; end;
@ -267,29 +316,89 @@ begin
end; end;
function TFSXTailHookFunction.GetWorkerClass: TCustomLEDFunctionWorkerClass; function TFSXTailHookFunction.GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass;
begin begin
Result := TFSXTailHookFunctionWorker; Result := TFSXTailHookFunctionWorker;
end; end;
{ TFSXFlapsFunction } { TFSXEngineAntiIceFunction }
procedure TFSXFlapsFunction.RegisterStates; function TFSXEngineAntiIceFunction.GetCategoryName: string;
begin begin
RegisterState(TLEDState.Create(FSXStateUIDFlapsNotAvailable, FSXStateDisplayNameFlapsNotAvailable, lcOff)); Result := FSXCategoryEngines;
RegisterState(TLEDState.Create(FSXStateUIDFlapsRetracted, FSXStateDisplayNameFlapsRetracted, lcGreen));
RegisterState(TLEDState.Create(FSXStateUIDFlapsBetween, FSXStateDisplayNameFlapsBetween, lcAmber));
RegisterState(TLEDState.Create(FSXStateUIDFlapsExtended, FSXStateDisplayNameFlapsExtended, lcRed));
end; end;
function TFSXFlapsFunction.GetWorkerClass: TCustomLEDFunctionWorkerClass; procedure TFSXEngineAntiIceFunction.RegisterStates;
begin
RegisterState(TLEDState.Create(FSXStateUIDEngineAntiIceNoEngines, FSXStateDisplayNameEngineAntiIceNoEngines, lcOff));
RegisterState(TLEDState.Create(FSXStateUIDEngineAntiIceAll, FSXStateDisplayNameEngineAntiIceAll, lcRed));
RegisterState(TLEDState.Create(FSXStateUIDEngineAntiIcePartial, FSXStateDisplayNameEngineAntiIcePartial, lcAmber));
RegisterState(TLEDState.Create(FSXStateUIDEngineAntiIceNone, FSXStateDisplayNameEngineAntiIceNone, lcGreen));
end;
function TFSXEngineAntiIceFunction.GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass;
begin
Result := TFSXEngineAntiIceFunctionWorker;
end;
{ TFSXEngineFunction }
function TFSXEngineFunction.GetCategoryName: string;
begin
Result := FSXCategoryEngines;
end;
procedure TFSXEngineFunction.RegisterStates;
begin
RegisterState(TLEDState.Create(FSXStateUIDEngineNoEngines, FSXStateDisplayNameEngineNoEngines, lcOff));
RegisterState(TLEDState.Create(FSXStateUIDEngineAllRunning, FSXStateDisplayNameEngineAllRunning, lcGreen));
RegisterState(TLEDState.Create(FSXStateUIDEnginePartiallyRunning, FSXStateDisplayNameEnginePartiallyRunning, lcAmber));
RegisterState(TLEDState.Create(FSXStateUIDEngineAllOff, FSXStateDisplayNameEngineAllOff, lcRed));
RegisterState(TLEDState.Create(FSXStateUIDEngineFailed, FSXStateDisplayNameEngineFailed, lcFlashingRedNormal));
RegisterState(TLEDState.Create(FSXStateUIDEngineOnFire, FSXStateDisplayNameEngineOnFire, lcFlashingRedFast));
end;
function TFSXEngineFunction.GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass;
begin
Result := TFSXEngineFunctionWorker;
end;
{ TFSXFlapsFunction }
function TFSXFlapsFunction.GetCategoryName: string;
begin
Result := FSXCategoryControlSurfaces;
end;
procedure TFSXFlapsFunction.RegisterStates;
begin
RegisterState(TLEDState.Create(FSXStateUIDFlapsNotAvailable, FSXStateDisplayNameFlapsNotAvailable, lcOff));
RegisterState(TLEDState.Create(FSXStateUIDFlapsRetracted, FSXStateDisplayNameFlapsRetracted, lcGreen));
RegisterState(TLEDState.Create(FSXStateUIDFlapsBetween, FSXStateDisplayNameFlapsBetween, lcAmber));
RegisterState(TLEDState.Create(FSXStateUIDFlapsExtended, FSXStateDisplayNameFlapsExtended, lcRed));
RegisterState(TLEDState.Create(FSXStateUIDFlapsSpeedExceeded, FSXStateDisplayNameFlapsSpeedExceeded, lcFlashingAmberNormal));
RegisterState(TLEDState.Create(FSXStateUIDFlapsDamageBySpeed, FSXStateDisplayNameFlapsDamageBySpeed, lcFlashingRedFast));
end;
function TFSXFlapsFunction.GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass;
begin begin
Result := TFSXFlapsFunctionWorker; Result := TFSXFlapsFunctionWorker;
end; end;
{ TFSXSpoilersFunction } { TFSXSpoilersFunction }
function TFSXSpoilersFunction.GetCategoryName: string;
begin
Result := FSXCategoryControlSurfaces;
end;
procedure TFSXSpoilersFunction.RegisterStates; procedure TFSXSpoilersFunction.RegisterStates;
begin begin
RegisterState(TLEDState.Create(FSXStateUIDSpoilersNotAvailable, FSXStateDisplayNameSpoilersNotAvailable, lcOff)); RegisterState(TLEDState.Create(FSXStateUIDSpoilersNotAvailable, FSXStateDisplayNameSpoilersNotAvailable, lcOff));
@ -299,90 +408,12 @@ begin
end; end;
function TFSXSpoilersFunction.GetWorkerClass: TCustomLEDFunctionWorkerClass; function TFSXSpoilersFunction.GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass;
begin begin
Result := TFSXSpoilersFunctionWorker; Result := TFSXSpoilersFunctionWorker;
end; end;
{ TFSXBatteryMasterFunction }
procedure TFSXBatteryMasterFunction.RegisterStates;
begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXBatteryMasterFunction.RegisterStates
end;
function TFSXBatteryMasterFunction.GetWorkerClass: TCustomLEDFunctionWorkerClass;
begin
Result := TFSXBatteryMasterFunctionWorker;
end;
{ TFSXAvionicsMasterFunction }
procedure TFSXAvionicsMasterFunction.RegisterStates;
begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXAvionicsMasterFunction.RegisterStates
end;
function TFSXAvionicsMasterFunction.GetWorkerClass: TCustomLEDFunctionWorkerClass;
begin
Result := TFSXAvionicsMasterFunctionWorker;
end;
{ TFSXPressDumpSwitchFunction }
procedure TFSXPressDumpSwitchFunction.RegisterStates;
begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXPressDumpSwitchFunction.RegisterStates
end;
function TFSXPressDumpSwitchFunction.GetWorkerClass: TCustomLEDFunctionWorkerClass;
begin
Result := TFSXPressDumpSwitchFunctionWorker;
end;
{ TFSXEngineAntiIceFunction }
procedure TFSXEngineAntiIceFunction.RegisterStates;
begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXEngineAntiIceFunction.RegisterStates
end;
function TFSXEngineAntiIceFunction.GetWorkerClass: TCustomLEDFunctionWorkerClass;
begin
Result := TFSXEngineAntiIceFunctionWorker;
end;
{ TFSXFuelPumpFunction }
procedure TFSXFuelPumpFunction.RegisterStates;
begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXFuelPumpFunction.RegisterStates
end;
function TFSXFuelPumpFunction.GetWorkerClass: TCustomLEDFunctionWorkerClass;
begin
Result := TFSXFuelPumpFunctionWorker;
end;
{ TFSXDeIceFunction }
procedure TFSXDeIceFunction.RegisterStates;
begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXDeIceFunction.RegisterStates
end;
function TFSXDeIceFunction.GetWorkerClass: TCustomLEDFunctionWorkerClass;
begin
Result := TFSXDeIceFunctionWorker;
end;
{ TFSXLightFunction } { TFSXLightFunction }
function TCustomFSXLightFunction.GetCategoryName: string; function TCustomFSXLightFunction.GetCategoryName: string;
begin begin
@ -390,15 +421,15 @@ begin
end; end;
function TCustomFSXLightFunction.GetWorkerClass: TCustomLEDFunctionWorkerClass; function TCustomFSXLightFunction.GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass;
begin begin
Result := TFSXLightStatesFunctionWorker; Result := TFSXLightStatesFunctionWorker;
end; end;
function TCustomFSXLightFunction.DoCreateWorker(ASettings: ILEDFunctionWorkerSettings): TCustomLEDFunctionWorker; function TCustomFSXLightFunction.DoCreateWorker(ASettings: ILEDFunctionWorkerSettings; const APreviousState: string): TCustomLEDFunctionWorker;
begin begin
Result := inherited DoCreateWorker(ASettings); Result := inherited DoCreateWorker(ASettings, APreviousState);
(Result as TFSXLightStatesFunctionWorker).StateMask := GetLightMask; (Result as TFSXLightStatesFunctionWorker).StateMask := GetLightMask;
end; end;
@ -459,81 +490,66 @@ begin
end; end;
{ TFSXAutoPilotFunction } procedure TCustomFSXAutoPilotFunction.RegisterStates;
procedure TFSXAutoPilotFunction.RegisterStates;
begin begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXAutoPilotFunction.RegisterStates RegisterState(TLEDState.Create(FSXStateUIDAutoPilotNotAvailable, FSXStateDisplayNameAutoPilotNotAvailable, lcOff));
RegisterState(TLEDState.Create(FSXStateUIDOn, FSXStateDisplayNameOn, lcGreen));
RegisterState(TLEDState.Create(FSXStateUIDOff, FSXStateDisplayNameOff, lcOff));
end; end;
function TFSXAutoPilotFunction.GetWorkerClass: TCustomLEDFunctionWorkerClass; { TFSXAutoPilotFunction }
function TFSXAutoPilotFunction.GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass;
begin begin
Result := TFSXAutoPilotFunctionWorker; Result := TFSXAutoPilotFunctionWorker;
end; end;
{ TFSXAutoPilotHeadingFunction } { TFSXAutoPilotHeadingFunction }
procedure TFSXAutoPilotHeadingFunction.RegisterStates; function TFSXAutoPilotHeadingFunction.GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass;
begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXAutoPilotHeadingFunction.RegisterState
end;
function TFSXAutoPilotHeadingFunction.GetWorkerClass: TCustomLEDFunctionWorkerClass;
begin begin
Result := TFSXAutoPilotHeadingFunctionWorker; Result := TFSXAutoPilotHeadingFunctionWorker;
end; end;
{ TFSXAutoPilotApproachFunction } { TFSXAutoPilotApproachFunction }
procedure TFSXAutoPilotApproachFunction.RegisterStates; function TFSXAutoPilotApproachFunction.GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass;
begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXAutoPilotApproachFunction.RegisterStates
end;
function TFSXAutoPilotApproachFunction.GetWorkerClass: TCustomLEDFunctionWorkerClass;
begin begin
Result := TFSXAutoPilotApproachFunctionWorker; Result := TFSXAutoPilotApproachFunctionWorker;
end; end;
{ TFSXAutoPilotBackcourseFunction } { TFSXAutoPilotBackcourseFunction }
procedure TFSXAutoPilotBackcourseFunction.RegisterStates; function TFSXAutoPilotBackcourseFunction.GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass;
begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXAutoPilotBackcourseFunction.RegisterStates
end;
function TFSXAutoPilotBackcourseFunction.GetWorkerClass: TCustomLEDFunctionWorkerClass;
begin begin
Result := TFSXAutoPilotBackcourseFunctionWorker; Result := TFSXAutoPilotBackcourseFunctionWorker;
end; end;
{ TFSXAutoPilotAltitudeFunction } { TFSXAutoPilotAltitudeFunction }
procedure TFSXAutoPilotAltitudeFunction.RegisterStates; function TFSXAutoPilotAltitudeFunction.GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass;
begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXAutoPilotAltitudeFunction.RegisterStates
end;
function TFSXAutoPilotAltitudeFunction.GetWorkerClass: TCustomLEDFunctionWorkerClass;
begin begin
Result := TFSXAutoPilotAltitudeFunctionWorker; Result := TFSXAutoPilotAltitudeFunctionWorker;
end; end;
{ TFSXAutoPilotNavFunction } { TFSXAutoPilotNavFunction }
procedure TFSXAutoPilotNavFunction.RegisterStates; function TFSXAutoPilotNavFunction.GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass;
begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXAutoPilotNavFunction.RegisterStates
end;
function TFSXAutoPilotNavFunction.GetWorkerClass: TCustomLEDFunctionWorkerClass;
begin begin
Result := TFSXAutoPilotNavFunctionWorker; Result := TFSXAutoPilotNavFunctionWorker;
end; end;
{ TFSXAvionicsMasterFunction }
function TFSXAvionicsMasterFunction.GetCategoryName: string;
begin
Result := FSXCategoryRadios;
end;
function TFSXAvionicsMasterFunction.GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass;
begin
Result := TFSXAvionicsMasterFunctionWorker;
end;
end. end.

View File

@ -41,7 +41,7 @@ type
FDisplayName: string; FDisplayName: string;
FUID: string; FUID: string;
protected protected
function DoCreateWorker(ASettings: ILEDFunctionWorkerSettings): TCustomLEDFunctionWorker; override; function DoCreateWorker(ASettings: ILEDFunctionWorkerSettings; const APreviousState: string = ''): TCustomLEDFunctionWorker; override;
property Provider: TFSXLEDFunctionProvider read FProvider; property Provider: TFSXLEDFunctionProvider read FProvider;
protected protected
@ -56,30 +56,23 @@ type
TCustomFSXFunctionClass = class of TCustomFSXFunction; TCustomFSXFunctionClass = class of TCustomFSXFunction;
TCustomFSXFunctionWorker = class(TCustomLEDFunctionWorker) TCustomFSXFunctionWorker = class(TCustomLEDMultiStateFunctionWorker)
private private
FDataHandler: IFSXSimConnectDataHandler; FDataHandler: IFSXSimConnectDataHandler;
FDefinitionID: Cardinal; FDefinitionID: Cardinal;
FSimConnect: IFSXSimConnect; FSimConnect: IFSXSimConnect;
FCurrentStateLock: TCriticalSection;
FCurrentState: ILEDStateWorker;
protected protected
procedure RegisterStates(AStates: ILEDMultiStateFunction; ASettings: ILEDFunctionWorkerSettings); override;
procedure RegisterVariables(ADefinition: IFSXSimConnectDefinition); virtual; abstract; procedure RegisterVariables(ADefinition: IFSXSimConnectDefinition); virtual; abstract;
procedure SetCurrentState(const AUID: string; ANotifyObservers: Boolean = True); overload; virtual;
procedure SetCurrentState(AState: ILEDStateWorker; ANotifyObservers: Boolean = True); overload; virtual;
procedure SetSimConnect(const Value: IFSXSimConnect); virtual; procedure SetSimConnect(const Value: IFSXSimConnect); virtual;
property DataHandler: IFSXSimConnectDataHandler read FDataHandler; property DataHandler: IFSXSimConnectDataHandler read FDataHandler;
property DefinitionID: Cardinal read FDefinitionID; property DefinitionID: Cardinal read FDefinitionID;
property SimConnect: IFSXSimConnect read FSimConnect write SetSimConnect; property SimConnect: IFSXSimConnect read FSimConnect write SetSimConnect;
protected protected
function GetCurrentState: ILEDStateWorker; override;
procedure HandleData(AData: Pointer); virtual; abstract; procedure HandleData(AData: Pointer); virtual; abstract;
public public
constructor Create(AStates: ILEDMultiStateFunction; ASettings: ILEDFunctionWorkerSettings); override; constructor Create(const AProviderUID, AFunctionUID: string; AStates: ILEDMultiStateFunction; ASettings: ILEDFunctionWorkerSettings; const APreviousState: string = ''); override;
destructor Destroy; override; destructor Destroy; override;
end; end;
@ -129,21 +122,23 @@ end;
procedure TFSXLEDFunctionProvider.RegisterFunctions; procedure TFSXLEDFunctionProvider.RegisterFunctions;
begin begin
{ Misc } { Systems }
RegisterFunction(TFSXAvionicsMasterFunction.Create( Self, FSXFunctionDisplayNameAvionicsMaster, FSXFunctionUIDAvionicsMaster));
RegisterFunction(TFSXBatteryMasterFunction.Create( Self, FSXFunctionDisplayNameBatteryMaster, FSXFunctionUIDBatteryMaster)); RegisterFunction(TFSXBatteryMasterFunction.Create( Self, FSXFunctionDisplayNameBatteryMaster, FSXFunctionUIDBatteryMaster));
RegisterFunction(TFSXDeIceFunction.Create( Self, FSXFunctionDisplayNameDeIce, FSXFunctionUIDDeIce)); RegisterFunction(TFSXDeIceFunction.Create( Self, FSXFunctionDisplayNameDeIce, FSXFunctionUIDDeIce));
RegisterFunction(TFSXEngineAntiIceFunction.Create( Self, FSXFunctionDisplayNameEngineAntiIce, FSXFunctionUIDEngineAntiIce));
RegisterFunction(TFSXEngineFunction.Create( Self, FSXFunctionDisplayNameEngine, FSXFunctionUIDEngine));
RegisterFunction(TFSXExitDoorFunction.Create( Self, FSXFunctionDisplayNameExitDoor, FSXFunctionUIDExitDoor)); RegisterFunction(TFSXExitDoorFunction.Create( Self, FSXFunctionDisplayNameExitDoor, FSXFunctionUIDExitDoor));
RegisterFunction(TFSXFlapsFunction.Create( Self, FSXFunctionDisplayNameFlaps, FSXFunctionUIDFlaps));
RegisterFunction(TFSXFuelPumpFunction.Create( Self, FSXFunctionDisplayNameFuelPump, FSXFunctionUIDFuelPump));
RegisterFunction(TFSXGearFunction.Create( Self, FSXFunctionDisplayNameGear, FSXFunctionUIDGear)); RegisterFunction(TFSXGearFunction.Create( Self, FSXFunctionDisplayNameGear, FSXFunctionUIDGear));
RegisterFunction(TFSXParkingBrakeFunction.Create( Self, FSXFunctionDisplayNameParkingBrake, FSXFunctionUIDParkingBrake)); RegisterFunction(TFSXParkingBrakeFunction.Create( Self, FSXFunctionDisplayNameParkingBrake, FSXFunctionUIDParkingBrake));
RegisterFunction(TFSXPressDumpSwitchFunction.Create( Self, FSXFunctionDisplayNamePressDumpSwitch, FSXFunctionUIDPressDumpSwitch)); RegisterFunction(TFSXPressDumpSwitchFunction.Create( Self, FSXFunctionDisplayNamePressDumpSwitch, FSXFunctionUIDPressDumpSwitch));
RegisterFunction(TFSXSpoilersFunction.Create( Self, FSXFunctionDisplayNameSpoilers, FSXFunctionUIDSpoilers));
RegisterFunction(TFSXTailHookFunction.Create( Self, FSXFunctionDisplayNameTailHook, FSXFunctionUIDTailHook)); RegisterFunction(TFSXTailHookFunction.Create( Self, FSXFunctionDisplayNameTailHook, FSXFunctionUIDTailHook));
{ Engines }
RegisterFunction(TFSXEngineAntiIceFunction.Create( Self, FSXFunctionDisplayNameEngineAntiIce, FSXFunctionUIDEngineAntiIce));
RegisterFunction(TFSXEngineFunction.Create( Self, FSXFunctionDisplayNameEngine, FSXFunctionUIDEngine));
{ Control surfaces }
RegisterFunction(TFSXFlapsFunction.Create( Self, FSXFunctionDisplayNameFlaps, FSXFunctionUIDFlaps));
RegisterFunction(TFSXSpoilersFunction.Create( Self, FSXFunctionDisplayNameSpoilers, FSXFunctionUIDSpoilers));
{ Lights } { Lights }
RegisterFunction(TFSXBeaconLightsFunction.Create( Self, FSXFunctionDisplayNameBeaconLights, FSXFunctionUIDBeaconLights)); RegisterFunction(TFSXBeaconLightsFunction.Create( Self, FSXFunctionDisplayNameBeaconLights, FSXFunctionUIDBeaconLights));
RegisterFunction(TFSXInstrumentLightsFunction.Create( Self, FSXFunctionDisplayNameInstrumentLights, FSXFunctionUIDInstrumentLights)); RegisterFunction(TFSXInstrumentLightsFunction.Create( Self, FSXFunctionDisplayNameInstrumentLights, FSXFunctionUIDInstrumentLights));
@ -160,6 +155,9 @@ begin
RegisterFunction(TFSXAutoPilotBackcourseFunction.Create(Self, FSXFunctionDisplayNameAutoPilotBackcourse, FSXFunctionUIDAutoPilotBackcourse)); RegisterFunction(TFSXAutoPilotBackcourseFunction.Create(Self, FSXFunctionDisplayNameAutoPilotBackcourse, FSXFunctionUIDAutoPilotBackcourse));
RegisterFunction(TFSXAutoPilotHeadingFunction.Create( Self, FSXFunctionDisplayNameAutoPilotHeading, FSXFunctionUIDAutoPilotHeading)); RegisterFunction(TFSXAutoPilotHeadingFunction.Create( Self, FSXFunctionDisplayNameAutoPilotHeading, FSXFunctionUIDAutoPilotHeading));
RegisterFunction(TFSXAutoPilotNavFunction.Create( Self, FSXFunctionDisplayNameAutoPilotNav, FSXFunctionUIDAutoPilotNav)); RegisterFunction(TFSXAutoPilotNavFunction.Create( Self, FSXFunctionDisplayNameAutoPilotNav, FSXFunctionUIDAutoPilotNav));
{ Radios }
RegisterFunction(TFSXAvionicsMasterFunction.Create( Self, FSXFunctionDisplayNameAvionicsMaster, FSXFunctionUIDAvionicsMaster));
end; end;
@ -202,7 +200,7 @@ end;
{ TCustomFSXFunction } { TCustomFSXFunction }
constructor TCustomFSXFunction.Create(AProvider: TFSXLEDFunctionProvider; const ADisplayName, AUID: string); constructor TCustomFSXFunction.Create(AProvider: TFSXLEDFunctionProvider; const ADisplayName, AUID: string);
begin begin
inherited Create; inherited Create(AProvider.GetUID);
FProvider := AProvider; FProvider := AProvider;
FDisplayName := ADisplayName; FDisplayName := ADisplayName;
@ -210,9 +208,9 @@ begin
end; end;
function TCustomFSXFunction.DoCreateWorker(ASettings: ILEDFunctionWorkerSettings): TCustomLEDFunctionWorker; function TCustomFSXFunction.DoCreateWorker(ASettings: ILEDFunctionWorkerSettings; const APreviousState: string): TCustomLEDFunctionWorker;
begin begin
Result := inherited DoCreateWorker(ASettings); Result := inherited DoCreateWorker(ASettings, APreviousState);
(Result as TCustomFSXFunctionWorker).SimConnect := Provider.GetSimConnect; (Result as TCustomFSXFunctionWorker).SimConnect := Provider.GetSimConnect;
end; end;
@ -237,23 +235,19 @@ end;
{ TCustomFSXFunctionWorker } { TCustomFSXFunctionWorker }
constructor TCustomFSXFunctionWorker.Create(AStates: ILEDMultiStateFunction; ASettings: ILEDFunctionWorkerSettings); constructor TCustomFSXFunctionWorker.Create(const AProviderUID, AFunctionUID: string; AStates: ILEDMultiStateFunction; ASettings: ILEDFunctionWorkerSettings; const APreviousState: string);
begin begin
FCurrentStateLock := TCriticalSection.Create;
{ We can't pass ourselves as the Data Handler, as it would keep a reference to { 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 this worker from the SimConnect interface. That'd mean the worker never
gets destroyed, and SimConnect never shuts down. Hence this proxy class. } gets destroyed, and SimConnect never shuts down. Hence this proxy class. }
FDataHandler := TCustomFSXFunctionWorkerDataHandler.Create(Self); FDataHandler := TCustomFSXFunctionWorkerDataHandler.Create(Self);
inherited Create(AStates, ASettings); inherited Create(AProviderUID, AFunctionUID, AStates, ASettings, APreviousState);
end; end;
destructor TCustomFSXFunctionWorker.Destroy; destructor TCustomFSXFunctionWorker.Destroy;
begin begin
FreeAndNil(FCurrentStateLock);
if DefinitionID <> 0 then if DefinitionID <> 0 then
SimConnect.RemoveDefinition(DefinitionID, DataHandler); SimConnect.RemoveDefinition(DefinitionID, DataHandler);
@ -261,50 +255,6 @@ begin
end; end;
procedure TCustomFSXFunctionWorker.RegisterStates(AStates: ILEDMultiStateFunction; ASettings: ILEDFunctionWorkerSettings);
begin
inherited RegisterStates(AStates, ASettings);
{ Make sure we have a default state }
if States.Count > 0 then
SetCurrentState((States[0] as ILEDStateWorker), False);
end;
function TCustomFSXFunctionWorker.GetCurrentState: ILEDStateWorker;
begin
FCurrentStateLock.Acquire;
try
Result := FCurrentState;
finally
FCurrentStateLock.Release;
end;
end;
procedure TCustomFSXFunctionWorker.SetCurrentState(const AUID: string; ANotifyObservers: Boolean);
begin
SetCurrentState(FindState(AUID), ANotifyObservers);
end;
procedure TCustomFSXFunctionWorker.SetCurrentState(AState: ILEDStateWorker; ANotifyObservers: Boolean);
begin
FCurrentStateLock.Acquire;
try
if AState <> FCurrentState then
begin
FCurrentState := AState;
if ANotifyObservers then
NotifyObservers;
end;
finally
FCurrentStateLock.Release;
end;
end;
procedure TCustomFSXFunctionWorker.SetSimConnect(const Value: IFSXSimConnect); procedure TCustomFSXFunctionWorker.SetSimConnect(const Value: IFSXSimConnect);
var var
definition: IFSXSimConnectDefinition; definition: IFSXSimConnectDefinition;

View File

@ -7,8 +7,20 @@ uses
type type
{ Misc } { Systems }
TFSXEngineFunctionWorker = class(TCustomFSXFunctionWorker) TFSXBatteryMasterFunctionWorker = class(TCustomFSXFunctionWorker)
protected
procedure RegisterVariables(ADefinition: IFSXSimConnectDefinition); override;
procedure HandleData(AData: Pointer); override;
end;
TFSXDeIceFunctionWorker = class(TCustomFSXFunctionWorker)
protected
procedure RegisterVariables(ADefinition: IFSXSimConnectDefinition); override;
procedure HandleData(AData: Pointer); override;
end;
TFSXExitDoorFunctionWorker = class(TCustomFSXFunctionWorker)
protected protected
procedure RegisterVariables(ADefinition: IFSXSimConnectDefinition); override; procedure RegisterVariables(ADefinition: IFSXSimConnectDefinition); override;
procedure HandleData(AData: Pointer); override; procedure HandleData(AData: Pointer); override;
@ -26,7 +38,7 @@ type
procedure HandleData(AData: Pointer); override; procedure HandleData(AData: Pointer); override;
end; end;
TFSXExitDoorFunctionWorker = class(TCustomFSXFunctionWorker) TFSXPressDumpSwitchFunctionWorker = class(TCustomFSXFunctionWorker)
protected protected
procedure RegisterVariables(ADefinition: IFSXSimConnectDefinition); override; procedure RegisterVariables(ADefinition: IFSXSimConnectDefinition); override;
procedure HandleData(AData: Pointer); override; procedure HandleData(AData: Pointer); override;
@ -39,12 +51,26 @@ type
end; end;
TFSXFlapsFunctionWorker = class(TCustomFSXFunctionWorker) { Engines }
TFSXEngineAntiIceFunctionWorker = class(TCustomFSXFunctionWorker)
protected protected
procedure RegisterVariables(ADefinition: IFSXSimConnectDefinition); override; procedure RegisterVariables(ADefinition: IFSXSimConnectDefinition); override;
procedure HandleData(AData: Pointer); override; procedure HandleData(AData: Pointer); override;
end; end;
TFSXEngineFunctionWorker = class(TCustomFSXFunctionWorker)
protected
procedure RegisterVariables(ADefinition: IFSXSimConnectDefinition); override;
procedure HandleData(AData: Pointer); override;
end;
{ Control surfaces }
TFSXFlapsFunctionWorker = class(TCustomFSXFunctionWorker)
protected
procedure RegisterVariables(ADefinition: IFSXSimConnectDefinition); override;
procedure HandleData(AData: Pointer); override;
end;
TFSXSpoilersFunctionWorker = class(TCustomFSXFunctionWorker) TFSXSpoilersFunctionWorker = class(TCustomFSXFunctionWorker)
protected protected
@ -53,48 +79,7 @@ type
end; end;
TFSXBatteryMasterFunctionWorker = class(TCustomFSXFunctionWorker) { Lights }
protected
procedure RegisterVariables(ADefinition: IFSXSimConnectDefinition); override;
procedure HandleData(AData: Pointer); override;
end;
TFSXAvionicsMasterFunctionWorker = class(TCustomFSXFunctionWorker)
protected
procedure RegisterVariables(ADefinition: IFSXSimConnectDefinition); override;
procedure HandleData(AData: Pointer); override;
end;
TFSXPressDumpSwitchFunctionWorker = class(TCustomFSXFunctionWorker)
protected
procedure RegisterVariables(ADefinition: IFSXSimConnectDefinition); override;
procedure HandleData(AData: Pointer); override;
end;
TFSXEngineAntiIceFunctionWorker = class(TCustomFSXFunctionWorker)
protected
procedure RegisterVariables(ADefinition: IFSXSimConnectDefinition); override;
procedure HandleData(AData: Pointer); override;
end;
TFSXFuelPumpFunctionWorker = class(TCustomFSXFunctionWorker)
protected
procedure RegisterVariables(ADefinition: IFSXSimConnectDefinition); override;
procedure HandleData(AData: Pointer); override;
end;
TFSXDeIceFunctionWorker = class(TCustomFSXFunctionWorker)
protected
procedure RegisterVariables(ADefinition: IFSXSimConnectDefinition); override;
procedure HandleData(AData: Pointer); override;
end;
TFSXLightStatesFunctionWorker = class(TCustomFSXFunctionWorker) TFSXLightStatesFunctionWorker = class(TCustomFSXFunctionWorker)
private private
FStateMask: Integer; FStateMask: Integer;
@ -106,42 +91,67 @@ type
end; end;
TFSXAutoPilotFunctionWorker = class(TCustomFSXFunctionWorker) { Autopilot }
protected PAutoPilotData = ^TAutoPilotData;
procedure RegisterVariables(ADefinition: IFSXSimConnectDefinition); override; TAutoPilotData = packed record
procedure HandleData(AData: Pointer); override; AutoPilotAvailable: Cardinal;
AutoPilotMaster: Cardinal;
AutoPilotHeading: Cardinal;
AutoPilotApproach: Cardinal;
AutoPilotBackcourse: Cardinal;
AutoPilotAltitude: Cardinal;
AutoPilotNav: Cardinal;
end; end;
TFSXAutoPilotHeadingFunctionWorker = class(TCustomFSXFunctionWorker) TCustomFSXAutoPilotFunctionWorker = class(TCustomFSXFunctionWorker)
protected protected
procedure RegisterVariables(ADefinition: IFSXSimConnectDefinition); override; procedure RegisterVariables(ADefinition: IFSXSimConnectDefinition); override;
procedure HandleData(AData: Pointer); override; procedure HandleData(AData: Pointer); override;
procedure SetOnOffState(AState: Cardinal); virtual;
procedure HandleAutoPilotData(AData: PAutoPilotData); virtual; abstract;
end; end;
TFSXAutoPilotApproachFunctionWorker = class(TCustomFSXFunctionWorker) TFSXAutoPilotFunctionWorker = class(TCustomFSXAutoPilotFunctionWorker)
protected protected
procedure RegisterVariables(ADefinition: IFSXSimConnectDefinition); override; procedure HandleAutoPilotData(AData: PAutoPilotData); override;
procedure HandleData(AData: Pointer); override;
end; end;
TFSXAutoPilotBackcourseFunctionWorker = class(TCustomFSXFunctionWorker) TFSXAutoPilotHeadingFunctionWorker = class(TCustomFSXAutoPilotFunctionWorker)
protected protected
procedure RegisterVariables(ADefinition: IFSXSimConnectDefinition); override; procedure HandleAutoPilotData(AData: PAutoPilotData); override;
procedure HandleData(AData: Pointer); override;
end; end;
TFSXAutoPilotAltitudeFunctionWorker = class(TCustomFSXFunctionWorker) TFSXAutoPilotApproachFunctionWorker = class(TCustomFSXAutoPilotFunctionWorker)
protected protected
procedure RegisterVariables(ADefinition: IFSXSimConnectDefinition); override; procedure HandleAutoPilotData(AData: PAutoPilotData); override;
procedure HandleData(AData: Pointer); override;
end; end;
TFSXAutoPilotNavFunctionWorker = class(TCustomFSXFunctionWorker) TFSXAutoPilotBackcourseFunctionWorker = class(TCustomFSXAutoPilotFunctionWorker)
protected
procedure HandleAutoPilotData(AData: PAutoPilotData); override;
end;
TFSXAutoPilotAltitudeFunctionWorker = class(TCustomFSXAutoPilotFunctionWorker)
protected
procedure HandleAutoPilotData(AData: PAutoPilotData); override;
end;
TFSXAutoPilotNavFunctionWorker = class(TCustomFSXAutoPilotFunctionWorker)
protected
procedure HandleAutoPilotData(AData: PAutoPilotData); override;
end;
{ Radios }
TFSXAvionicsMasterFunctionWorker = class(TCustomFSXFunctionWorker)
protected protected
procedure RegisterVariables(ADefinition: IFSXSimConnectDefinition); override; procedure RegisterVariables(ADefinition: IFSXSimConnectDefinition); override;
procedure HandleData(AData: Pointer); override; procedure HandleData(AData: Pointer); override;
@ -158,6 +168,200 @@ uses
SimConnect; SimConnect;
{ TFSXBatteryMasterFunctionWorker }
procedure TFSXBatteryMasterFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition);
begin
ADefinition.AddVariable('ELECTRICAL MASTER BATTERY', FSX_UNIT_BOOL, SIMCONNECT_DATAType_INT32);
end;
procedure TFSXBatteryMasterFunctionWorker.HandleData(AData: Pointer);
begin
if PCardinal(AData)^ <> 0 then
SetCurrentState(FSXStateUIDOn)
else
SetCurrentState(FSXStateUIDOff);
end;
{ TFSXDeIceFunctionWorker }
procedure TFSXDeIceFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition);
begin
ADefinition.AddVariable('STRUCTURAL DEICE SWITCH', FSX_UNIT_BOOL, SIMCONNECT_DATAType_INT32);
end;
procedure TFSXDeIceFunctionWorker.HandleData(AData: Pointer);
begin
if PCardinal(AData)^ <> 0 then
SetCurrentState(FSXStateUIDOn)
else
SetCurrentState(FSXStateUIDOff);
end;
{ TFSXExitDoorFunctionWorker }
procedure TFSXExitDoorFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition);
begin
ADefinition.AddVariable('CANOPY OPEN', FSX_UNIT_PERCENT, SIMCONNECT_DATAType_FLOAT64);
end;
procedure TFSXExitDoorFunctionWorker.HandleData(AData: Pointer);
begin
case Trunc(PDouble(AData)^) of
0..5: SetCurrentState(FSXStateUIDExitDoorClosed);
95..100: SetCurrentState(FSXStateUIDExitDoorOpen);
else SetCurrentState(FSXStateUIDExitDoorBetween);
end;
end;
{ TFSXGearFunctionWorker }
procedure TFSXGearFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition);
begin
ADefinition.AddVariable('IS GEAR RETRACTABLE', FSX_UNIT_BOOL, SIMCONNECT_DATAType_INT32);
ADefinition.AddVariable('GEAR TOTAL PCT EXTENDED', FSX_UNIT_PERCENT, SIMCONNECT_DATAType_FLOAT64);
ADefinition.AddVariable('GEAR DAMAGE BY SPEED', FSX_UNIT_BOOL, SIMCONNECT_DATAType_INT32);
ADefinition.AddVariable('GEAR SPEED EXCEEDED', FSX_UNIT_BOOL, SIMCONNECT_DATAType_INT32);
end;
procedure TFSXGearFunctionWorker.HandleData(AData: Pointer);
type
PGearData = ^TGearData;
TGearData = packed record
IsGearRetractable: Cardinal;
TotalPctExtended: Double;
DamageBySpeed: Integer;
SpeedExceeded: Integer;
end;
var
gearData: PGearData;
begin
gearData := AData;
if gearData^.DamageBySpeed <> 0 then
SetCurrentState(FSXStateUIDGearDamageBySpeed)
else if gearData^.SpeedExceeded <> 0 then
SetCurrentState(FSXStateUIDGearSpeedExceeded)
else if gearData^.IsGearRetractable <> 0 then
begin
case Trunc(gearData ^.TotalPctExtended * 100) of
0: SetCurrentState(FSXStateUIDGearRetracted);
95..100: SetCurrentState(FSXStateUIDGearExtended);
else SetCurrentState(FSXStateUIDGearBetween);
end;
end else
SetCurrentState(FSXStateUIDGearNotRetractable);
end;
{ TFSXParkingBrakeFunctionWorker }
procedure TFSXParkingBrakeFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition);
begin
ADefinition.AddVariable('BRAKE PARKING INDICATOR', FSX_UNIT_BOOL, SIMCONNECT_DATATYPE_INT32);
end;
procedure TFSXParkingBrakeFunctionWorker.HandleData(AData: Pointer);
begin
if PCardinal(AData)^ <> 0 then
SetCurrentState(FSXStateUIDOn)
else
SetCurrentState(FSXStateUIDOff);
end;
{ TFSXPressDumpSwitchFunctionWorker }
procedure TFSXPressDumpSwitchFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition);
begin
ADefinition.AddVariable('PRESSURIZATION DUMP SWITCH', FSX_UNIT_BOOL, SIMCONNECT_DATAType_INT32);
end;
procedure TFSXPressDumpSwitchFunctionWorker.HandleData(AData: Pointer);
begin
if PCardinal(AData)^ <> 0 then
SetCurrentState(FSXStateUIDOn)
else
SetCurrentState(FSXStateUIDOff);
end;
{ TFSXTailHookFunctionWorker }
procedure TFSXTailHookFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition);
begin
ADefinition.AddVariable('TAILHOOK POSITION', FSX_UNIT_PERCENT, SIMCONNECT_DATAType_FLOAT64);
end;
procedure TFSXTailHookFunctionWorker.HandleData(AData: Pointer);
begin
case Trunc(PDouble(AData)^) of
0..5: SetCurrentState(FSXStateUIDTailHookRetracted);
95..100: SetCurrentState(FSXStateUIDTailHookBetween);
else SetCurrentState(FSXStateUIDTailHookExtended);
end;
end;
{ TFSXEngineAntiIceFunctionWorker }
procedure TFSXEngineAntiIceFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition);
var
engineIndex: Integer;
begin
ADefinition.AddVariable('NUMBER OF ENGINES', FSX_UNIT_NUMBER, SIMCONNECT_DATAType_INT32);
for engineIndex := 1 to FSX_MAX_ENGINES do
ADefinition.AddVariable(Format('ENG ANTI ICE:%d', [engineIndex]), FSX_UNIT_BOOL, SIMCONNECT_DATAType_INT32);
end;
procedure TFSXEngineAntiIceFunctionWorker.HandleData(AData: Pointer);
type
PAntiIceData = ^TAntiIceData;
TAntiIceData = packed record
NumberOfEngines: Integer;
EngineAntiIce: array[1..FSX_MAX_ENGINES] of Integer;
end;
var
antiIceData: PAntiIceData;
engineCount: Integer;
antiIceCount: Integer;
engineIndex: Integer;
begin
antiIceData := AData;
engineCount := Min(antiIceData^.NumberOfEngines, FSX_MAX_ENGINES);
antiIceCount := 0;
for engineIndex := 1 to engineCount do
begin
if antiIceData^.EngineAntiIce[engineIndex] <> 0 then
Inc(antiIceCount);
end;
if engineCount > 0 then
begin
if antiIceCount = 0 then
SetCurrentState(FSXStateUIDEngineAntiIceNone)
else if antiIceCount = engineCount then
SetCurrentState(FSXStateUIDEngineAntiIceAll)
else
SetCurrentState(FSXStateUIDEngineAntiIcePartial);
end else
SetCurrentState(FSXStateUIDEngineAntiIceNoEngines);
end;
{ TFSXEngineFunctionWorker } { TFSXEngineFunctionWorker }
procedure TFSXEngineFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition); procedure TFSXEngineFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition);
var var
@ -236,105 +440,13 @@ begin
end; end;
{ TFSXGearFunctionWorker }
procedure TFSXGearFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition);
begin
ADefinition.AddVariable('IS GEAR RETRACTABLE', FSX_UNIT_BOOL, SIMCONNECT_DATAType_INT32);
ADefinition.AddVariable('GEAR TOTAL PCT EXTENDED', FSX_UNIT_PERCENT, SIMCONNECT_DATAType_FLOAT64);
ADefinition.AddVariable('GEAR DAMAGE BY SPEED', FSX_UNIT_BOOL, SIMCONNECT_DATAType_INT32);
ADefinition.AddVariable('GEAR SPEED EXCEEDED', FSX_UNIT_BOOL, SIMCONNECT_DATAType_INT32);
end;
procedure TFSXGearFunctionWorker.HandleData(AData: Pointer);
type
PGearData = ^TGearData;
TGearData = packed record
IsGearRetractable: Cardinal;
TotalPctExtended: Double;
DamageBySpeed: Integer;
SpeedExceeded: Integer;
end;
var
gearData: PGearData;
begin
gearData := AData;
if gearData^.DamageBySpeed <> 0 then
SetCurrentState(FSXStateUIDGearDamageBySpeed)
else if gearData^.SpeedExceeded <> 0 then
SetCurrentState(FSXStateUIDGearSpeedExceeded)
else if gearData^.IsGearRetractable <> 0 then
begin
case Trunc(gearData ^.TotalPctExtended * 100) of
0: SetCurrentState(FSXStateUIDGearRetracted);
95..100: SetCurrentState(FSXStateUIDGearExtended);
else SetCurrentState(FSXStateUIDGearBetween);
end;
end else
SetCurrentState(FSXStateUIDGearNotRetractable);
end;
{ TFSXParkingBrakeFunctionWorker }
procedure TFSXParkingBrakeFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition);
begin
ADefinition.AddVariable('BRAKE PARKING INDICATOR', FSX_UNIT_BOOL, SIMCONNECT_DATATYPE_INT32);
end;
procedure TFSXParkingBrakeFunctionWorker.HandleData(AData: Pointer);
begin
if PCardinal(AData)^ <> 0 then
SetCurrentState(FSXStateUIDOn)
else
SetCurrentState(FSXStateUIDOff);
end;
{ TFSXExitDoorFunctionWorker }
procedure TFSXExitDoorFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition);
begin
ADefinition.AddVariable('CANOPY OPEN', FSX_UNIT_PERCENT, SIMCONNECT_DATAType_FLOAT64);
end;
procedure TFSXExitDoorFunctionWorker.HandleData(AData: Pointer);
begin
case Trunc(PDouble(AData)^) of
0..5: SetCurrentState(FSXStateUIDExitDoorClosed);
95..100: SetCurrentState(FSXStateUIDExitDoorOpen);
else SetCurrentState(FSXStateUIDExitDoorBetween);
end;
end;
{ TFSXTailHookFunctionWorker }
procedure TFSXTailHookFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition);
begin
ADefinition.AddVariable('TAILHOOK POSITION', FSX_UNIT_PERCENT, SIMCONNECT_DATAType_FLOAT64);
end;
procedure TFSXTailHookFunctionWorker.HandleData(AData: Pointer);
begin
case Trunc(PDouble(AData)^) of
0..5: SetCurrentState(FSXStateUIDTailHookRetracted);
95..100: SetCurrentState(FSXStateUIDTailHookBetween);
else SetCurrentState(FSXStateUIDTailHookExtended);
end;
end;
{ TFSXFlapsFunctionWorker } { TFSXFlapsFunctionWorker }
procedure TFSXFlapsFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition); procedure TFSXFlapsFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition);
begin begin
ADefinition.AddVariable('FLAPS AVAILABLE', FSX_UNIT_BOOL, SIMCONNECT_DATAType_INT32); ADefinition.AddVariable('FLAPS AVAILABLE', FSX_UNIT_BOOL, SIMCONNECT_DATAType_INT32);
ADefinition.AddVariable('FLAPS HANDLE PERCENT', FSX_UNIT_PERCENT, SIMCONNECT_DATAType_FLOAT64); ADefinition.AddVariable('FLAPS HANDLE PERCENT', FSX_UNIT_PERCENT, SIMCONNECT_DATAType_FLOAT64);
ADefinition.AddVariable('FLAP DAMAGE BY SPEED', FSX_UNIT_BOOL, SIMCONNECT_DATAType_INT32);
ADefinition.AddVariable('FLAP SPEED EXCEEDED', FSX_UNIT_BOOL, SIMCONNECT_DATAType_INT32);
end; end;
@ -344,6 +456,8 @@ type
TFlapsData = packed record TFlapsData = packed record
FlapsAvailable: Cardinal; FlapsAvailable: Cardinal;
FlapsHandlePercent: Double; FlapsHandlePercent: Double;
DamageBySpeed: Integer;
SpeedExceeded: Integer;
end; end;
var var
@ -354,11 +468,16 @@ begin
if flapsData^.FlapsAvailable <> 0 then if flapsData^.FlapsAvailable <> 0 then
begin begin
case Trunc(flapsData^.FlapsHandlePercent) of if flapsData^.DamageBySpeed <> 0 then
0..5: SetCurrentState(FSXStateUIDFlapsRetracted); SetCurrentState(FSXStateUIDFlapsDamageBySpeed)
95..100: SetCurrentState(FSXStateUIDFlapsExtended); else if flapsData^.SpeedExceeded <> 0 then
else SetCurrentState(FSXStateUIDFlapsBetween); SetCurrentState(FSXStateUIDFlapsSpeedExceeded)
end; else
case Trunc(flapsData^.FlapsHandlePercent) of
0..5: SetCurrentState(FSXStateUIDFlapsRetracted);
95..100: SetCurrentState(FSXStateUIDFlapsExtended);
else SetCurrentState(FSXStateUIDFlapsBetween);
end;
end else end else
SetCurrentState(FSXStateUIDFlapsNotAvailable); SetCurrentState(FSXStateUIDFlapsNotAvailable);
end; end;
@ -398,84 +517,6 @@ begin
end; end;
{ TFSXBatteryMasterFunctionWorker }
procedure TFSXBatteryMasterFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition);
begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXBatteryMasterFunctionWorker.RegisterVariables
end;
procedure TFSXBatteryMasterFunctionWorker.HandleData(AData: Pointer);
begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXBatteryMasterFunctionWorker.HandleData
end;
{ TFSXAvionicsMasterFunctionWorker }
procedure TFSXAvionicsMasterFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition);
begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXAvionicsMasterFunctionWorker.RegisterVariables
end;
procedure TFSXAvionicsMasterFunctionWorker.HandleData(AData: Pointer);
begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXAvionicsMasterFunctionWorker.HandleData
end;
{ TFSXPressDumpSwitchFunctionWorker }
procedure TFSXPressDumpSwitchFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition);
begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXPressDumpSwitchFunctionWorker.RegisterVariables
end;
procedure TFSXPressDumpSwitchFunctionWorker.HandleData(AData: Pointer);
begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXPressDumpSwitchFunctionWorker.HandleData
end;
{ TFSXEngineAntiIceFunctionWorker }
procedure TFSXEngineAntiIceFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition);
begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXEngineAntiIceFunctionWorker.RegisterVariables
end;
procedure TFSXEngineAntiIceFunctionWorker.HandleData(AData: Pointer);
begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXEngineAntiIceFunctionWorker.HandleData
end;
{ TFSXFuelPumpFunctionWorker }
procedure TFSXFuelPumpFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition);
begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXFuelPumpFunctionWorker.RegisterVariables
end;
procedure TFSXFuelPumpFunctionWorker.HandleData(AData: Pointer);
begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXFuelPumpFunctionWorker.HandleData
end;
{ TFSXDeIceFunctionWorker }
procedure TFSXDeIceFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition);
begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXDeIceFunctionWorker.RegisterVariables
end;
procedure TFSXDeIceFunctionWorker.HandleData(AData: Pointer);
begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXDeIceFunctionWorker.HandleData
end;
{ TFSXLightStatesFunctionWorker } { TFSXLightStatesFunctionWorker }
procedure TFSXLightStatesFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition); procedure TFSXLightStatesFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition);
begin begin
@ -492,81 +533,97 @@ begin
end; end;
{ TFSXAutoPilotFunctionWorker } { TCustomFSXAutoPilotFunctionWorker }
procedure TFSXAutoPilotFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition); procedure TCustomFSXAutoPilotFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition);
begin begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXAutoPilotFunctionWorker.RegisterVariables ADefinition.AddVariable('AUTOPILOT AVAILABLE', FSX_UNIT_BOOL, SIMCONNECT_DATAType_INT32);
ADefinition.AddVariable('AUTOPILOT MASTER', FSX_UNIT_BOOL, SIMCONNECT_DATAType_INT32);
ADefinition.AddVariable('AUTOPILOT HEADING LOCK', FSX_UNIT_BOOL, SIMCONNECT_DATAType_INT32);
ADefinition.AddVariable('AUTOPILOT APPROACH HOLD', FSX_UNIT_BOOL, SIMCONNECT_DATAType_INT32);
ADefinition.AddVariable('AUTOPILOT BACKCOURSE HOLD', FSX_UNIT_BOOL, SIMCONNECT_DATAType_INT32);
ADefinition.AddVariable('AUTOPILOT ALTITUDE LOCK', FSX_UNIT_BOOL, SIMCONNECT_DATAType_INT32);
ADefinition.AddVariable('AUTOPILOT NAV1 LOCK', FSX_UNIT_BOOL, SIMCONNECT_DATAType_INT32);
end; end;
procedure TFSXAutoPilotFunctionWorker.HandleData(AData: Pointer); procedure TCustomFSXAutoPilotFunctionWorker.HandleData(AData: Pointer);
var
autoPilotData: PAutoPilotData;
begin begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXAutoPilotFunctionWorker.HandleData autoPilotData := AData;
if autoPilotData^.AutoPilotAvailable <> 0 then
HandleAutoPilotData(autoPilotData)
else
SetCurrentState(FSXStateUIDOff);
end;
procedure TCustomFSXAutoPilotFunctionWorker.SetOnOffState(AState: Cardinal);
begin
if AState <> 0 then
SetCurrentState(FSXStateUIDOn)
else
SetCurrentState(FSXStateUIDOff);
end;
{ TFSXAutoPilotFunctionWorker }
procedure TFSXAutoPilotFunctionWorker.HandleAutoPilotData(AData: PAutoPilotData);
begin
SetOnOffState(AData^.AutoPilotMaster);
end; end;
{ TFSXAutoPilotHeadingFunctionWorker } { TFSXAutoPilotHeadingFunctionWorker }
procedure TFSXAutoPilotHeadingFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition); procedure TFSXAutoPilotHeadingFunctionWorker.HandleAutoPilotData(AData: PAutoPilotData);
begin begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXAutoPilotHeadingFunctionWorker.RegisterVariables SetOnOffState(AData^.AutoPilotHeading);
end;
procedure TFSXAutoPilotHeadingFunctionWorker.HandleData(AData: Pointer);
begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXAutoPilotHeadingFunctionWorker.HandleData
end; end;
{ TFSXAutoPilotApproachFunctionWorker } { TFSXAutoPilotApproachFunctionWorker }
procedure TFSXAutoPilotApproachFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition); procedure TFSXAutoPilotApproachFunctionWorker.HandleAutoPilotData(AData: PAutoPilotData);
begin begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXAutoPilotApproachFunctionWorker.RegisterVariables SetOnOffState(AData^.AutoPilotApproach);
end;
procedure TFSXAutoPilotApproachFunctionWorker.HandleData(AData: Pointer);
begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXAutoPilotApproachFunctionWorker.HandleData
end; end;
{ TFSXAutoPilotBackcourseFunctionWorker } { TFSXAutoPilotBackcourseFunctionWorker }
procedure TFSXAutoPilotBackcourseFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition); procedure TFSXAutoPilotBackcourseFunctionWorker.HandleAutoPilotData(AData: PAutoPilotData);
begin begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXAutoPilotBackcourseFunctionWorker.RegisterVariables SetOnOffState(AData^.AutoPilotBackcourse);
end;
procedure TFSXAutoPilotBackcourseFunctionWorker.HandleData(AData: Pointer);
begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXAutoPilotBackcourseFunctionWorker.HandleData
end; end;
{ TFSXAutoPilotAltitudeFunctionWorker } { TFSXAutoPilotAltitudeFunctionWorker }
procedure TFSXAutoPilotAltitudeFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition); procedure TFSXAutoPilotAltitudeFunctionWorker.HandleAutoPilotData(AData: PAutoPilotData);
begin begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXAutoPilotAltitudeFunctionWorker.RegisterVariables SetOnOffState(AData^.AutoPilotAltitude);
end;
procedure TFSXAutoPilotAltitudeFunctionWorker.HandleData(AData: Pointer);
begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXAutoPilotAltitudeFunctionWorker.HandleData
end; end;
{ TFSXAutoPilotNavFunctionWorker } { TFSXAutoPilotNavFunctionWorker }
procedure TFSXAutoPilotNavFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition); procedure TFSXAutoPilotNavFunctionWorker.HandleAutoPilotData(AData: PAutoPilotData);
begin begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXAutoPilotNavFunctionWorker.RegisterVariables SetOnOffState(AData^.AutoPilotNav);
end; end;
procedure TFSXAutoPilotNavFunctionWorker.HandleData(AData: Pointer); { TFSXAvionicsMasterFunctionWorker }
procedure TFSXAvionicsMasterFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition);
begin begin
// #ToDo1 -cEmpty -oMvR: 22-2-2013: TFSXAutoPilotNavFunctionWorker.HandleData ADefinition.AddVariable('AVIONICS MASTER SWITCH', FSX_UNIT_BOOL, SIMCONNECT_DATAType_INT32);
end;
procedure TFSXAvionicsMasterFunctionWorker.HandleData(AData: Pointer);
begin
if PCardinal(AData)^ <> 0 then
SetCurrentState(FSXStateUIDOn)
else
SetCurrentState(FSXStateUIDOff);
end; end;
end. end.

View File

@ -6,8 +6,12 @@ const
FSXProviderUID = 'fsx'; FSXProviderUID = 'fsx';
FSXCategory = 'Flight Simulator X'; FSXCategory = 'Flight Simulator X';
FSXCategorySystems = FSXCategory + ' - Systems';
FSXCategoryEngines = FSXCategory + ' - Engines';
FSXCategoryControlSurfaces = FSXCategory + ' - Control surfaces';
FSXCategoryLights = FSXCategory + ' - Lights'; FSXCategoryLights = FSXCategory + ' - Lights';
FSXCategoryAutoPilot = FSXCategory + ' - Autopilot'; FSXCategoryAutoPilot = FSXCategory + ' - Autopilot';
FSXCategoryRadios = FSXCategory + ' - Radios';
FSXStateUIDOn = 'on'; FSXStateUIDOn = 'on';
FSXStateUIDOff = 'off'; FSXStateUIDOff = 'off';
@ -73,9 +77,11 @@ const
FSXFunctionUIDRecognitionLights = 'recognitionLights'; FSXFunctionUIDRecognitionLights = 'recognitionLights';
FSXFunctionDisplayNameRecognitionLights = 'Recognition lights'; FSXFunctionDisplayNameRecognitionLights = 'Recognition lights';
FSXFunctionUIDParkingBrake = 'parkingBrake'; FSXFunctionUIDParkingBrake = 'parkingBrake';
FSXFunctionDisplayNameParkingBrake = 'Parking brake'; FSXFunctionDisplayNameParkingBrake = 'Parking brake';
FSXFunctionUIDExitDoor = 'exitDoor'; FSXFunctionUIDExitDoor = 'exitDoor';
FSXFunctionDisplayNameExitDoor = 'Exit door'; FSXFunctionDisplayNameExitDoor = 'Exit door';
@ -87,6 +93,7 @@ const
FSXStateDisplayNameExitDoorBetween = 'Opening / closing'; FSXStateDisplayNameExitDoorBetween = 'Opening / closing';
FSXStateDisplayNameExitDoorOpen = 'Open'; FSXStateDisplayNameExitDoorOpen = 'Open';
FSXFunctionUIDTailHook = 'tailHook'; FSXFunctionUIDTailHook = 'tailHook';
FSXFunctionDisplayNameTailHook = 'Tail hook'; FSXFunctionDisplayNameTailHook = 'Tail hook';
@ -106,11 +113,15 @@ const
FSXStateUIDFlapsRetracted = 'retracted'; FSXStateUIDFlapsRetracted = 'retracted';
FSXStateUIDFlapsBetween = 'between'; FSXStateUIDFlapsBetween = 'between';
FSXStateUIDFlapsExtended = 'extended'; FSXStateUIDFlapsExtended = 'extended';
FSXStateUIDFlapsSpeedExceeded = 'speedExceeded';
FSXStateUIDFlapsDamageBySpeed = 'damageBySpeed';
FSXStateDisplayNameFlapsNotAvailable = 'No flaps'; FSXStateDisplayNameFlapsNotAvailable = 'No flaps';
FSXStateDisplayNameFlapsRetracted = 'Retracted'; FSXStateDisplayNameFlapsRetracted = 'Retracted';
FSXStateDisplayNameFlapsBetween = 'Extending / retracting'; FSXStateDisplayNameFlapsBetween = 'Extending / retracting';
FSXStateDisplayNameFlapsExtended = 'Extended'; FSXStateDisplayNameFlapsExtended = 'Extended';
FSXStateDisplayNameFlapsSpeedExceeded = 'Speed exceeded';
FSXStateDisplayNameFlapsDamageBySpeed = 'Damage by speed';
FSXFunctionUIDSpoilers = 'spoilers'; FSXFunctionUIDSpoilers = 'spoilers';
@ -130,21 +141,35 @@ const
FSXFunctionUIDBatteryMaster = 'batteryMaster'; FSXFunctionUIDBatteryMaster = 'batteryMaster';
FSXFunctionDisplayNameBatteryMaster = 'Battery master'; FSXFunctionDisplayNameBatteryMaster = 'Battery master';
FSXFunctionUIDAvionicsMaster = 'avionicsMaster'; FSXFunctionUIDAvionicsMaster = 'avionicsMaster';
FSXFunctionDisplayNameAvionicsMaster = 'Avionics master'; FSXFunctionDisplayNameAvionicsMaster = 'Avionics master';
FSXFunctionUIDPressDumpSwitch = 'pressurizationDumpSwitch'; FSXFunctionUIDPressDumpSwitch = 'pressurizationDumpSwitch';
FSXFunctionDisplayNamePressDumpSwitch = 'Pressurization dump switch'; FSXFunctionDisplayNamePressDumpSwitch = 'Pressurization dump switch';
FSXFunctionUIDEngineAntiIce = 'engineAntiIce'; FSXFunctionUIDEngineAntiIce = 'engineAntiIce';
FSXFunctionDisplayNameEngineAntiIce = 'Engine anti-ice'; FSXFunctionDisplayNameEngineAntiIce = 'Engine anti-ice';
FSXFunctionUIDFuelPump = 'fuelPump'; FSXStateUIDEngineAntiIceNoEngines = 'noEngines';
FSXFunctionDisplayNameFuelPump = 'Fuel pump'; FSXStateUIDEngineAntiIceAll = 'all';
FSXStateUIDEngineAntiIcePartial = 'partial';
FSXStateUIDEngineAntiIceNone = 'none';
FSXStateDisplayNameEngineAntiIceNoEngines = 'No engines';
FSXStateDisplayNameEngineAntiIceAll = 'All';
FSXStateDisplayNameEngineAntiIcePartial = 'Partial';
FSXStateDisplayNameEngineAntiIceNone = 'None';
FSXFunctionUIDDeIce = 'structuralDeIce'; FSXFunctionUIDDeIce = 'structuralDeIce';
FSXFunctionDisplayNameDeIce = 'De-ice'; FSXFunctionDisplayNameDeIce = 'De-ice';
FSXStateUIDAutoPilotNotAvailable = 'notAvailable';
FSXStateDisplayNameAutoPilotNotAvailable = 'Not available';
FSXFunctionUIDAutoPilot = 'autoPilotMaster'; FSXFunctionUIDAutoPilot = 'autoPilotMaster';
FSXFunctionDisplayNameAutoPilot = 'Autopilot master'; FSXFunctionDisplayNameAutoPilot = 'Autopilot master';

View File

@ -43,7 +43,8 @@ uses
OtlCommon, OtlCommon,
SimConnect, SimConnect,
FSXResources; FSXResources,
FSXSimConnectStateMonitor;
const const
@ -68,7 +69,7 @@ type
destructor Destroy; override; destructor Destroy; override;
procedure Attach(ADataHandler: IFSXSimConnectDataHandler); procedure Attach(ADataHandler: IFSXSimConnectDataHandler);
procedure Detach(ADataHandler: IFSXSimConnectDataHandler); function Detach(ADataHandler: IFSXSimConnectDataHandler): Integer;
procedure HandleData(AData: Pointer); procedure HandleData(AData: Pointer);
@ -76,7 +77,10 @@ type
end; end;
TFSXSimConnectDefinitionMap = TDictionary<Cardinal, TFSXSimConnectDefinitionRef>; TFSXSimConnectDefinitionMap = class(TObjectDictionary<Cardinal, TFSXSimConnectDefinitionRef>)
public
constructor Create(ACapacity: Integer = 0); reintroduce;
end;
TFSXSimConnectClient = class(TOmniWorker) TFSXSimConnectClient = class(TOmniWorker)
private private
@ -98,6 +102,8 @@ type
procedure RegisterDefinitions; procedure RegisterDefinitions;
procedure RegisterDefinition(ADefinitionID: Cardinal; ADefinition: IFSXSimConnectDefinitionAccess); procedure RegisterDefinition(ADefinitionID: Cardinal; ADefinition: IFSXSimConnectDefinitionAccess);
procedure UpdateDefinition(ADefinitionID: Cardinal);
procedure UnregisterDefinition(ADefinitionID: Cardinal);
function SameDefinition(ADefinition1, ADefinition2: IFSXSimConnectDefinitionAccess): Boolean; function SameDefinition(ADefinition1, ADefinition2: IFSXSimConnectDefinitionAccess): Boolean;
@ -306,13 +312,13 @@ end;
procedure TFSXSimConnectClient.Cleanup; procedure TFSXSimConnectClient.Cleanup;
begin begin
// #ToDo1 -oMvR: 22-2-2013: unregister definitions FreeAndNil(FSimConnectDataEvent);
FreeAndNil(FDefinitions);
if SimConnectHandle <> 0 then if SimConnectHandle <> 0 then
SimConnect_Close(SimConnectHandle); SimConnect_Close(SimConnectHandle);
FreeAndNil(FSimConnectDataEvent); TFSXSimConnectStateMonitor.SetCurrentState(scsDisconnected);
FreeAndNil(FDefinitions);
inherited Cleanup; inherited Cleanup;
end; end;
@ -327,13 +333,19 @@ begin
begin begin
if SimConnect_Open(FSimConnectHandle, FSXSimConnectAppName, 0, 0, SimConnectDataEvent.Handle, 0) = S_OK then if SimConnect_Open(FSimConnectHandle, FSXSimConnectAppName, 0, 0, SimConnectDataEvent.Handle, 0) = S_OK then
begin begin
TFSXSimConnectStateMonitor.SetCurrentState(scsConnected);
Task.ClearTimer(TIMER_TRYSIMCONNECT); Task.ClearTimer(TIMER_TRYSIMCONNECT);
RegisterDefinitions; RegisterDefinitions;
end; end;
end; end;
if SimConnectHandle = 0 then if SimConnectHandle = 0 then
begin
TFSXSimConnectStateMonitor.SetCurrentState(scsFailed);
Task.SetTimer(TIMER_TRYSIMCONNECT, INTERVAL_TRYSIMCONNECT, TM_TRYSIMCONNECT); Task.SetTimer(TIMER_TRYSIMCONNECT, INTERVAL_TRYSIMCONNECT, TM_TRYSIMCONNECT);
end;
end; end;
@ -364,6 +376,8 @@ begin
begin begin
FSimConnectHandle := 0; FSimConnectHandle := 0;
Task.SetTimer(TIMER_TRYSIMCONNECT, INTERVAL_TRYSIMCONNECT, TM_TRYSIMCONNECT); Task.SetTimer(TIMER_TRYSIMCONNECT, INTERVAL_TRYSIMCONNECT, TM_TRYSIMCONNECT);
TFSXSimConnectStateMonitor.SetCurrentState(scsDisconnected);
end; end;
end; end;
end; end;
@ -409,6 +423,25 @@ begin
end; end;
procedure TFSXSimConnectClient.UpdateDefinition(ADefinitionID: Cardinal);
begin
if SimConnectHandle <> 0 then
{ One-time data update; the RequestID is counted backwards to avoid conflicts with
the FLAG_CHANGED request which is still active }
SimConnect_RequestDataOnSimObject(SimConnectHandle, High(Cardinal) - ADefinitionID, ADefinitionID,
SIMCONNECT_OBJECT_ID_USER,
SIMCONNECT_PERIOD_SIM_FRAME,
0, 0, 0, 1);
end;
procedure TFSXSimConnectClient.UnregisterDefinition(ADefinitionID: Cardinal);
begin
if SimConnectHandle <> 0 then
SimConnect_ClearDataDefinition(SimConnectHandle, ADefinitionID);
end;
function TFSXSimConnectClient.SameDefinition(ADefinition1, ADefinition2: IFSXSimConnectDefinitionAccess): Boolean; function TFSXSimConnectClient.SameDefinition(ADefinition1, ADefinition2: IFSXSimConnectDefinitionAccess): Boolean;
var var
variableIndex: Integer; variableIndex: Integer;
@ -463,6 +496,10 @@ begin
begin begin
definitionRef.Attach(addDefinition.DataHandler); definitionRef.Attach(addDefinition.DataHandler);
addDefinition.DefinitionID := definitionID; addDefinition.DefinitionID := definitionID;
{ Request an update on the definition to update the new worker }
UpdateDefinition(definitionID);
hasDefinition := True; hasDefinition := True;
break; break;
end; end;
@ -488,11 +525,22 @@ end;
procedure TFSXSimConnectClient.TMRemoveDefinition(var Msg: TOmniMessage); procedure TFSXSimConnectClient.TMRemoveDefinition(var Msg: TOmniMessage);
var var
removeDefinition: TRemoveDefinitionValue; removeDefinition: TRemoveDefinitionValue;
definitionRef: TFSXSimConnectDefinitionRef;
begin begin
removeDefinition := Msg.MsgData; removeDefinition := Msg.MsgData;
// #ToDo1 -oMvR: 22-2-2013: actually remove the definition if Definitions.ContainsKey(removeDefinition.DefinitionID) then
begin
definitionRef := Definitions[removeDefinition.DefinitionID];
if definitionRef.Detach(removeDefinition.DataHandler) = 0 then
begin
{ Unregister with SimConnect }
UnregisterDefinition(removeDefinition.DefinitionID);
Definitions.Remove(removeDefinition.DefinitionID);
end;
end;
removeDefinition.Signal; removeDefinition.Signal;
end; end;
@ -538,9 +586,17 @@ begin
end; end;
procedure TFSXSimConnectDefinitionRef.Detach(ADataHandler: IFSXSimConnectDataHandler); function TFSXSimConnectDefinitionRef.Detach(ADataHandler: IFSXSimConnectDataHandler): Integer;
begin begin
DataHandlers.Remove(ADataHandler as IFSXSimConnectDataHandler); DataHandlers.Remove(ADataHandler as IFSXSimConnectDataHandler);
Result := DataHandlers.Count;
end;
{ TFSXSimConnectDefinitionMap }
constructor TFSXSimConnectDefinitionMap.Create(ACapacity: Integer);
begin
inherited Create([doOwnsValues], ACapacity);
end; end;

View File

@ -55,6 +55,14 @@ type
end; end;
TFSXSimConnectState = (scsDisconnected, scsConnected, scsFailed);
IFSXSimConnectStateObserver = interface
['{0508904F-8189-479D-AF70-E98B00C9D9B2}']
procedure ObserverStateUpdate(ANewState: TFSXSimConnectState);
end;
const const
FSX_UNIT_PERCENT = 'percent'; FSX_UNIT_PERCENT = 'percent';
FSX_UNIT_MASK = 'mask'; FSX_UNIT_MASK = 'mask';

View File

@ -0,0 +1,114 @@
unit FSXSimConnectStateMonitor;
interface
uses
System.Classes,
System.SyncObjs,
FSXSimConnectIntf;
type
TFSXSimConnectStateMonitor = class(TObject)
private
FObservers: TInterfaceList;
FCurrentStateLock: TCriticalSection;
FCurrentState: TFSXSimConnectState;
procedure DoSetCurrentState(const Value: TFSXSimConnectState);
protected
property CurrentStateLock: TCriticalSection read FCurrentStateLock;
property Observers: TInterfaceList read FObservers;
public
constructor Create;
destructor Destroy; override;
class function Instance: TFSXSimConnectStateMonitor;
class procedure SetCurrentState(AState: TFSXSimConnectState);
procedure Attach(AObserver: IFSXSimConnectStateObserver);
procedure Detach(AObserver: IFSXSimConnectStateObserver);
property CurrentState: TFSXSimConnectState read FCurrentState write DoSetCurrentState;
end;
implementation
uses
System.SysUtils;
var
FSXSimConnectStateInstance: TFSXSimConnectStateMonitor;
{ TFSXSimConnectState }
class function TFSXSimConnectStateMonitor.Instance: TFSXSimConnectStateMonitor;
begin
Result := FSXSimConnectStateInstance;
end;
class procedure TFSXSimConnectStateMonitor.SetCurrentState(AState: TFSXSimConnectState);
begin
Instance.DoSetCurrentState(AState);
end;
constructor TFSXSimConnectStateMonitor.Create;
begin
inherited Create;
FCurrentStateLock := TCriticalSection.Create;
FObservers := TInterfaceList.Create;
end;
destructor TFSXSimConnectStateMonitor.Destroy;
begin
FreeAndNil(FObservers);
FreeAndNil(FCurrentStateLock);
inherited Destroy;
end;
procedure TFSXSimConnectStateMonitor.Attach(AObserver: IFSXSimConnectStateObserver);
begin
Observers.Add(AObserver as IFSXSimConnectStateObserver);
end;
procedure TFSXSimConnectStateMonitor.Detach(AObserver: IFSXSimConnectStateObserver);
begin
Observers.Remove(AObserver as IFSXSimConnectStateObserver);
end;
procedure TFSXSimConnectStateMonitor.DoSetCurrentState(const Value: TFSXSimConnectState);
var
observer: IInterface;
begin
CurrentStateLock.Acquire;
try
if Value <> FCurrentState then
begin
FCurrentState := Value;
for observer in Observers do
(observer as IFSXSimConnectStateObserver).ObserverStateUpdate(CurrentState);
end;
finally
CurrentStateLock.Release;
end;
end;
initialization
FSXSimConnectStateInstance := TFSXSimConnectStateMonitor.Create;
finalization
FreeAndNil(FSXSimConnectStateInstance);
end.

View File

@ -179,8 +179,8 @@ begin
for buttonIndex := 0 to Pred(G940_BUTTONCOUNT) do for buttonIndex := 0 to Pred(G940_BUTTONCOUNT) do
begin begin
if buttonIndex >= ButtonColors.Count then if (buttonIndex >= ButtonColors.Count) or (not Assigned(ButtonColors[buttonIndex])) then
buttonColor := lcOff buttonColor := lcGreen
else else
buttonColor := (ButtonColors[buttonIndex] as ILEDStateColor).GetCurrentColor; buttonColor := (ButtonColors[buttonIndex] as ILEDStateColor).GetCurrentColor;

View File

@ -2,7 +2,8 @@ unit LEDFunction;
interface interface
uses uses
Classes, System.Classes,
System.SyncObjs,
LEDFunctionIntf, LEDFunctionIntf,
LEDStateIntf; LEDStateIntf;
@ -10,7 +11,7 @@ uses
type type
TCustomLEDFunctionWorker = class; TCustomLEDFunctionWorker = class;
TCustomLEDFunctionWorkerClass = class of TCustomLEDFunctionWorker; TCustomLEDMultiStateFunctionWorkerClass = class of TCustomLEDMultiStateFunctionWorker;
TCustomLEDFunctionProvider = class(TInterfacedObject, ILEDFunctionProvider) TCustomLEDFunctionProvider = class(TInterfacedObject, ILEDFunctionProvider)
@ -38,26 +39,27 @@ type
function GetDisplayName: string; virtual; abstract; function GetDisplayName: string; virtual; abstract;
function GetUID: string; virtual; abstract; function GetUID: string; virtual; abstract;
function CreateWorker(ASettings: ILEDFunctionWorkerSettings): ILEDFunctionWorker; virtual; abstract; function CreateWorker(ASettings: ILEDFunctionWorkerSettings; const APreviousState: string = ''): ILEDFunctionWorker; virtual; abstract;
end; end;
TCustomMultiStateLEDFunction = class(TCustomLEDFunction, ILEDMultiStateFunction) TCustomMultiStateLEDFunction = class(TCustomLEDFunction, ILEDMultiStateFunction)
private private
FStates: TInterfaceList; FStates: TInterfaceList;
FProviderUID: string;
protected protected
procedure RegisterStates; virtual; abstract; procedure RegisterStates; virtual; abstract;
function RegisterState(AState: ILEDState): ILEDState; virtual; function RegisterState(AState: ILEDState): ILEDState; virtual;
function GetWorkerClass: TCustomLEDFunctionWorkerClass; virtual; abstract; function GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass; virtual; abstract;
function DoCreateWorker(ASettings: ILEDFunctionWorkerSettings): TCustomLEDFunctionWorker; virtual; function DoCreateWorker(ASettings: ILEDFunctionWorkerSettings; const APreviousState: string = ''): TCustomLEDFunctionWorker; virtual;
protected protected
function CreateWorker(ASettings: ILEDFunctionWorkerSettings): ILEDFunctionWorker; override; function CreateWorker(ASettings: ILEDFunctionWorkerSettings; const APreviousState: string = ''): ILEDFunctionWorker; override;
{ ILEDMultiStateFunction } { ILEDMultiStateFunction }
function GetEnumerator: ILEDStateEnumerator; virtual; function GetEnumerator: ILEDStateEnumerator; virtual;
public public
constructor Create; constructor Create(const AProviderUID: string);
destructor Destroy; override; destructor Destroy; override;
end; end;
@ -65,25 +67,44 @@ type
TCustomLEDFunctionWorker = class(TInterfacedObject, ILEDFunctionWorker) TCustomLEDFunctionWorker = class(TInterfacedObject, ILEDFunctionWorker)
private private
FObservers: TInterfaceList; FObservers: TInterfaceList;
FStates: TInterfaceList; FProviderUID: string;
FFunctionUID: string;
protected protected
procedure RegisterStates(AStates: ILEDMultiStateFunction; ASettings: ILEDFunctionWorkerSettings); virtual;
function FindState(const AUID: string): ILEDStateWorker; virtual;
procedure NotifyObservers; virtual; procedure NotifyObservers; virtual;
property Observers: TInterfaceList read FObservers; property Observers: TInterfaceList read FObservers;
property States: TInterfaceList read FStates;
protected protected
{ ILEDFunctionWorker } { ILEDFunctionWorker }
procedure Attach(AObserver: ILEDFunctionObserver); virtual; procedure Attach(AObserver: ILEDFunctionObserver); virtual;
procedure Detach(AObserver: ILEDFunctionObserver); virtual; procedure Detach(AObserver: ILEDFunctionObserver); virtual;
function GetProviderUID: string; virtual;
function GetFunctionUID: string; virtual;
function GetCurrentState: ILEDStateWorker; virtual; abstract; function GetCurrentState: ILEDStateWorker; virtual; abstract;
public public
constructor Create; overload; virtual; constructor Create(const AProviderUID, AFunctionUID: string);
constructor Create(AStates: ILEDMultiStateFunction; ASettings: ILEDFunctionWorkerSettings); overload; virtual; destructor Destroy; override;
end;
TCustomLEDMultiStateFunctionWorker = class(TCustomLEDFunctionWorker)
private
FStates: TInterfaceList;
FCurrentStateLock: TCriticalSection;
FCurrentState: ILEDStateWorker;
protected
procedure RegisterStates(AStates: ILEDMultiStateFunction; ASettings: ILEDFunctionWorkerSettings); virtual;
function FindState(const AUID: string): ILEDStateWorker; virtual;
procedure SetCurrentState(const AUID: string; ANotifyObservers: Boolean = True); overload; virtual;
procedure SetCurrentState(AState: ILEDStateWorker; ANotifyObservers: Boolean = True); overload; virtual;
property States: TInterfaceList read FStates;
protected
function GetCurrentState: ILEDStateWorker; override;
public
constructor Create(const AProviderUID, AFunctionUID: string; AStates: ILEDMultiStateFunction; ASettings: ILEDFunctionWorkerSettings; const APreviousState: string = ''); virtual;
destructor Destroy; override; destructor Destroy; override;
end; end;
@ -125,11 +146,13 @@ uses
{ TCustomMultiStateLEDFunction } { TCustomMultiStateLEDFunction }
constructor TCustomMultiStateLEDFunction.Create; constructor TCustomMultiStateLEDFunction.Create(const AProviderUID: string);
begin begin
inherited Create; inherited Create;
FStates := TInterfaceList.Create; FStates := TInterfaceList.Create;
FProviderUID := AProviderUID;
RegisterStates; RegisterStates;
end; end;
@ -155,39 +178,31 @@ begin
end; end;
function TCustomMultiStateLEDFunction.CreateWorker(ASettings: ILEDFunctionWorkerSettings): ILEDFunctionWorker; function TCustomMultiStateLEDFunction.CreateWorker(ASettings: ILEDFunctionWorkerSettings; const APreviousState: string): ILEDFunctionWorker;
begin begin
Result := DoCreateWorker(ASettings); Result := DoCreateWorker(ASettings, APreviousState);
end; end;
function TCustomMultiStateLEDFunction.DoCreateWorker(ASettings: ILEDFunctionWorkerSettings): TCustomLEDFunctionWorker; function TCustomMultiStateLEDFunction.DoCreateWorker(ASettings: ILEDFunctionWorkerSettings; const APreviousState: string): TCustomLEDFunctionWorker;
begin begin
Result := GetWorkerClass.Create(Self, ASettings); Result := GetWorkerClass.Create(FProviderUID, GetUID, Self, ASettings, APreviousState);
end; end;
{ TCustomLEDFunctionWorker } { TCustomLEDFunctionWorker }
constructor TCustomLEDFunctionWorker.Create; constructor TCustomLEDFunctionWorker.Create(const AProviderUID, AFunctionUID: string);
begin begin
inherited Create; inherited Create;
FObservers := TInterfaceList.Create; FObservers := TInterfaceList.Create;
end; FProviderUID := AProviderUID;
FFunctionUID := AFunctionUID;
constructor TCustomLEDFunctionWorker.Create(AStates: ILEDMultiStateFunction; ASettings: ILEDFunctionWorkerSettings);
begin
Create;
FStates := TInterfaceList.Create;
RegisterStates(AStates, ASettings);
end; end;
destructor TCustomLEDFunctionWorker.Destroy; destructor TCustomLEDFunctionWorker.Destroy;
begin begin
FreeAndNil(FStates);
FreeAndNil(FObservers); FreeAndNil(FObservers);
inherited Destroy; inherited Destroy;
@ -207,7 +222,57 @@ begin
end; end;
procedure TCustomLEDFunctionWorker.RegisterStates(AStates: ILEDMultiStateFunction; ASettings: ILEDFunctionWorkerSettings); function TCustomLEDFunctionWorker.GetProviderUID: string;
begin
Result := FProviderUID;
end;
function TCustomLEDFunctionWorker.GetFunctionUID: string;
begin
Result := FFunctionUID;
end;
procedure TCustomLEDFunctionWorker.NotifyObservers;
var
observer: IInterface;
begin
for observer in Observers do
(observer as ILEDFunctionObserver).ObserveUpdate(Self);
end;
{ TCustomLEDMultiStateFunctionWorker }
constructor TCustomLEDMultiStateFunctionWorker.Create(const AProviderUID, AFunctionUID: string; AStates: ILEDMultiStateFunction; ASettings: ILEDFunctionWorkerSettings; const APreviousState: string);
begin
inherited Create(AProviderUID, AFunctionUID);
FCurrentStateLock := TCriticalSection.Create;
FStates := TInterfaceList.Create;
RegisterStates(AStates, ASettings);
if Length(APreviousState) > 0 then
FCurrentState := FindState(APreviousState);
{ Make sure we have a default state }
if (not Assigned(FCurrentState)) and (States.Count > 0) then
SetCurrentState((States[0] as ILEDStateWorker), False);
end;
destructor TCustomLEDMultiStateFunctionWorker.Destroy;
begin
FreeAndNil(FCurrentStateLock);
FreeAndNil(FStates);
inherited Destroy;
end;
procedure TCustomLEDMultiStateFunctionWorker.RegisterStates(AStates: ILEDMultiStateFunction; ASettings: ILEDFunctionWorkerSettings);
var var
state: ILEDState; state: ILEDState;
color: TLEDColor; color: TLEDColor;
@ -223,7 +288,7 @@ begin
end; end;
function TCustomLEDFunctionWorker.FindState(const AUID: string): ILEDStateWorker; function TCustomLEDMultiStateFunctionWorker.FindState(const AUID: string): ILEDStateWorker;
var var
state: IInterface; state: IInterface;
@ -241,13 +306,37 @@ begin
end; end;
procedure TCustomLEDFunctionWorker.NotifyObservers; procedure TCustomLEDMultiStateFunctionWorker.SetCurrentState(const AUID: string; ANotifyObservers: Boolean);
var
observer: IInterface;
begin begin
for observer in Observers do SetCurrentState(FindState(AUID), ANotifyObservers);
(observer as ILEDFunctionObserver).ObserveUpdate(Self); end;
procedure TCustomLEDMultiStateFunctionWorker.SetCurrentState(AState: ILEDStateWorker; ANotifyObservers: Boolean);
begin
FCurrentStateLock.Acquire;
try
if AState <> FCurrentState then
begin
FCurrentState := AState;
if ANotifyObservers then
NotifyObservers;
end;
finally
FCurrentStateLock.Release;
end;
end;
function TCustomLEDMultiStateFunctionWorker.GetCurrentState: ILEDStateWorker;
begin
FCurrentStateLock.Acquire;
try
Result := FCurrentState;
finally
FCurrentStateLock.Release;
end;
end; end;

View File

@ -29,7 +29,7 @@ type
function GetDisplayName: string; function GetDisplayName: string;
function GetUID: string; function GetUID: string;
function CreateWorker(ASettings: ILEDFunctionWorkerSettings): ILEDFunctionWorker; function CreateWorker(ASettings: ILEDFunctionWorkerSettings; const APreviousState: string = ''): ILEDFunctionWorker;
end; end;
@ -50,6 +50,9 @@ type
procedure Attach(AObserver: ILEDFunctionObserver); procedure Attach(AObserver: ILEDFunctionObserver);
procedure Detach(AObserver: ILEDFunctionObserver); procedure Detach(AObserver: ILEDFunctionObserver);
function GetProviderUID: string;
function GetFunctionUID: string;
function GetCurrentState: ILEDStateWorker; function GetCurrentState: ILEDStateWorker;
end; end;

View File

@ -30,7 +30,7 @@ type
function Initialize: Boolean; override; function Initialize: Boolean; override;
procedure Cleanup; override; procedure Cleanup; override;
function CreateWorker(AProfileButton: TProfileButton): ILEDFunctionWorker; function CreateWorker(AProfileButton: TProfileButton; const APreviousState: string): ILEDFunctionWorker;
property ButtonWorkers: TInterfaceList read FButtonWorkers; property ButtonWorkers: TInterfaceList read FButtonWorkers;
property ButtonColors: TInterfaceList read FButtonColors; property ButtonColors: TInterfaceList read FButtonColors;
@ -49,6 +49,7 @@ type
implementation implementation
uses uses
Generics.Collections,
System.SysUtils, System.SysUtils,
Winapi.Windows, Winapi.Windows,
@ -95,7 +96,7 @@ begin
end; end;
function TLEDStateConsumer.CreateWorker(AProfileButton: TProfileButton): ILEDFunctionWorker; function TLEDStateConsumer.CreateWorker(AProfileButton: TProfileButton; const APreviousState: string): ILEDFunctionWorker;
var var
provider: ILEDFunctionProvider; provider: ILEDFunctionProvider;
ledFunction: ILEDFunction; ledFunction: ILEDFunction;
@ -108,7 +109,7 @@ begin
begin begin
ledFunction := provider.Find(AProfileButton.FunctionUID); ledFunction := provider.Find(AProfileButton.FunctionUID);
if Assigned(ledFunction) then if Assigned(ledFunction) then
Result := ledFunction.CreateWorker(TProfileButtonWorkerSettings.Create(AProfileButton)); Result := ledFunction.CreateWorker(TProfileButtonWorkerSettings.Create(AProfileButton), APreviousState);
end; end;
end; end;
@ -175,26 +176,55 @@ end;
procedure TLEDStateConsumer.TMLoadProfile(var Msg: TOmniMessage); procedure TLEDStateConsumer.TMLoadProfile(var Msg: TOmniMessage);
function GetFunctionKey(const AProviderUID, AFunctionUID: string): string; inline;
begin
Result := AProviderUID + '|' + AFunctionUID;
end;
var var
oldWorkers: TInterfaceList; oldWorkers: TInterfaceList;
oldStates: TDictionary<string, string>;
oldWorker: IInterface; oldWorker: IInterface;
profile: TProfile; profile: TProfile;
buttonIndex: Integer; buttonIndex: Integer;
worker: ILEDFunctionWorker; worker: ILEDFunctionWorker;
state: ILEDStateWorker;
previousState: string;
button: TProfileButton;
functionKey: string;
begin begin
profile := Msg.MsgData; profile := Msg.MsgData;
{ Keep a copy of the old workers until all the new ones are initialized, oldStates := nil;
so we don't get unneccessary SimConnect reconnects. } oldWorkers := nil;
oldWorkers := TInterfaceList.Create;
try try
oldStates := TDictionary<string, string>.Create;
oldWorkers := TInterfaceList.Create;
{ Keep a copy of the old workers until all the new ones are initialized,
so we don't get unneccessary SimConnect reconnects. }
for oldWorker in ButtonWorkers do for oldWorker in ButtonWorkers do
begin begin
if Assigned(oldWorker) then if Assigned(oldWorker) then
begin begin
(oldWorker as ILEDFunctionWorker).Detach(Self); worker := (oldWorker as ILEDFunctionWorker);
oldWorkers.Add(oldWorker); try
worker.Detach(Self);
oldWorkers.Add(worker);
{ Keep the current state as well, to prevent the LEDs from flickering }
state := worker.GetCurrentState;
try
oldStates.AddOrSetValue(GetFunctionKey(worker.GetProviderUID, worker.GetFunctionUID), state.GetUID);
finally
state := nil;
end;
finally
worker := nil;
end;
end; end;
end; end;
@ -204,7 +234,14 @@ begin
begin begin
if profile.HasButton(buttonIndex) then if profile.HasButton(buttonIndex) then
begin begin
worker := CreateWorker(profile.Buttons[buttonIndex]) as ILEDFunctionWorker; button := profile.Buttons[buttonIndex];
previousState := '';
functionKey := GetFunctionKey(button.ProviderUID, button.FunctionUID);
if oldStates.ContainsKey(functionKey) then
previousState := oldStates[functionKey];
worker := CreateWorker(button, previousState) as ILEDFunctionWorker;
ButtonWorkers.Add(worker); ButtonWorkers.Add(worker);
if Assigned(worker) then if Assigned(worker) then
@ -214,6 +251,7 @@ begin
end; end;
finally finally
FreeAndNil(oldWorkers); FreeAndNil(oldWorkers);
FreeAndNil(oldStates);
end; end;
Changed; Changed;

View File

@ -28,6 +28,8 @@ type
constructor Create; constructor Create;
destructor Destroy; override; destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
procedure ClearStateColors; procedure ClearStateColors;
function GetStateColor(const AStateUID: string; out AValue: TLEDColor): Boolean; function GetStateColor(const AStateUID: string; out AValue: TLEDColor): Boolean;
procedure SetStateColor(const AStateUID: string; const AValue: TLEDColor); procedure SetStateColor(const AStateUID: string; const AValue: TLEDColor);
@ -43,20 +45,24 @@ type
TProfile = class(TPersistent) TProfile = class(TPersistent)
private private
FName: string; FName: string;
FIsTemporary: Boolean;
FButtons: TProfileButtonList; FButtons: TProfileButtonList;
function GetButton(Index: Integer): TProfileButton; function GetButton(Index: Integer): TProfileButton;
function GetButtonCount: Integer; function GetButtonCount: Integer;
protected protected
function Load(AReader: IX2PersistReader): Boolean; procedure Load(AReader: IX2PersistReader);
procedure Save(AWriter: IX2PersistWriter); procedure Save(AWriter: IX2PersistWriter);
public public
constructor Create; constructor Create;
destructor Destroy; override; destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
function HasButton(AIndex: Integer): Boolean; function HasButton(AIndex: Integer): Boolean;
property Name: string read FName write FName; property Name: string read FName write FName;
property IsTemporary: Boolean read FIsTemporary write FIsTemporary;
property ButtonCount: Integer read GetButtonCount; property ButtonCount: Integer read GetButtonCount;
property Buttons[Index: Integer]: TProfileButton read GetButton; property Buttons[Index: Integer]: TProfileButton read GetButton;
@ -65,6 +71,8 @@ type
TProfileList = class(TObjectList<TProfile>) TProfileList = class(TObjectList<TProfile>)
public public
function Find(const AName: string): TProfile;
procedure Load(AReader: IX2PersistReader); procedure Load(AReader: IX2PersistReader);
procedure Save(AWriter: IX2PersistWriter); procedure Save(AWriter: IX2PersistWriter);
end; end;
@ -84,6 +92,7 @@ const
KeyProviderUID = 'ProviderUID'; KeyProviderUID = 'ProviderUID';
KeyFunctionUID = 'FunctionUID'; KeyFunctionUID = 'FunctionUID';
KeyIsTemporary = 'IsTemporary';
{ TProfileButton } { TProfileButton }
@ -103,6 +112,27 @@ begin
end; end;
procedure TProfileButton.Assign(Source: TPersistent);
var
sourceButton: TProfileButton;
stateUID: string;
begin
if Source is TProfileButton then
begin
sourceButton := TProfileButton(Source);
FProviderUID := sourceButton.ProviderUID;
FFunctionUID := sourceButton.FunctionUID;
FStateColors.Clear;
for stateUID in sourceButton.StateColors.Keys do
SetStateColor(stateUID, sourceButton.StateColors[stateUID]);
end else
inherited Assign(Source);
end;
procedure TProfileButton.ClearStateColors; procedure TProfileButton.ClearStateColors;
begin begin
FStateColors.Clear; FStateColors.Clear;
@ -192,22 +222,44 @@ begin
end; end;
function TProfile.Load(AReader: IX2PersistReader): Boolean; procedure TProfile.Assign(Source: TPersistent);
var
sourceProfile: TProfile;
buttonIndex: Integer;
begin
if Source is TProfile then
begin
sourceProfile := TProfile(Source);
FName := sourceProfile.Name;
FIsTemporary := sourceProfile.IsTemporary;
FButtons.Clear;
for buttonIndex := 0 to Pred(sourceProfile.ButtonCount) do
Buttons[buttonIndex].Assign(sourceProfile.Buttons[buttonIndex]);
end else
inherited Assign(Source);
end;
procedure TProfile.Load(AReader: IX2PersistReader);
var var
buttonIndex: Integer; buttonIndex: Integer;
button: TProfileButton; button: TProfileButton;
begin begin
Result := False;
buttonIndex := 0; buttonIndex := 0;
if not AReader.ReadBoolean(KeyIsTemporary, FIsTemporary) then
FIsTemporary := False;
while AReader.BeginSection(SectionButton + IntToStr(buttonIndex)) do while AReader.BeginSection(SectionButton + IntToStr(buttonIndex)) do
try try
button := TProfileButton.Create; button := TProfileButton.Create;
if button.Load(AReader) then if button.Load(AReader) then
begin begin
FButtons.Add(button); FButtons.Add(button);
Result := True;
end else end else
FreeAndNil(button); FreeAndNil(button);
finally finally
@ -222,6 +274,8 @@ var
buttonIndex: Integer; buttonIndex: Integer;
begin begin
AWriter.WriteBoolean(KeyIsTemporary, IsTemporary);
for buttonIndex := 0 to Pred(FButtons.Count) do for buttonIndex := 0 to Pred(FButtons.Count) do
begin begin
if AWriter.BeginSection(SectionButton + IntToStr(buttonIndex)) then if AWriter.BeginSection(SectionButton + IntToStr(buttonIndex)) then
@ -272,6 +326,22 @@ end;
{ TProfileList } { TProfileList }
function TProfileList.Find(const AName: string): TProfile;
var
profile: TProfile;
begin
Result := nil;
for profile in Self do
if SameText(profile.Name, AName) then
begin
Result := profile;
break;
end;
end;
procedure TProfileList.Load(AReader: IX2PersistReader); procedure TProfileList.Load(AReader: IX2PersistReader);
var var
profiles: TStringList; profiles: TStringList;
@ -291,11 +361,9 @@ begin
try try
profile := TProfile.Create; profile := TProfile.Create;
profile.Name := profileName; profile.Name := profileName;
profile.Load(AReader);
if profile.Load(AReader) then Add(profile);
Add(profile)
else
FreeAndNil(profile);
finally finally
AReader.EndSection; AReader.EndSection;
end; end;

View File

@ -9,6 +9,7 @@ type
private private
FCheckUpdates: Boolean; FCheckUpdates: Boolean;
FHasCheckUpdates: Boolean; FHasCheckUpdates: Boolean;
FActiveProfile: string;
procedure SetCheckUpdates(const Value: Boolean); procedure SetCheckUpdates(const Value: Boolean);
public public
@ -17,6 +18,8 @@ type
property CheckUpdates: Boolean read FCheckUpdates write SetCheckUpdates; property CheckUpdates: Boolean read FCheckUpdates write SetCheckUpdates;
property HasCheckUpdates: Boolean read FHasCheckUpdates; property HasCheckUpdates: Boolean read FHasCheckUpdates;
property ActiveProfile: string read FActiveProfile write FActiveProfile;
end; end;
@ -25,6 +28,7 @@ const
SectionSettings = 'Settings'; SectionSettings = 'Settings';
KeyCheckUpdates = 'CheckUpdates'; KeyCheckUpdates = 'CheckUpdates';
KeyActiveProfile = 'ActiveProfile';
{ TSettings } { TSettings }
@ -37,6 +41,9 @@ begin
try try
if AReader.ReadBoolean(KeyCheckUpdates, value) then if AReader.ReadBoolean(KeyCheckUpdates, value) then
CheckUpdates := value; CheckUpdates := value;
if not AReader.ReadString(KeyActiveProfile, FActiveProfile) then
FActiveProfile := '';
finally finally
AReader.EndSection; AReader.EndSection;
end; end;
@ -48,6 +55,7 @@ begin
if AWriter.BeginSection(SectionSettings) then if AWriter.BeginSection(SectionSettings) then
try try
AWriter.WriteBoolean(KeyCheckUpdates, CheckUpdates); AWriter.WriteBoolean(KeyCheckUpdates, CheckUpdates);
AWriter.WriteString(KeyActiveProfile, ActiveProfile);
finally finally
AWriter.EndSection; AWriter.EndSection;
end; end;

View File

@ -25,7 +25,7 @@ type
function GetDisplayName: string; override; function GetDisplayName: string; override;
function GetUID: string; override; function GetUID: string; override;
function CreateWorker(ASettings: ILEDFunctionWorkerSettings): ILEDFunctionWorker; override; function CreateWorker(ASettings: ILEDFunctionWorkerSettings; const APreviousState: string = ''): ILEDFunctionWorker; override;
public public
constructor Create(AColor: TLEDColor); constructor Create(AColor: TLEDColor);
end; end;
@ -46,7 +46,7 @@ type
protected protected
function GetCurrentState: ILEDStateWorker; override; function GetCurrentState: ILEDStateWorker; override;
public public
constructor Create(AColor: TLEDColor); constructor Create(const AProviderUID, AFunctionUID: string; AColor: TLEDColor);
end; end;
@ -94,16 +94,16 @@ begin
end; end;
function TStaticLEDFunction.CreateWorker(ASettings: ILEDFunctionWorkerSettings): ILEDFunctionWorker; function TStaticLEDFunction.CreateWorker(ASettings: ILEDFunctionWorkerSettings; const APreviousState: string): ILEDFunctionWorker;
begin begin
Result := TStaticLEDFunctionWorker.Create(FColor); Result := TStaticLEDFunctionWorker.Create(StaticProviderUID, GetUID, FColor);
end; end;
{ TStaticLEDFunctionWorker } { TStaticLEDFunctionWorker }
constructor TStaticLEDFunctionWorker.Create(AColor: TLEDColor); constructor TStaticLEDFunctionWorker.Create(const AProviderUID, AFunctionUID: string; AColor: TLEDColor);
begin begin
inherited Create; inherited Create(AProviderUID, AFunctionUID);
FState := TLEDStateWorker.Create('', TLEDColorPool.GetColor(AColor)); FState := TLEDStateWorker.Create('', TLEDColorPool.GetColor(AColor));
end; end;