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

Added: basic interfaces for refactoring

This commit is contained in:
Mark van Renswoude 2013-02-06 07:19:35 +00:00
parent 607cb3d52e
commit 688b859f66
13 changed files with 711 additions and 8 deletions

View File

@ -67,7 +67,6 @@ object ButtonSelectForm: TButtonSelectForm
Default = True Default = True
ModalResult = 1 ModalResult = 1
TabOrder = 1 TabOrder = 1
ExplicitTop = 94
end end
object btnCancel: TButton object btnCancel: TButton
Left = 401 Left = 401
@ -79,7 +78,6 @@ object ButtonSelectForm: TButtonSelectForm
Caption = 'Cancel' Caption = 'Cancel'
ModalResult = 2 ModalResult = 2
TabOrder = 2 TabOrder = 2
ExplicitTop = 94
end end
object edtButton: TEdit object edtButton: TEdit
Left = 80 Left = 80

View File

@ -116,7 +116,7 @@ begin
info.InstanceGUID := lpddi.guidInstance; info.InstanceGUID := lpddi.guidInstance;
info.ProductGUID := lpddi.guidProduct; info.ProductGUID := lpddi.guidProduct;
items.AddObject(String(lpddi.tszProductName), info); items.AddObject(string(lpddi.tszProductName), info);
Result := True; Result := True;
end; end;

View File

@ -275,10 +275,6 @@ object MainForm: TMainForm
Caption = 'Extra' Caption = 'Extra'
ImageIndex = 1 ImageIndex = 1
TabVisible = False TabVisible = False
ExplicitLeft = 0
ExplicitTop = 0
ExplicitWidth = 0
ExplicitHeight = 0
object GroupBox1: TGroupBox object GroupBox1: TGroupBox
AlignWithMargins = True AlignWithMargins = True
Left = 6 Left = 6

View File

@ -10,7 +10,15 @@ uses
G940LEDStateConsumer in 'Units\G940LEDStateConsumer.pas', G940LEDStateConsumer in 'Units\G940LEDStateConsumer.pas',
LEDFunctionMap in 'Units\LEDFunctionMap.pas', LEDFunctionMap in 'Units\LEDFunctionMap.pas',
LEDStateConsumer in 'Units\LEDStateConsumer.pas', LEDStateConsumer in 'Units\LEDStateConsumer.pas',
LEDStateProvider in 'Units\LEDStateProvider.pas'; LEDStateProvider in 'Units\LEDStateProvider.pas',
LEDStateIntf in 'Units\LEDStateIntf.pas',
LEDState in 'Units\LEDState.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',
LEDFunctionRegistry in 'Units\LEDFunctionRegistry.pas';
{$R *.res} {$R *.res}

View File

@ -173,6 +173,14 @@
<DCCReference Include="Units\LEDFunctionMap.pas"/> <DCCReference Include="Units\LEDFunctionMap.pas"/>
<DCCReference Include="Units\LEDStateConsumer.pas"/> <DCCReference Include="Units\LEDStateConsumer.pas"/>
<DCCReference Include="Units\LEDStateProvider.pas"/> <DCCReference Include="Units\LEDStateProvider.pas"/>
<DCCReference Include="Units\LEDStateIntf.pas"/>
<DCCReference Include="Units\LEDState.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"/>
<DCCReference Include="Units\LEDFunctionRegistry.pas"/>
<BuildConfiguration Include="Debug"> <BuildConfiguration Include="Debug">
<Key>Cfg_2</Key> <Key>Cfg_2</Key>
<CfgParent>Base</CfgParent> <CfgParent>Base</CfgParent>

View File

@ -0,0 +1,57 @@
unit ConfigConversion;
interface
{ Version 0.x: registry -> 1.x: XML }
procedure Convert0To1;
implementation
procedure Convert0To1;
begin
// FUNCTION_NONE = 0;
// FUNCTION_OFF = 1;
// FUNCTION_RED = 2;
// FUNCTION_AMBER = 3;
// FUNCTION_GREEN = 4;
{
FUNCTION_PROVIDER_OFFSET = 4
FUNCTION_FSX_GEAR = FUNCTION_PROVIDER_OFFSET + 1;
FUNCTION_FSX_LANDINGLIGHTS = FUNCTION_PROVIDER_OFFSET + 2;
FUNCTION_FSX_INSTRUMENTLIGHTS = FUNCTION_PROVIDER_OFFSET + 3;
FUNCTION_FSX_PARKINGBRAKE = FUNCTION_PROVIDER_OFFSET + 4;
FUNCTION_FSX_ENGINE = FUNCTION_PROVIDER_OFFSET + 5;
FUNCTION_FSX_EXITDOOR = FUNCTION_PROVIDER_OFFSET + 6;
FUNCTION_FSX_STROBELIGHTS = FUNCTION_PROVIDER_OFFSET + 7;
FUNCTION_FSX_NAVLIGHTS = FUNCTION_PROVIDER_OFFSET + 8;
FUNCTION_FSX_BEACONLIGHTS = FUNCTION_PROVIDER_OFFSET + 9;
FUNCTION_FSX_FLAPS = FUNCTION_PROVIDER_OFFSET + 10;
FUNCTION_FSX_BATTERYMASTER = FUNCTION_PROVIDER_OFFSET + 11;
FUNCTION_FSX_AVIONICSMASTER = FUNCTION_PROVIDER_OFFSET + 12;
FUNCTION_FSX_SPOILERS = FUNCTION_PROVIDER_OFFSET + 13;
FUNCTION_FSX_PRESSURIZATIONDUMPSWITCH = FUNCTION_PROVIDER_OFFSET + 14;
FUNCTION_FSX_CARBHEAT = FUNCTION_PROVIDER_OFFSET + 15;
FUNCTION_FSX_AUTOPILOT = FUNCTION_PROVIDER_OFFSET + 16;
FUNCTION_FSX_FUELPUMP = FUNCTION_PROVIDER_OFFSET + 17;
FUNCTION_FSX_TAILHOOK = FUNCTION_PROVIDER_OFFSET + 18;
FUNCTION_FSX_AUTOPILOT_AMBER = FUNCTION_PROVIDER_OFFSET + 19;
FUNCTION_FSX_AUTOPILOT_HEADING = FUNCTION_PROVIDER_OFFSET + 20;
FUNCTION_FSX_AUTOPILOT_APPROACH = FUNCTION_PROVIDER_OFFSET + 21;
FUNCTION_FSX_AUTOPILOT_BACKCOURSE = FUNCTION_PROVIDER_OFFSET + 22;
FUNCTION_FSX_AUTOPILOT_ALTITUDE = FUNCTION_PROVIDER_OFFSET + 23;
FUNCTION_FSX_AUTOPILOT_NAV = FUNCTION_PROVIDER_OFFSET + 24;
FUNCTION_FSX_TAXILIGHTS = FUNCTION_PROVIDER_OFFSET + 25;
FUNCTION_FSX_RECOGNITIONLIGHTS = FUNCTION_PROVIDER_OFFSET + 26;
}
end;
end.

View File

@ -0,0 +1,181 @@
unit LEDFunction;
interface
uses
Classes,
LEDFunctionIntf,
LEDStateIntf,
ObserverIntf;
type
TCustomLEDFunctionProvider = class(TInterfacedObject, ILEDFunctionProvider)
private
FFunctions: TInterfaceList;
protected
procedure RegisterFunction(AFunction: ILEDFunction);
protected
{ ILEDFunctionProvider }
function GetUniqueName: string; virtual; abstract;
function GetEnumerator: ILEDFunctionEnumerator; virtual;
public
constructor Create;
destructor Destroy; override;
end;
TCustomLEDFunction = class(TInterfacedObject, IObservable, ILEDFunction)
private
FCurrentState: ILEDState;
FObservers: TInterfaceList;
protected
procedure SetCurrentState(AState: ILEDState); virtual;
procedure NotifyObservers; virtual;
property Observers: TInterfaceList read FObservers;
protected
{ IObservable }
procedure Attach(AObserver: IObserver);
procedure Detach(AObserver: IObserver);
{ ILEDFunction }
function GetCategoryName: string; virtual; abstract;
function GetDisplayName: string; virtual; abstract;
function GetUniqueName: string; virtual; abstract;
function GetCurrentState: ILEDState; virtual;
public
constructor Create;
destructor Destroy; override;
end;
TLEDFunctionEnumerator = class(TInterfacedObject, ILEDFunctionEnumerator)
private
FList: TInterfaceList;
FIndex: Integer;
protected
{ ILEDFunctionEnumerator }
function GetCurrent: ILEDFunction; virtual;
function MoveNext: Boolean; virtual;
public
constructor Create(AList: TInterfaceList);
end;
implementation
uses
SysUtils;
{ TCustomLEDFunction }
constructor TCustomLEDFunction.Create;
begin
inherited Create;
FObservers := TInterfaceList.Create;
end;
destructor TCustomLEDFunction.Destroy;
begin
FreeAndNil(FObservers);
inherited Destroy;
end;
procedure TCustomLEDFunction.Attach(AObserver: IObserver);
begin
end;
procedure TCustomLEDFunction.Detach(AObserver: IObserver);
begin
end;
function TCustomLEDFunction.GetCurrentState: ILEDState;
begin
end;
procedure TCustomLEDFunction.SetCurrentState(AState: ILEDState);
begin
FCurrentState := AState;
NotifyObservers;
end;
procedure TCustomLEDFunction.NotifyObservers;
var
observer: IInterface;
begin
for observer in Observers do
(observer as IObserver).Update(Self);
end;
{ TCustomLEDFunctionProvider }
constructor TCustomLEDFunctionProvider.Create;
begin
inherited Create;
FFunctions := TInterfaceList.Create;
end;
destructor TCustomLEDFunctionProvider.Destroy;
begin
FreeAndNil(FFunctions);
inherited;
end;
procedure TCustomLEDFunctionProvider.RegisterFunction(AFunction: ILEDFunction);
begin
{ Make sure to explicitly request the ILEDFunction interface; I've experienced
incomparable pointers otherwise if we ever need to write an UnregisterFunction.
My best, but unverified, guess is that it works kinda like a VMT. }
FFunctions.Add(AFunction as ILEDFunction);
end;
function TCustomLEDFunctionProvider.GetEnumerator: ILEDFunctionEnumerator;
begin
Result := TLEDFunctionEnumerator.Create(FFunctions);
end;
{ TLEDFunctionEnumerator }
constructor TLEDFunctionEnumerator.Create(AList: TInterfaceList);
begin
inherited Create;
FList := AList;
FIndex := -1;
end;
function TLEDFunctionEnumerator.GetCurrent: ILEDFunction;
begin
Result := (FList[FIndex] as ILEDFunction);
end;
function TLEDFunctionEnumerator.MoveNext: Boolean;
begin
Result := (FIndex < Pred(FList.Count));
if Result then
Inc(FIndex);
end;
end.

View File

@ -0,0 +1,43 @@
unit LEDFunctionIntf;
interface
uses
LEDStateIntf,
ObserverIntf;
type
ILEDFunction = interface;
ILEDFunctionEnumerator = interface;
ILEDFunctionProvider = interface
['{B38F6F90-DC96-42CE-B8F0-21F0DD8AA537}']
function GetUniqueName: string;
function GetEnumerator: ILEDFunctionEnumerator;
end;
ILEDFunction = interface(IObservable)
['{7087067A-1016-4A7D-ACB1-BA1F388DAD6C}']
function GetCategoryName: string;
function GetDisplayName: string;
function GetUniqueName: string;
function GetCurrentState: ILEDState;
end;
ILEDFunctionEnumerator = interface
['{A03E4E54-19CB-4C08-AD5F-20265817086D}']
function GetCurrent: ILEDFunction;
function MoveNext: Boolean;
property Current: ILEDFunction read GetCurrent;
end;
implementation
end.

View File

@ -0,0 +1,216 @@
unit LEDFunctionRegistry;
interface
uses
Classes,
LEDFunctionIntf;
type
TLEDFunctionProviderList = class;
TLEDFunctionRegistry = class(TObject)
private
FProviders: TLEDFunctionProviderList;
protected
class function Instance: TLEDFunctionRegistry;
procedure DoRegister(AProvider: ILEDFunctionProvider);
procedure DoUnregister(AProvider: ILEDFunctionProvider);
function DoFind(const AUniqueName: string): ILEDFunctionProvider;
function GetProviders: TLEDFunctionProviderList;
public
constructor Create;
destructor Destroy; override;
class procedure Register(AProvider: ILEDFunctionProvider);
class procedure Unregister(AProvider: ILEDFunctionProvider);
class function Find(const AUniqueName: string): ILEDFunctionProvider;
class function Providers: TLEDFunctionProviderList;
end;
TLEDFunctionProviderListEnumerator = class;
TLEDFunctionProviderList = class(TObject)
private
FList: TInterfaceList;
protected
procedure Add(AProvider: ILEDFunctionProvider);
procedure Remove(AProvider: ILEDFunctionProvider);
public
constructor Create;
destructor Destroy; override;
function Find(const AUniqueName: string): ILEDFunctionProvider;
function GetEnumerator: TLEDFunctionProviderListEnumerator;
end;
TLEDFunctionProviderListEnumerator = class(TInterfaceListEnumerator)
public
function GetCurrent: ILEDFunctionProvider; inline;
property Current: ILEDFunctionProvider read GetCurrent;
end;
implementation
uses
SysUtils;
var
RegistryInstance: TLEDFunctionRegistry;
{ TLEDFunctionRegistry }
class procedure TLEDFunctionRegistry.Register(AProvider: ILEDFunctionProvider);
begin
Instance.DoRegister(AProvider);
end;
class procedure TLEDFunctionRegistry.Unregister(AProvider: ILEDFunctionProvider);
begin
Instance.DoUnregister(AProvider);
end;
class function TLEDFunctionRegistry.Find(const AUniqueName: string): ILEDFunctionProvider;
begin
Result := Instance.DoFind(AUniqueName);
end;
class function TLEDFunctionRegistry.Providers: TLEDFunctionProviderList;
begin
Result := Instance.GetProviders;
end;
class function TLEDFunctionRegistry.Instance: TLEDFunctionRegistry;
begin
if not Assigned(RegistryInstance) then
RegistryInstance := TLEDFunctionRegistry.Create;
Result := RegistryInstance;
end;
constructor TLEDFunctionRegistry.Create;
begin
inherited Create;
FProviders := TLEDFunctionProviderList.Create;
end;
destructor TLEDFunctionRegistry.Destroy;
begin
FreeAndNil(FProviders);
inherited;
end;
procedure TLEDFunctionRegistry.DoRegister(AProvider: ILEDFunctionProvider);
begin
FProviders.Add(AProvider);
end;
procedure TLEDFunctionRegistry.DoUnregister(AProvider: ILEDFunctionProvider);
begin
FProviders.Remove(AProvider);
end;
function TLEDFunctionRegistry.DoFind(const AUniqueName: string): ILEDFunctionProvider;
begin
Result := FProviders.Find(AUniqueName);
end;
function TLEDFunctionRegistry.GetProviders: TLEDFunctionProviderList;
begin
Result := FProviders;
end;
{ TLEDFunctionProviderList }
constructor TLEDFunctionProviderList.Create;
begin
inherited Create;
FList := TInterfaceList.Create;
end;
destructor TLEDFunctionProviderList.Destroy;
begin
FreeAndNil(FList);
inherited;
end;
function TLEDFunctionProviderList.Find(const AUniqueName: string): ILEDFunctionProvider;
var
provider: ILEDFunctionProvider;
begin
Result := nil;
for provider in Self do
if provider.GetUniqueName = AUniqueName then
begin
Result := provider;
break;
end;
end;
procedure TLEDFunctionProviderList.Add(AProvider: ILEDFunctionProvider);
var
stableReference: ILEDFunctionProvider;
begin
stableReference := (AProvider as ILEDFunctionProvider);
if FList.IndexOf(stableReference) = -1 then
FList.Add(stableReference);
end;
procedure TLEDFunctionProviderList.Remove(AProvider: ILEDFunctionProvider);
var
index: Integer;
begin
index := FList.IndexOf(AProvider as ILEDFunctionProvider);
if index > -1 then
FList.Delete(index);
end;
function TLEDFunctionProviderList.GetEnumerator: TLEDFunctionProviderListEnumerator;
begin
Result := TLEDFunctionProviderListEnumerator.Create(FList);
end;
{ TLEDFunctionProviderListEnumerator }
function TLEDFunctionProviderListEnumerator.GetCurrent: ILEDFunctionProvider;
begin
Result := ((inherited GetCurrent) as ILEDFunctionProvider);
end;
initialization
finalization
FreeAndNil(RegistryInstance);
end.

View File

@ -0,0 +1,52 @@
unit LEDState;
interface
uses
SysUtils,
LEDStateIntf;
type
TCustomLEDState = class(TInterfacedObject, ILEDState)
protected
{ ILEDState }
procedure Tick; virtual;
function GetColor: TLEDColor; virtual; abstract;
end;
TStaticLEDState = class(TCustomLEDState)
private
FColor: TLEDColor;
protected
function GetColor: TLEDColor; override;
public
constructor Create(AColor: TLEDColor);
end;
implementation
{ TCustomLEDState }
procedure TCustomLEDState.Tick;
begin
end;
{ TStaticLEDState }
constructor TStaticLEDState.Create(AColor: TLEDColor);
begin
inherited Create;
FColor := AColor;
end;
function TStaticLEDState.GetColor: TLEDColor;
begin
Result := FColor;
end;
end.

View File

@ -0,0 +1,17 @@
unit LEDStateIntf;
interface
type
TLEDColor = (lcOff, lcGreen, lcAmber, lcRed);
ILEDState = interface
['{B40DF462-B660-4002-A6B9-DD30AC69E8DB}']
procedure Tick;
function GetColor: TLEDColor;
end;
implementation
end.

View File

@ -0,0 +1,20 @@
unit ObserverIntf;
interface
type
IObserver = interface
['{B78415C9-9F64-4AF1-8983-BACE2B7225EF}']
procedure Update(Sender: IInterface);
end;
IObservable = interface
['{BC004BDA-14E4-4923-BE6D-98A0746852F1}']
procedure Attach(AObserver: IObserver);
procedure Detach(AObserver: IObserver);
end;
implementation
end.

View File

@ -0,0 +1,107 @@
unit StaticLEDFunction;
interface
uses
LEDFunction,
LEDStateIntf;
type
TStaticLEDFunctionProvider = class(TCustomLEDFunctionProvider)
protected
function GetUniqueName: string; override;
public
constructor Create;
end;
TStaticLEDFunction = class(TCustomLEDFunction)
private
FColor: TLEDColor;
protected
function GetCategoryName: string; override;
function GetDisplayName: string; override;
function GetUniqueName: string; override;
public
constructor Create(AColor: TLEDColor);
end;
implementation
uses
LEDFunctionRegistry;
const
CategoryStatic = 'Static';
ProviderUniqueName = 'static';
FunctionUniqueName: array[TLEDColor] of string =
(
'off',
'green',
'amber',
'red'
);
FunctionDisplayName: array[TLEDColor] of string =
(
'Off',
'Green',
'Amber',
'Red'
);
{ TStaticLEDFunctionProvider }
constructor TStaticLEDFunctionProvider.Create;
var
color: TLEDColor;
begin
inherited Create;
for color := Low(TLEDColor) to High(TLEDColor) do
RegisterFunction(TStaticLEDFunction.Create(color));
end;
function TStaticLEDFunctionProvider.GetUniqueName: string;
begin
Result := ProviderUniqueName;
end;
{ TStaticLEDFunction }
constructor TStaticLEDFunction.Create(AColor: TLEDColor);
begin
inherited Create;
FColor := AColor;
end;
function TStaticLEDFunction.GetCategoryName: string;
begin
Result := CategoryStatic;
end;
function TStaticLEDFunction.GetDisplayName: string;
begin
Result := FunctionDisplayName[FColor];
end;
function TStaticLEDFunction.GetUniqueName: string;
begin
Result := FunctionUniqueName[FColor];
end;
initialization
TLEDFunctionRegistry.Register(TStaticLEDFunctionProvider.Create);
end.