1
0
mirror of synced 2024-11-22 10:03:51 +00:00

Added: engine, landing gear and light state functions as an implementation proof of concept

Added: IFSXSimConnect interface and data handling prototype
This commit is contained in:
Mark van Renswoude 2013-02-18 21:46:32 +00:00
parent d665f2d979
commit b66659cd95
9 changed files with 614 additions and 94 deletions

View File

@ -13,7 +13,6 @@ uses
LEDColorIntf in 'Units\LEDColorIntf.pas',
LEDColor in 'Units\LEDColor.pas',
LEDFunctionIntf in 'Units\LEDFunctionIntf.pas',
ObserverIntf in 'Units\ObserverIntf.pas',
LEDFunction in 'Units\LEDFunction.pas',
StaticLEDFunction in 'Units\StaticLEDFunction.pas',
ConfigConversion in 'Units\ConfigConversion.pas',

View File

@ -173,7 +173,6 @@
<DCCReference Include="Units\LEDColorIntf.pas"/>
<DCCReference Include="Units\LEDColor.pas"/>
<DCCReference Include="Units\LEDFunctionIntf.pas"/>
<DCCReference Include="Units\ObserverIntf.pas"/>
<DCCReference Include="Units\LEDFunction.pas"/>
<DCCReference Include="Units\StaticLEDFunction.pas"/>
<DCCReference Include="Units\ConfigConversion.pas"/>

View File

@ -0,0 +1,366 @@
unit FSXLEDFunction;
interface
uses
FSXLEDFunctionProvider,
LEDFunction,
LEDFunctionIntf;
type
{ Base classes }
TFSXOnOffFunction = class(TCustomFSXFunction)
protected
procedure RegisterStates; override;
end;
{ Function implementations }
TFSXEngineFunction = class(TCustomFSXFunction)
protected
procedure RegisterStates; override;
function GetWorkerClass: TCustomLEDFunctionWorkerClass; override;
end;
TFSXGearFunction = class(TCustomFSXFunction)
protected
procedure RegisterStates; override;
function GetWorkerClass: TCustomLEDFunctionWorkerClass; override;
end;
TFSXLightFunction = class(TFSXOnOffFunction)
protected
function GetCategoryName: string; override;
function GetWorkerClass: TCustomLEDFunctionWorkerClass; override;
function DoCreateWorker(ASettings: ILEDFunctionWorkerSettings): TCustomLEDFunctionWorker; override;
protected
function GetLightMask: Integer; virtual; abstract;
end;
TFSXLandingLightsFunction = class(TFSXLightFunction)
protected
function GetLightMask: Integer; override;
end;
TFSXInstrumentLightsFunction = class(TFSXLightFunction)
protected
function GetLightMask: Integer; override;
end;
TFSXBeaconLightsFunction = class(TFSXLightFunction)
protected
function GetLightMask: Integer; override;
end;
TFSXNavLightsFunction = class(TFSXLightFunction)
protected
function GetLightMask: Integer; override;
end;
TFSXStrobeLightsFunction = class(TFSXLightFunction)
protected
function GetLightMask: Integer; override;
end;
TFSXTaxiLightsFunction = class(TFSXLightFunction)
protected
function GetLightMask: Integer; override;
end;
TFSXRecognitionLightsFunction = class(TFSXLightFunction)
protected
function GetLightMask: Integer; override;
end;
implementation
uses
System.Math,
System.SysUtils,
FSXSimConnectIntf,
FSXResources,
LEDColorIntf,
LEDState,
LEDStateIntf,
SimConnect;
type
{ Worker implementations }
TFSXEngineFunctionWorker = class(TCustomFSXFunctionWorker)
protected
procedure RegisterVariables; override;
procedure HandleData(AData: Pointer); override;
end;
TFSXGearFunctionWorker = class(TCustomFSXFunctionWorker)
protected
procedure RegisterVariables; override;
procedure HandleData(AData: Pointer); override;
end;
TFSXLightStatesFunctionWorker = class(TCustomFSXFunctionWorker)
private
FStateMask: Integer;
protected
procedure RegisterVariables; override;
procedure HandleData(AData: Pointer); override;
public
property StateMask: Integer read FStateMask write FStateMask;
end;
{ TFSXOnOffFunction }
procedure TFSXOnOffFunction.RegisterStates;
begin
RegisterState(TLEDState.Create(FSXStateUIDOn, FSXStateDisplayNameOn, lcGreen));
RegisterState(TLEDState.Create(FSXStateUIDOff, FSXStateDisplayNameOff, lcRed));
end;
{ TFSXEngineFunction }
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: TCustomLEDFunctionWorkerClass;
begin
Result := TFSXEngineFunctionWorker;
end;
{ TFSXEngineFunctionWorker }
procedure TFSXEngineFunctionWorker.RegisterVariables;
var
engineIndex: Integer;
begin
Definition.AddVariable('NUMBER OF ENGINES', FSX_UNIT_NUMBER, SIMCONNECT_DATAType_INT32);
for engineIndex := 1 to FSX_MAX_ENGINES do
Definition.AddVariable(Format('GENERAL ENG COMBUSTION:%d', [engineIndex]), FSX_UNIT_BOOL, SIMCONNECT_DATAType_INT32);
for engineIndex := 1 to FSX_MAX_ENGINES do
Definition.AddVariable(Format('ENG FAILED:%d', [engineIndex]), FSX_UNIT_BOOL, SIMCONNECT_DATAType_INT32);
for engineIndex := 1 to FSX_MAX_ENGINES do
Definition.AddVariable(Format('ENG ON FIRE:%d', [engineIndex]), FSX_UNIT_BOOL, SIMCONNECT_DATAType_INT32);
end;
procedure TFSXEngineFunctionWorker.HandleData(AData: Pointer);
type
PEngineData = ^TEngineData;
TEngineData = packed record
NumberOfEngines: Integer;
Combustion: array[1..FSX_MAX_ENGINES] of Integer;
Failed: array[1..FSX_MAX_ENGINES] of Integer;
OnFire: array[1..FSX_MAX_ENGINES] of Integer;
end;
var
engineData: PEngineData;
engineCount: Integer;
engineIndex: Integer;
hasFire: Boolean;
hasFailure: Boolean;
runningCount: Integer;
begin
engineData := AData;
if engineData^.NumberOfEngines > 0 then
begin
engineCount := Min(engineData^.NumberOfEngines, FSX_MAX_ENGINES);
hasFire := False;
hasFailure := False;
runningCount := 0;
for engineIndex := 1 to engineCount do
begin
if engineData^.OnFire[engineIndex] <> 0 then
hasFire := True;
if engineData^.Failed[engineIndex] <> 0 then
hasFailure := True;
if engineData^.Combustion[engineIndex] <> 0 then
Inc(runningCount);
end;
if hasFire then
SetCurrentState(FSXStateUIDEngineOnFire)
else if hasFailure then
SetCurrentState(FSXStateUIDEngineFailed)
else if runningCount = 0 then
SetCurrentState(FSXStateUIDEngineAllOff)
else if runningCount = engineCount then
SetCurrentState(FSXStateUIDEngineAllRunning)
else
SetCurrentState(FSXStateUIDEnginePartiallyRunning);
end else
SetCurrentState(FSXStateUIDEngineNoEngines);
end;
{ TFSXGearFunction }
procedure TFSXGearFunction.RegisterStates;
begin
RegisterState(TLEDState.Create(FSXStateUIDGearNotRetractable, FSXStateDisplayNameGearNotRetractable, lcOff));
RegisterState(TLEDState.Create(FSXStateUIDGearRetracted, FSXStateDisplayNameGearRetracted, lcRed));
RegisterState(TLEDState.Create(FSXStateUIDGearBetween, FSXStateDisplayNameGearBetween, lcAmber));
RegisterState(TLEDState.Create(FSXStateUIDGearExtended, FSXStateDisplayNameGearExtended, lcGreen));
RegisterState(TLEDState.Create(FSXStateUIDGearSpeedExceeded, FSXStateDisplayNameGearSpeedExceeded, lcFlashingAmberNormal));
RegisterState(TLEDState.Create(FSXStateUIDGearDamageBySpeed, FSXStateDisplayNameGearDamageBySpeed, lcFlashingRedFast));
end;
function TFSXGearFunction.GetWorkerClass: TCustomLEDFunctionWorkerClass;
begin
Result := TFSXGearFunctionWorker;
end;
{ TFSXGearFunctionWorker }
procedure TFSXGearFunctionWorker.RegisterVariables;
begin
Definition.AddVariable('IS GEAR RETRACTABLE', FSX_UNIT_BOOL, SIMCONNECT_DATAType_INT32);
Definition.AddVariable('GEAR TOTAL PCT EXTENDED', FSX_UNIT_PERCENT, SIMCONNECT_DATAType_FLOAT64);
Definition.AddVariable('GEAR DAMAGE BY SPEED', FSX_UNIT_BOOL, SIMCONNECT_DATAType_INT32);
Definition.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;
{ TFSXLightFunction }
function TFSXLightFunction.GetCategoryName: string;
begin
Result := FSXCategoryLights;
end;
function TFSXLightFunction.GetWorkerClass: TCustomLEDFunctionWorkerClass;
begin
Result := TFSXLightStatesFunctionWorker;
end;
function TFSXLightFunction.DoCreateWorker(ASettings: ILEDFunctionWorkerSettings): TCustomLEDFunctionWorker;
begin
Result := inherited DoCreateWorker(ASettings);
(Result as TFSXLightStatesFunctionWorker).StateMask := GetLightMask;
end;
{ TFSXLandingLightsFunction }
function TFSXLandingLightsFunction.GetLightMask: Integer;
begin
Result := FSX_LIGHTON_LANDING;
end;
{ TFSXInstrumentLightsFunction }
function TFSXInstrumentLightsFunction.GetLightMask: Integer;
begin
Result := FSX_LIGHTON_PANEL;
end;
{ TFSXBeaconLightsFunction }
function TFSXBeaconLightsFunction.GetLightMask: Integer;
begin
Result := FSX_LIGHTON_BEACON;
end;
{ TFSXNavLightsFunction }
function TFSXNavLightsFunction.GetLightMask: Integer;
begin
Result := FSX_LIGHTON_NAV;
end;
{ TFSXStrobeLightsFunction }
function TFSXStrobeLightsFunction.GetLightMask: Integer;
begin
Result := FSX_LIGHTON_STROBE;
end;
{ TFSXTaxiLightsFunction }
function TFSXTaxiLightsFunction.GetLightMask: Integer;
begin
Result := FSX_LIGHTON_TAXI;
end;
{ TFSXRecognitionLightsFunction }
function TFSXRecognitionLightsFunction.GetLightMask: Integer;
begin
Result := FSX_LIGHTON_RECOGNITION;
end;
{ TFSXLightStatesFunctionWorker }
procedure TFSXLightStatesFunctionWorker.RegisterVariables;
begin
Definition.AddVariable('LIGHT ON STATES', FSX_UNIT_MASK, SIMCONNECT_DATATYPE_INT32);
end;
procedure TFSXLightStatesFunctionWorker.HandleData(AData: Pointer);
begin
if (PCardinal(AData)^ and StateMask) <> 0 then
SetCurrentState(FSXStateUIDOn)
else
SetCurrentState(FSXStateUIDOff);
end;
end.

View File

@ -8,8 +8,7 @@ uses
FSXSimConnectIntf,
LEDFunction,
LEDFunctionIntf,
LEDStateIntf,
ObserverIntf;
LEDStateIntf;
type
@ -17,24 +16,21 @@ type
TCustomFSXFunctionList = TObjectList<TCustomFSXFunction>;
TFSXLEDFunctionProvider = class(TCustomLEDFunctionProvider)
TFSXLEDFunctionProvider = class(TCustomLEDFunctionProvider, IFSXSimConnectObserver)
private
FConnectedFunctions: TCustomFSXFunctionList;
FSimConnectHandle: THandle;
protected
procedure SimConnect;
procedure SimDisconnect;
procedure Connect(AFunction: TCustomFSXFunction); virtual;
procedure Disconnect(AFunction: TCustomFSXFunction); virtual;
property ConnectedFunctions: TCustomFSXFunctionList read FConnectedFunctions;
property SimConnectHandle: THandle read FSimConnectHandle;
FSimConnect: IFSXSimConnect;
FSimConnectLock: TCriticalSection;
protected
procedure RegisterFunctions; override;
function GetUID: string; override;
protected
{ IFSXSimConnectObserver }
procedure ObserveDestroy(Sender: IFSXSimConnect);
public
constructor Create;
destructor Destroy; override;
function GetSimConnect: IFSXSimConnect;
end;
@ -45,9 +41,6 @@ type
FDisplayName: string;
FUID: string;
protected
procedure SimConnected; virtual;
procedure SimDisconnected; virtual;
property Provider: TFSXLEDFunctionProvider read FProvider;
protected
function GetCategoryName: string; override;
@ -58,7 +51,10 @@ type
end;
TCustomFSXFunctionWorker = class(TCustomLEDFunctionWorker)
TCustomFSXFunctionClass = class of TCustomFSXFunction;
TCustomFSXFunctionWorker = class(TCustomLEDFunctionWorker, IFSXSimConnectDataHandler)
private
FSimConnect: IFSXSimConnect;
FDefinition: IFSXSimConnectDefinition;
@ -73,6 +69,9 @@ type
property SimConnect: IFSXSimConnect read FSimConnect;
protected
function GetCurrentState: ILEDStateWorker; override;
{ IFSXSimConnectDataHandler }
procedure HandleData(AData: Pointer); virtual; abstract;
public
constructor Create(AStates: ILEDMultiStateFunction; ASettings: ILEDFunctionWorkerSettings; ASimConnect: IFSXSimConnect);
destructor Destroy; override;
@ -85,15 +84,63 @@ uses
FSXLEDFunction,
FSXResources,
FSXSimConnectClient,
LEDFunctionRegistry,
SimConnect;
{ TFSXLEDFunctionProvider }
constructor TFSXLEDFunctionProvider.Create;
begin
inherited Create;
FSimConnectLock := TCriticalSection.Create;
end;
destructor TFSXLEDFunctionProvider.Destroy;
begin
FreeAndNil(FSimConnectLock);
inherited Destroy;
end;
procedure TFSXLEDFunctionProvider.RegisterFunctions;
begin
RegisterFunction(TFSXGearFunction.Create(Self, FSXFunctionDisplayNameGear, FSXFunctionUIDGear));
{
AConsumer.AddFunction(FUNCTION_FSX_CARBHEAT, 'Anti-ice');
AConsumer.AddFunction(FUNCTION_FSX_AUTOPILOT, 'Auto pilot (main)');
AConsumer.AddFunction(FUNCTION_FSX_AUTOPILOT_AMBER, 'Auto pilot (main - off / amber)');
AConsumer.AddFunction(FUNCTION_FSX_AUTOPILOT_ALTITUDE, 'Auto pilot - Altitude');
AConsumer.AddFunction(FUNCTION_FSX_AUTOPILOT_APPROACH, 'Auto pilot - Approach');
AConsumer.AddFunction(FUNCTION_FSX_AUTOPILOT_BACKCOURSE, 'Auto pilot - Backcourse');
AConsumer.AddFunction(FUNCTION_FSX_AUTOPILOT_HEADING, 'Auto pilot - Heading');
AConsumer.AddFunction(FUNCTION_FSX_AUTOPILOT_NAV, 'Auto pilot - Nav');
AConsumer.AddFunction(FUNCTION_FSX_AVIONICSMASTER, 'Avionics master switch');
AConsumer.AddFunction(FUNCTION_FSX_BATTERYMASTER, 'Battery master switch');
AConsumer.AddFunction(FUNCTION_FSX_ENGINE, 'Engine');
AConsumer.AddFunction(FUNCTION_FSX_EXITDOOR, 'Exit door');
AConsumer.AddFunction(FUNCTION_FSX_FLAPS, 'Flaps');
AConsumer.AddFunction(FUNCTION_FSX_PARKINGBRAKE, 'Parking brake');
AConsumer.AddFunction(FUNCTION_FSX_PRESSURIZATIONDUMPSWITCH, 'Pressurization dump switch');
AConsumer.AddFunction(FUNCTION_FSX_SPOILERS, 'Spoilers (air brake)');
AConsumer.AddFunction(FUNCTION_FSX_TAILHOOK, 'Tail hook');
}
{ Misc }
RegisterFunction(TFSXEngineFunction.Create( Self, FSXFunctionDisplayNameEngine, FSXFunctionUIDEngine));
RegisterFunction(TFSXGearFunction.Create( Self, FSXFunctionDisplayNameGear, FSXFunctionUIDGear));
{ Lights }
RegisterFunction(TFSXBeaconLightsFunction.Create( Self, FSXFunctionDisplayNameBeaconLights, FSXFunctionUIDBeaconLights));
RegisterFunction(TFSXInstrumentLightsFunction.Create( Self, FSXFunctionDisplayNameInstrumentLights, FSXFunctionUIDInstrumentLights));
RegisterFunction(TFSXLandingLightsFunction.Create( Self, FSXFunctionDisplayNameLandingLights, FSXFunctionUIDLandingLights));
RegisterFunction(TFSXNavLightsFunction.Create( Self, FSXFunctionDisplayNameNavLights, FSXFunctionUIDNavLights));
RegisterFunction(TFSXRecognitionLightsFunction.Create(Self, FSXFunctionDisplayNameRecognitionLights, FSXFunctionUIDRecognitionLights));
RegisterFunction(TFSXStrobeLightsFunction.Create( Self, FSXFunctionDisplayNameStrobeLights, FSXFunctionUIDStrobeLights));
RegisterFunction(TFSXTaxiLightsFunction.Create( Self, FSXFunctionDisplayNameTaxiLights, FSXFunctionUIDTaxiLights));
end;
@ -103,56 +150,33 @@ begin
end;
procedure TFSXLEDFunctionProvider.ObserveDestroy(Sender: IFSXSimConnect);
begin
FSimConnectLock.Acquire;
try
FSimConnect := nil;
finally
FSimConnectLock.Release;
end;
end;
function TFSXLEDFunctionProvider.GetSimConnect: IFSXSimConnect;
begin
// TODO
end;
procedure TFSXLEDFunctionProvider.SimConnect;
var
fsxFunction: TCustomFSXFunction;
begin
if SimConnectHandle <> 0 then
exit;
// FSimConnectHandle :=
if SimConnectHandle <> 0 then
FSimConnectLock.Acquire;
try
if not Assigned(FSimConnect) then
begin
for fsxFunction in ConnectedFunctions do
fsxFunction.SimConnected;
FSimConnect := TFSXSimConnectInterface.Create;
FSimConnect.Attach(Self);
end;
end;
procedure TFSXLEDFunctionProvider.SimDisconnect;
begin
if SimConnectHandle = 0 then
exit;
end;
procedure TFSXLEDFunctionProvider.Connect(AFunction: TCustomFSXFunction);
begin
if ConnectedFunctions.IndexOf(AFunction) = -1 then
begin
ConnectedFunctions.Add(AFunction);
if ConnectedFunctions.Count > 0 then
SimConnect;
Result := FSimConnect;
finally
FSimConnectLock.Release;
end;
end;
procedure TFSXLEDFunctionProvider.Disconnect(AFunction: TCustomFSXFunction);
begin
ConnectedFunctions.Remove(AFunction);
if ConnectedFunctions.Count = 0 then
SimDisconnect;
end;
{ TCustomFSXFunction }
constructor TCustomFSXFunction.Create(AProvider: TFSXLEDFunctionProvider; const ADisplayName, AUID: string);
@ -183,16 +207,6 @@ begin
end;
procedure TCustomFSXFunction.SimConnected;
begin
end;
procedure TCustomFSXFunction.SimDisconnected;
begin
end;
{ TCustomFSXFunctionWorker }
constructor TCustomFSXFunctionWorker.Create(AStates: ILEDMultiStateFunction; ASettings: ILEDFunctionWorkerSettings; ASimConnect: IFSXSimConnect);
begin
@ -203,7 +217,9 @@ begin
FDefinition := ASimConnect.CreateDefinition;
RegisterVariables;
ASimConnect.AddDefinition(FDefinition);
// TODO pass self as callback for this definition
ASimConnect.AddDefinition(FDefinition, Self);
end;

View File

@ -3,18 +3,45 @@ unit FSXResources;
interface
const
FSXProviderUID = 'fsx';
FSXCategory = 'Flight Simulator X';
FSXCategoryLights = FSXCategory + ' - Lights';
FSXStateUIDOn = 'on';
FSXStateUIDOff = 'off';
FSXStateDisplayNameOn = 'On';
FSXStateDisplayNameOff = 'Off';
FSXFunctionUIDEngine = 'engine';
FSXFunctionDisplayNameEngine = 'Engine';
FSXStateUIDEngineNoEngines = 'noEngines';
FSXStateUIDEngineAllRunning = 'allRunning';
FSXStateUIDEnginePartiallyRunning = 'partiallyRunning';
FSXStateUIDEngineAllOff = 'allOff';
FSXStateUIDEngineFailed = 'failed';
FSXStateUIDEngineOnFire = 'onFire';
FSXStateDisplayNameEngineNoEngines = 'No engines';
FSXStateDisplayNameEngineAllRunning = 'All running';
FSXStateDisplayNameEnginePartiallyRunning = 'Partially running';
FSXStateDisplayNameEngineAllOff = 'All off';
FSXStateDisplayNameEngineFailed = 'Engine failure';
FSXStateDisplayNameEngineOnFire = 'On fire';
FSXFunctionUIDGear = 'gear';
FSXFunctionDisplayNameGear = 'Landing gear';
FSXStateUIDGearNotRetractable = 'notRetractable';
FSXStateUIDGearRetracted = 'retracted';
FSXStateUIDGearBetween = 'between';
FSXStateUIDGearExtended = 'extended';
FSXStateUIDGearSpeedExceeded = 'speedExceeded';
FSXStateUIDGearDamageBySpeed = 'damageBySpeed';
FSXStateDisplayNameGearNotRetractable = 'Not retractable';
FSXStateDisplayNameGearRetracted = 'Retracted';
FSXStateDisplayNameGearBetween = 'Extending / retracting';
FSXStateDisplayNameGearExtended = 'Extended';
@ -22,6 +49,27 @@ const
FSXStateDisplayNameGearDamageBySpeed = 'Damage by speed';
FSXFunctionUIDLandingLights = 'landingLights';
FSXFunctionDisplayNameLandingLights = 'Landing lights';
FSXFunctionUIDInstrumentLights = 'instrumentLights';
FSXFunctionDisplayNameInstrumentLights = 'Instrument lights';
FSXFunctionUIDBeaconLights = 'beaconLights';
FSXFunctionDisplayNameBeaconLights = 'Beacon lights';
FSXFunctionUIDNavLights = 'navLights';
FSXFunctionDisplayNameNavLights = 'Nav lights';
FSXFunctionUIDStrobeLights = 'strobeLights';
FSXFunctionDisplayNameStrobeLights = 'Strobe lights';
FSXFunctionUIDTaxiLights = 'taxiLights';
FSXFunctionDisplayNameTaxiLights = 'Taxi lights';
FSXFunctionUIDRecognitionLights = 'recognitionLights';
FSXFunctionDisplayNameRecognitionLights = 'Recognition lights';
implementation

View File

@ -2,20 +2,29 @@ unit FSXSimConnectClient;
interface
uses
Classes,
OtlTaskControl,
FSXSimConnectIntf;
type
TFSXSimConnectInterface = class(TInterfacedObject, IFSXSimConnect)
private
FClient: IOmniTaskControl;
FObservers: TInterfaceList;
protected
property Client: IOmniTaskControl read FClient;
property Observers: TInterfaceList read FObservers;
protected
{ IFSXSimConnect }
procedure Attach(AObserver: IFSXSimConnectObserver);
procedure Detach(AObserver: IFSXSimConnectObserver);
function CreateDefinition: IFSXSimConnectDefinition;
procedure AddDefinition(ADefinition: IFSXSimConnectDefinition);
procedure AddDefinition(ADefinition: IFSXSimConnectDefinition; ADataHandler: IFSXSimConnectDataHandler);
procedure RemoveDefinition(ADataHandler: IFSXSimConnectDataHandler);
public
constructor Create;
destructor Destroy; override;
@ -29,6 +38,11 @@ uses
SimConnect;
const
TM_ADDDEFINITION = 3001;
TM_REMOVEDEFINITION = 3002;
type
TFSXSimConnectClient = class(TOmniWorker)
end;
@ -58,11 +72,15 @@ var
begin
worker := TFSXSimConnectClient.Create;
FClient := CreateTask(worker);
FObservers := TInterfaceList.Create;
end;
destructor TFSXSimConnectInterface.Destroy;
begin
FreeAndNil(FObservers);
FClient.Terminate;
FClient := nil;
@ -70,15 +88,34 @@ begin
end;
procedure TFSXSimConnectInterface.Attach(AObserver: IFSXSimConnectObserver);
begin
Observers.Add(AObserver as IFSXSimConnectObserver);
end;
procedure TFSXSimConnectInterface.Detach(AObserver: IFSXSimConnectObserver);
begin
Observers.Remove(AObserver as IFSXSimConnectObserver);
end;
function TFSXSimConnectInterface.CreateDefinition: IFSXSimConnectDefinition;
begin
Result := TFSXSimConnectDefinition.Create(Self);
end;
procedure TFSXSimConnectInterface.AddDefinition(ADefinition: IFSXSimConnectDefinition);
procedure TFSXSimConnectInterface.AddDefinition(ADefinition: IFSXSimConnectDefinition; ADataHandler: IFSXSimConnectDataHandler);
begin
// TODO
Client.Comm.Send(TM_ADDDEFINITION, [ADefinition, ADataHandler]);
// TODO pass to thread; if definition already exists (same variables), link to existing definition to avoid too many SimConnect definition
end;
procedure TFSXSimConnectInterface.RemoveDefinition(ADataHandler: IFSXSimConnectDataHandler);
begin
Client.Comm.Send(TM_REMOVEDEFINITION, ADataHandler);
end;

View File

@ -6,13 +6,30 @@ uses
type
IFSXSimConnect = interface;
IFSXSimConnectDefinition = interface;
IFSXSimConnectObserver = interface
['{ACE8979A-D656-4F97-A332-A54BB615C4D1}']
procedure ObserveDestroy(Sender: IFSXSimConnect);
end;
IFSXSimConnectDataHandler = interface
['{29F00FB8-00AB-419F-83A3-A6AB3582599F}']
procedure HandleData(AData: Pointer);
end;
IFSXSimConnect = interface
['{B6BE3E7C-0804-43D6-84DE-8010C5728A07}']
procedure Attach(AObserver: IFSXSimConnectObserver);
procedure Detach(AObserver: IFSXSimConnectObserver);
function CreateDefinition: IFSXSimConnectDefinition;
procedure AddDefinition(ADefinition: IFSXSimConnectDefinition);
procedure AddDefinition(ADefinition: IFSXSimConnectDefinition; ADataHandler: IFSXSimConnectDataHandler);
procedure RemoveDefinition(ADataHandler: IFSXSimConnectDataHandler);
end;
@ -30,6 +47,16 @@ const
FSX_UNIT_BOOL = 'bool';
FSX_UNIT_NUMBER = 'number';
FSX_LIGHTON_NAV = $0001;
FSX_LIGHTON_BEACON = $0002;
FSX_LIGHTON_LANDING = $0004;
FSX_LIGHTON_TAXI = $0008;
FSX_LIGHTON_STROBE = $0010;
FSX_LIGHTON_PANEL = $0020;
FSX_LIGHTON_RECOGNITION = $0040;
FSX_LIGHTON_CABIN = $0200;
FSX_MAX_ENGINES = 4;
implementation

View File

@ -5,11 +5,14 @@ uses
Classes,
LEDFunctionIntf,
LEDStateIntf,
ObserverIntf;
LEDStateIntf;
type
TCustomLEDFunctionWorker = class;
TCustomLEDFunctionWorkerClass = class of TCustomLEDFunctionWorker;
TCustomLEDFunctionProvider = class(TInterfacedObject, ILEDFunctionProvider)
private
FFunctions: TInterfaceList;
@ -45,7 +48,12 @@ type
protected
procedure RegisterStates; virtual; abstract;
function RegisterState(AState: ILEDState): ILEDState; virtual;
function GetWorkerClass: TCustomLEDFunctionWorkerClass; virtual; abstract;
function DoCreateWorker(ASettings: ILEDFunctionWorkerSettings): TCustomLEDFunctionWorker; virtual;
protected
function CreateWorker(ASettings: ILEDFunctionWorkerSettings): ILEDFunctionWorker; override;
{ ILEDMultiStateFunction }
function GetEnumerator: ILEDStateEnumerator; virtual;
public
@ -67,9 +75,9 @@ type
property Observers: TInterfaceList read FObservers;
property States: TInterfaceList read FStates;
protected
{ IObservable }
procedure Attach(AObserver: IObserver); virtual;
procedure Detach(AObserver: IObserver); virtual;
{ ILEDFunctionWorker }
procedure Attach(AObserver: ILEDFunctionObserver); virtual;
procedure Detach(AObserver: ILEDFunctionObserver); virtual;
function GetCurrentState: ILEDStateWorker; virtual; abstract;
public
@ -147,6 +155,18 @@ begin
end;
function TCustomMultiStateLEDFunction.CreateWorker(ASettings: ILEDFunctionWorkerSettings): ILEDFunctionWorker;
begin
Result := DoCreateWorker(ASettings);
end;
function TCustomMultiStateLEDFunction.DoCreateWorker(ASettings: ILEDFunctionWorkerSettings): TCustomLEDFunctionWorker;
begin
Result := GetWorkerClass.Create(Self, ASettings);
end;
{ TCustomLEDFunctionWorker }
constructor TCustomLEDFunctionWorker.Create;
begin
@ -174,16 +194,16 @@ begin
end;
procedure TCustomLEDFunctionWorker.Attach(AObserver: IObserver);
procedure TCustomLEDFunctionWorker.Attach(AObserver: ILEDFunctionObserver);
begin
{ TInterfaceList is thread-safe }
Observers.Add(AObserver as IObserver);
Observers.Add(AObserver as ILEDFunctionObserver);
end;
procedure TCustomLEDFunctionWorker.Detach(AObserver: IObserver);
procedure TCustomLEDFunctionWorker.Detach(AObserver: ILEDFunctionObserver);
begin
Observers.Remove(AObserver as IObserver);
Observers.Remove(AObserver as ILEDFunctionObserver);
end;
@ -225,7 +245,7 @@ var
begin
for observer in Observers do
(observer as IObserver).Update(Self);
(observer as ILEDFunctionObserver).ObserveUpdate(Self);
end;

View File

@ -3,8 +3,7 @@ unit LEDFunctionIntf;
interface
uses
LEDColorIntf,
LEDStateIntf,
ObserverIntf;
LEDStateIntf;
type
@ -40,8 +39,17 @@ type
end;
ILEDFunctionWorker = interface(IObservable)
ILEDFunctionObserver = interface
['{B78415C9-9F64-4AF1-8983-BACE2B7225EF}']
procedure ObserveUpdate(Sender: ILEDFunctionWorker);
end;
ILEDFunctionWorker = interface
['{5EF3230D-B52F-4BD6-8AD3-F3A035F155B1}']
procedure Attach(AObserver: ILEDFunctionObserver);
procedure Detach(AObserver: ILEDFunctionObserver);
function GetCurrentState: ILEDStateWorker;
end;