Refactored to single task
This commit is contained in:
parent
3b34cdef39
commit
caec794f3b
@ -15,7 +15,9 @@ uses
|
|||||||
OtlTaskControl,
|
OtlTaskControl,
|
||||||
pngimage,
|
pngimage,
|
||||||
|
|
||||||
CustomLEDStateProvider;
|
LEDFunctionMap,
|
||||||
|
LEDStateConsumer,
|
||||||
|
LEDStateProvider;
|
||||||
|
|
||||||
|
|
||||||
type
|
type
|
||||||
@ -59,10 +61,7 @@ type
|
|||||||
// procedure tmrG940InitTimer(Sender: TObject);
|
// procedure tmrG940InitTimer(Sender: TObject);
|
||||||
private
|
private
|
||||||
FEventMonitor: TOmniEventMonitor;
|
FEventMonitor: TOmniEventMonitor;
|
||||||
FProviderConsumerChannel: IOmniTwoWayChannel;
|
|
||||||
FStateConsumerTask: IOmniTaskControl;
|
FStateConsumerTask: IOmniTaskControl;
|
||||||
FStateProviderWorker: IOmniWorker;
|
|
||||||
FStateProviderTask: IOmniTaskControl;
|
|
||||||
|
|
||||||
// FInitCounter: Integer;
|
// FInitCounter: Integer;
|
||||||
// FInitRedState: Byte;
|
// FInitRedState: Byte;
|
||||||
@ -70,20 +69,17 @@ type
|
|||||||
protected
|
protected
|
||||||
procedure SetDeviceState(const AMessage: string; AFound: Boolean);
|
procedure SetDeviceState(const AMessage: string; AFound: Boolean);
|
||||||
|
|
||||||
procedure InitializeStateProvider(AProviderClass: TCustomLEDStateProviderClass);
|
procedure InitializeStateProvider(AProviderClass: TLEDStateProviderClass);
|
||||||
procedure FinalizeStateProvider;
|
procedure FinalizeStateProvider;
|
||||||
|
|
||||||
procedure UpdateMapping;
|
procedure UpdateMapping;
|
||||||
procedure UpdateMappingFSX(AFunctionMap: TLEDFunctionMap);
|
procedure UpdateMappingFSX;
|
||||||
|
|
||||||
procedure EventMonitorMessage(const task: IOmniTaskControl; const msg: TOmniMessage);
|
procedure EventMonitorMessage(const task: IOmniTaskControl; const msg: TOmniMessage);
|
||||||
procedure HandleDeviceStateMessage(ATask: IOmniTaskControl; AMessage: TOmniMessage);
|
procedure HandleDeviceStateMessage(ATask: IOmniTaskControl; AMessage: TOmniMessage);
|
||||||
|
|
||||||
property EventMonitor: TOmniEventMonitor read FEventMonitor;
|
property EventMonitor: TOmniEventMonitor read FEventMonitor;
|
||||||
property ProviderConsumerChannel: IOmniTwoWayChannel read FProviderConsumerChannel;
|
|
||||||
property StateConsumerTask: IOmniTaskControl read FStateConsumerTask;
|
property StateConsumerTask: IOmniTaskControl read FStateConsumerTask;
|
||||||
property StateProviderWorker: IOmniWorker read FStateProviderWorker;
|
|
||||||
property StateProviderTask: IOmniTaskControl read FStateProviderTask;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -96,7 +92,7 @@ uses
|
|||||||
OtlTask,
|
OtlTask,
|
||||||
|
|
||||||
FSXLEDStateProvider,
|
FSXLEDStateProvider,
|
||||||
LEDStateConsumer;
|
G940LEDStateConsumer;
|
||||||
|
|
||||||
|
|
||||||
{$R *.dfm}
|
{$R *.dfm}
|
||||||
@ -122,10 +118,9 @@ var
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
FEventMonitor := TOmniEventMonitor.Create(Self);
|
FEventMonitor := TOmniEventMonitor.Create(Self);
|
||||||
FProviderConsumerChannel := CreateTwoWayChannel(1024);
|
|
||||||
|
|
||||||
consumer := TG940LEDStateConsumer.Create(ProviderConsumerChannel.Endpoint1);
|
consumer := TG940LEDStateConsumer.Create;
|
||||||
FStateConsumerTask := FEventMonitor.Monitor(CreateTask(consumer));
|
FStateConsumerTask := FEventMonitor.Monitor(CreateTask(consumer)).MsgWait;
|
||||||
|
|
||||||
// ToDo handle OnTerminate, check exit code for initialization errors
|
// ToDo handle OnTerminate, check exit code for initialization errors
|
||||||
EventMonitor.OnTaskMessage := EventMonitorMessage;
|
EventMonitor.OnTaskMessage := EventMonitorMessage;
|
||||||
@ -201,55 +196,32 @@ end;
|
|||||||
*)
|
*)
|
||||||
|
|
||||||
|
|
||||||
procedure TMainForm.InitializeStateProvider(AProviderClass: TCustomLEDStateProviderClass);
|
procedure TMainForm.InitializeStateProvider(AProviderClass: TLEDStateProviderClass);
|
||||||
begin
|
begin
|
||||||
if Assigned(StateProviderTask) then
|
|
||||||
FinalizeStateProvider;
|
|
||||||
|
|
||||||
FStateProviderWorker := AProviderClass.Create(ProviderConsumerChannel.Endpoint2);
|
|
||||||
FStateProviderTask := CreateTask(StateProviderWorker);
|
|
||||||
|
|
||||||
StateProviderTask.Run;
|
|
||||||
StateProviderTask.WaitForInit;
|
|
||||||
|
|
||||||
UpdateMapping;
|
UpdateMapping;
|
||||||
|
TLEDStateConsumer.InitializeStateProvider(StateConsumerTask, AProviderClass);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TMainForm.FinalizeStateProvider;
|
procedure TMainForm.FinalizeStateProvider;
|
||||||
begin
|
begin
|
||||||
FStateProviderWorker := nil;
|
TLEDStateConsumer.FinalizeStateProvider(StateConsumerTask);
|
||||||
|
|
||||||
if Assigned(StateProviderTask) then
|
|
||||||
StateProviderTask.Terminate;
|
|
||||||
|
|
||||||
FStateProviderTask := nil;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TMainForm.UpdateMapping;
|
procedure TMainForm.UpdateMapping;
|
||||||
var
|
|
||||||
provider: TCustomLEDStateProvider;
|
|
||||||
functionMap: TLEDFunctionMap;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if not Assigned(StateProviderWorker) then
|
if not Assigned(StateConsumerTask) then
|
||||||
Exit;
|
Exit;
|
||||||
|
|
||||||
provider := (StateProviderWorker.Implementor as TCustomLEDStateProvider);
|
TLEDStateConsumer.ClearFunctions(StateConsumerTask);
|
||||||
functionMap := provider.LockFunctionMap;
|
UpdateMappingFSX;
|
||||||
try
|
|
||||||
UpdateMappingFSX(functionMap);
|
|
||||||
finally
|
|
||||||
provider.UnlockFunctionMap;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TMainForm.UpdateMappingFSX(AFunctionMap: TLEDFunctionMap);
|
procedure TMainForm.UpdateMappingFSX;
|
||||||
begin
|
begin
|
||||||
AFunctionMap.Clear;
|
TLEDStateConsumer.SetFunction(StateConsumerTask, 3, FUNCTION_FSX_GEAR);
|
||||||
AFunctionMap.SetFunction(4, FUNCTION_FSX_GEAR);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -279,24 +251,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
(*
|
|
||||||
procedure TMainForm.DoStateChange(Sender: TObject; ALEDPosition: Integer; AState: TLEDState);
|
|
||||||
begin
|
|
||||||
if not Assigned(ThrottleDevice) then
|
|
||||||
exit;
|
|
||||||
|
|
||||||
// (MvR) 2-1-2012: dit moet slimmer zodra we lsWarning/lsError willen ondersteunen
|
|
||||||
|
|
||||||
case AState of
|
|
||||||
lsOff: SetButtonColor(ThrottleDevice, TLogiPanelButton(Pred(ALEDPosition)), LOGI_OFF);
|
|
||||||
lsGreen: SetButtonColor(ThrottleDevice, TLogiPanelButton(Pred(ALEDPosition)), LOGI_GREEN);
|
|
||||||
lsAmber: SetButtonColor(ThrottleDevice, TLogiPanelButton(Pred(ALEDPosition)), LOGI_AMBER);
|
|
||||||
lsRed: SetButtonColor(ThrottleDevice, TLogiPanelButton(Pred(ALEDPosition)), LOGI_RED);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
*)
|
|
||||||
|
|
||||||
|
|
||||||
procedure TMainForm.btnFSXConnectClick(Sender: TObject);
|
procedure TMainForm.btnFSXConnectClick(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
InitializeStateProvider(TFSXLEDStateProvider);
|
InitializeStateProvider(TFSXLEDStateProvider);
|
||||||
|
@ -3,9 +3,11 @@ program G940LEDControl;
|
|||||||
uses
|
uses
|
||||||
Forms,
|
Forms,
|
||||||
MainFrm in 'Forms\MainFrm.pas' {MainForm},
|
MainFrm in 'Forms\MainFrm.pas' {MainForm},
|
||||||
CustomLEDStateProvider in 'Units\CustomLEDStateProvider.pas',
|
|
||||||
FSXLEDStateProvider in 'Units\FSXLEDStateProvider.pas',
|
FSXLEDStateProvider in 'Units\FSXLEDStateProvider.pas',
|
||||||
LEDStateConsumer in 'Units\LEDStateConsumer.pas';
|
LEDStateConsumer in 'Units\LEDStateConsumer.pas',
|
||||||
|
LEDStateProvider in 'Units\LEDStateProvider.pas',
|
||||||
|
LEDFunctionMap in 'Units\LEDFunctionMap.pas',
|
||||||
|
G940LEDStateConsumer in 'Units\G940LEDStateConsumer.pas';
|
||||||
|
|
||||||
{$R *.res}
|
{$R *.res}
|
||||||
|
|
||||||
|
@ -33,106 +33,7 @@
|
|||||||
<Borland.Personality>Delphi.Personality</Borland.Personality>
|
<Borland.Personality>Delphi.Personality</Borland.Personality>
|
||||||
<Borland.ProjectType />
|
<Borland.ProjectType />
|
||||||
<BorlandProject>
|
<BorlandProject>
|
||||||
<BorlandProject><Delphi.Personality><Parameters><Parameters Name="UseLauncher">False</Parameters><Parameters Name="LoadAllSymbols">True</Parameters><Parameters Name="LoadUnspecifiedSymbols">False</Parameters></Parameters><VersionInfo><VersionInfo Name="IncludeVerInfo">False</VersionInfo><VersionInfo Name="AutoIncBuild">False</VersionInfo><VersionInfo Name="MajorVer">1</VersionInfo><VersionInfo Name="MinorVer">0</VersionInfo><VersionInfo Name="Release">0</VersionInfo><VersionInfo Name="Build">0</VersionInfo><VersionInfo Name="Debug">False</VersionInfo><VersionInfo Name="PreRelease">False</VersionInfo><VersionInfo Name="Special">False</VersionInfo><VersionInfo Name="Private">False</VersionInfo><VersionInfo Name="DLL">False</VersionInfo><VersionInfo Name="Locale">1043</VersionInfo><VersionInfo Name="CodePage">1252</VersionInfo></VersionInfo><VersionInfoKeys><VersionInfoKeys Name="CompanyName"></VersionInfoKeys><VersionInfoKeys Name="FileDescription"></VersionInfoKeys><VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys><VersionInfoKeys Name="InternalName"></VersionInfoKeys><VersionInfoKeys Name="LegalCopyright"></VersionInfoKeys><VersionInfoKeys Name="LegalTrademarks"></VersionInfoKeys><VersionInfoKeys Name="OriginalFilename"></VersionInfoKeys><VersionInfoKeys Name="ProductName"></VersionInfoKeys><VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys><VersionInfoKeys Name="Comments"></VersionInfoKeys></VersionInfoKeys><Source><Source Name="MainSource">G940LEDControl.dpr</Source></Source> <Excluded_Packages>
|
<BorlandProject><Delphi.Personality><Parameters><Parameters Name="UseLauncher">False</Parameters><Parameters Name="LoadAllSymbols">True</Parameters><Parameters Name="LoadUnspecifiedSymbols">False</Parameters></Parameters><VersionInfo><VersionInfo Name="IncludeVerInfo">False</VersionInfo><VersionInfo Name="AutoIncBuild">False</VersionInfo><VersionInfo Name="MajorVer">1</VersionInfo><VersionInfo Name="MinorVer">0</VersionInfo><VersionInfo Name="Release">0</VersionInfo><VersionInfo Name="Build">0</VersionInfo><VersionInfo Name="Debug">False</VersionInfo><VersionInfo Name="PreRelease">False</VersionInfo><VersionInfo Name="Special">False</VersionInfo><VersionInfo Name="Private">False</VersionInfo><VersionInfo Name="DLL">False</VersionInfo><VersionInfo Name="Locale">1043</VersionInfo><VersionInfo Name="CodePage">1252</VersionInfo></VersionInfo><VersionInfoKeys><VersionInfoKeys Name="CompanyName"></VersionInfoKeys><VersionInfoKeys Name="FileDescription"></VersionInfoKeys><VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys><VersionInfoKeys Name="InternalName"></VersionInfoKeys><VersionInfoKeys Name="LegalCopyright"></VersionInfoKeys><VersionInfoKeys Name="LegalTrademarks"></VersionInfoKeys><VersionInfoKeys Name="OriginalFilename"></VersionInfoKeys><VersionInfoKeys Name="ProductName"></VersionInfoKeys><VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys><VersionInfoKeys Name="Comments"></VersionInfoKeys></VersionInfoKeys><Source><Source Name="MainSource">G940LEDControl.dpr</Source></Source><Excluded_Packages>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -508,8 +409,7 @@
|
|||||||
<Excluded_Packages Name="P:\algemeen\bin\D2007\wpViewPDF_D2007.bpl">WPViewPDF - PDFViewClass</Excluded_Packages>
|
<Excluded_Packages Name="P:\algemeen\bin\D2007\wpViewPDF_D2007.bpl">WPViewPDF - PDFViewClass</Excluded_Packages>
|
||||||
<Excluded_Packages Name="P:\algemeen\bin\D2007\madExceptVcl_.bpl">madExceptVcl 2.0c - www.madshi.net</Excluded_Packages>
|
<Excluded_Packages Name="P:\algemeen\bin\D2007\madExceptVcl_.bpl">madExceptVcl 2.0c - www.madshi.net</Excluded_Packages>
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi11\dclcxPivotGridOLAPD11.bpl">ExpressPivotGrid 2 OLAP by Developer Express Inc.</Excluded_Packages>
|
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi11\dclcxPivotGridOLAPD11.bpl">ExpressPivotGrid 2 OLAP by Developer Express Inc.</Excluded_Packages>
|
||||||
</Excluded_Packages>
|
</Excluded_Packages></Delphi.Personality></BorlandProject></BorlandProject>
|
||||||
</Delphi.Personality></BorlandProject></BorlandProject>
|
|
||||||
</ProjectExtensions>
|
</ProjectExtensions>
|
||||||
<Import Project="$(MSBuildBinPath)\Borland.Delphi.Targets" />
|
<Import Project="$(MSBuildBinPath)\Borland.Delphi.Targets" />
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@ -519,8 +419,10 @@
|
|||||||
<DCCReference Include="Forms\MainFrm.pas">
|
<DCCReference Include="Forms\MainFrm.pas">
|
||||||
<Form>MainForm</Form>
|
<Form>MainForm</Form>
|
||||||
</DCCReference>
|
</DCCReference>
|
||||||
<DCCReference Include="Units\CustomLEDStateProvider.pas" />
|
|
||||||
<DCCReference Include="Units\FSXLEDStateProvider.pas" />
|
<DCCReference Include="Units\FSXLEDStateProvider.pas" />
|
||||||
|
<DCCReference Include="Units\G940LEDStateConsumer.pas" />
|
||||||
|
<DCCReference Include="Units\LEDFunctionMap.pas" />
|
||||||
<DCCReference Include="Units\LEDStateConsumer.pas" />
|
<DCCReference Include="Units\LEDStateConsumer.pas" />
|
||||||
|
<DCCReference Include="Units\LEDStateProvider.pas" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -1,158 +0,0 @@
|
|||||||
unit CustomLEDStateProvider;
|
|
||||||
|
|
||||||
interface
|
|
||||||
uses
|
|
||||||
Classes,
|
|
||||||
SyncObjs,
|
|
||||||
|
|
||||||
OtlComm,
|
|
||||||
OtlTaskControl;
|
|
||||||
|
|
||||||
const
|
|
||||||
MAX_LEDS = 8;
|
|
||||||
FUNCTION_NONE = 0;
|
|
||||||
|
|
||||||
|
|
||||||
MSG_EXECUTE = 10;
|
|
||||||
MSG_UPDATEFUNCTIONMAP = 11;
|
|
||||||
MSG_SETSTATEBYFUNCTION = 12;
|
|
||||||
|
|
||||||
|
|
||||||
type
|
|
||||||
TLEDState = (lsOff, lsGreen, lsAmber, lsRed, lsWarning, lsError);
|
|
||||||
|
|
||||||
|
|
||||||
// todo implement assign
|
|
||||||
TLEDFunctionMap = class(TPersistent)
|
|
||||||
private
|
|
||||||
FFunctions: array[0..MAX_LEDS - 1] of Integer;
|
|
||||||
|
|
||||||
function GetCount: Integer;
|
|
||||||
public
|
|
||||||
procedure Clear;
|
|
||||||
|
|
||||||
procedure SetFunction(ALEDIndex, AFunction: Integer);
|
|
||||||
function GetFunction(ALEDIndex: Integer): Integer;
|
|
||||||
|
|
||||||
property Count: Integer read GetCount;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
TCustomLEDStateProvider = class(TOmniWorker)
|
|
||||||
private
|
|
||||||
FConsumerChannel: IOmniCommunicationEndpoint;
|
|
||||||
FFunctionMap: TLEDFunctionMap;
|
|
||||||
FFunctionMapLock: TCriticalSection;
|
|
||||||
FState: array[0..MAX_LEDS - 1] of TLEDState;
|
|
||||||
protected
|
|
||||||
procedure MsgExecute(var msg: TOmniMessage); message MSG_EXECUTE;
|
|
||||||
protected
|
|
||||||
function Initialize: Boolean; override;
|
|
||||||
procedure Execute; virtual; abstract;
|
|
||||||
|
|
||||||
procedure SetStateByFunction(AFunction: Integer; AState: TLEDState);
|
|
||||||
|
|
||||||
property ConsumerChannel: IOmniCommunicationEndpoint read FConsumerChannel;
|
|
||||||
public
|
|
||||||
constructor Create(AConsumerChannel: IOmniCommunicationEndpoint);
|
|
||||||
destructor Destroy; override;
|
|
||||||
|
|
||||||
function LockFunctionMap: TLEDFunctionMap;
|
|
||||||
procedure UnlockFunctionMap;
|
|
||||||
end;
|
|
||||||
|
|
||||||
TCustomLEDStateProviderClass = class of TCustomLEDStateProvider;
|
|
||||||
|
|
||||||
|
|
||||||
implementation
|
|
||||||
uses
|
|
||||||
SysUtils;
|
|
||||||
|
|
||||||
|
|
||||||
{ TCustomLEDStateProvider }
|
|
||||||
constructor TCustomLEDStateProvider.Create(AConsumerChannel: IOmniCommunicationEndpoint);
|
|
||||||
var
|
|
||||||
ledIndex: Integer;
|
|
||||||
|
|
||||||
begin
|
|
||||||
inherited Create;
|
|
||||||
|
|
||||||
FConsumerChannel := AConsumerChannel;
|
|
||||||
|
|
||||||
FFunctionMap := TLEDFunctionMap.Create;
|
|
||||||
FFunctionMapLock := TCriticalSection.Create;
|
|
||||||
|
|
||||||
for ledIndex := Low(FState) to High(FState) do
|
|
||||||
FState[ledIndex] := lsGreen;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
destructor TCustomLEDStateProvider.Destroy;
|
|
||||||
begin
|
|
||||||
FreeAndNil(FFunctionMap);
|
|
||||||
FreeAndNil(FFunctionMapLock);
|
|
||||||
|
|
||||||
inherited;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TCustomLEDStateProvider.Initialize: Boolean;
|
|
||||||
begin
|
|
||||||
Result := True;
|
|
||||||
Task.Comm.OtherEndpoint.Send(MSG_EXECUTE);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TCustomLEDStateProvider.LockFunctionMap: TLEDFunctionMap;
|
|
||||||
begin
|
|
||||||
FFunctionMapLock.Acquire;
|
|
||||||
Result := FFunctionMap;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
procedure TCustomLEDStateProvider.UnlockFunctionMap;
|
|
||||||
begin
|
|
||||||
FFunctionMapLock.Release;
|
|
||||||
Task.Comm.Send(MSG_UPDATEFUNCTIONMAP, Self);
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
procedure TCustomLEDStateProvider.SetStateByFunction(AFunction: Integer; AState: TLEDState);
|
|
||||||
begin
|
|
||||||
ConsumerChannel.Send(MSG_SETSTATEBYFUNCTION, [AFunction, Ord(AState)]);
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
procedure TCustomLEDStateProvider.MsgExecute(var msg: TOmniMessage);
|
|
||||||
begin
|
|
||||||
Execute;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
{ TLEDFunctionMap }
|
|
||||||
procedure TLEDFunctionMap.Clear;
|
|
||||||
var
|
|
||||||
ledPosition: Integer;
|
|
||||||
|
|
||||||
begin
|
|
||||||
for ledPosition := Low(FFunctions) to High(FFunctions) do
|
|
||||||
FFunctions[ledPosition] := FUNCTION_NONE;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
procedure TLEDFunctionMap.SetFunction(ALEDIndex, AFunction: Integer);
|
|
||||||
begin
|
|
||||||
FFunctions[ALEDIndex] := AFunction;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
function TLEDFunctionMap.GetFunction(ALEDIndex: Integer): Integer;
|
|
||||||
begin
|
|
||||||
Result := FFunctions[ALEDIndex];
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
function TLEDFunctionMap.GetCount: Integer;
|
|
||||||
begin
|
|
||||||
Result := Length(FFunctions);
|
|
||||||
end;
|
|
||||||
|
|
||||||
end.
|
|
@ -5,7 +5,8 @@ uses
|
|||||||
Classes,
|
Classes,
|
||||||
SyncObjs,
|
SyncObjs,
|
||||||
|
|
||||||
CustomLEDStateProvider,
|
LEDStateConsumer,
|
||||||
|
LEDStateProvider,
|
||||||
SimConnect;
|
SimConnect;
|
||||||
|
|
||||||
|
|
||||||
@ -17,25 +18,33 @@ const
|
|||||||
|
|
||||||
|
|
||||||
type
|
type
|
||||||
TFSXLEDStateProvider = class(TCustomLEDStateProvider)
|
TFSXLEDStateProvider = class(TLEDStateProvider)
|
||||||
private
|
private
|
||||||
FSimConnectHandle: THandle;
|
FSimConnectHandle: THandle;
|
||||||
|
FUseFunctionGear: Boolean;
|
||||||
protected
|
protected
|
||||||
procedure Execute; override;
|
function GetProcessMessagesInterval: Integer; override;
|
||||||
|
|
||||||
procedure UpdateMap(AConnection: THandle);
|
procedure SetInitialState;
|
||||||
|
procedure UpdateMap;
|
||||||
procedure HandleDispatch(AData: PSimConnectRecv);
|
procedure HandleDispatch(AData: PSimConnectRecv);
|
||||||
|
|
||||||
function GetDataDouble(var AData: Cardinal): Double;
|
function GetDataDouble(var AData: Cardinal): Double;
|
||||||
|
|
||||||
property SimConnectHandle: THandle read FSimConnectHandle;
|
property SimConnectHandle: THandle read FSimConnectHandle;
|
||||||
|
public
|
||||||
|
procedure Initialize; override;
|
||||||
|
procedure Finalize; override;
|
||||||
|
procedure ProcessMessages; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
uses
|
uses
|
||||||
ComObj,
|
ComObj,
|
||||||
SysUtils;
|
SysUtils,
|
||||||
|
|
||||||
|
LEDFunctionMap;
|
||||||
|
|
||||||
|
|
||||||
const
|
const
|
||||||
@ -52,80 +61,73 @@ const
|
|||||||
|
|
||||||
|
|
||||||
{ TFSXLEDStateProvider }
|
{ TFSXLEDStateProvider }
|
||||||
procedure TFSXLEDStateProvider.Execute;
|
procedure TFSXLEDStateProvider.Initialize;
|
||||||
var
|
|
||||||
connection: THandle;
|
|
||||||
data: PSimConnectRecv;
|
|
||||||
dataSize: Cardinal;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if not InitSimConnect then
|
if not InitSimConnect then
|
||||||
|
raise EInitializeError.Create('SimConnect.dll could not be loaded', EXIT_ERROR_INITSIMCONNECT);
|
||||||
|
|
||||||
|
if SimConnect_Open(FSimConnectHandle, APPNAME, 0, 0, 0, 0) <> S_OK then
|
||||||
|
raise EInitializeError.Create('Connection to Flight Simulator could not be established', EXIT_ERROR_CONNECT);
|
||||||
|
|
||||||
|
UpdateMap;
|
||||||
|
SetInitialState;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TFSXLEDStateProvider.Finalize;
|
||||||
|
begin
|
||||||
|
inherited;
|
||||||
|
|
||||||
|
if SimConnectHandle <> 0 then
|
||||||
begin
|
begin
|
||||||
Task.SetExitStatus(EXIT_ERROR_INITSIMCONNECT, 'SimConnect.dll could not be loaded');
|
SimConnect_Close(SimConnectHandle);
|
||||||
Task.Terminate;
|
FSimConnectHandle := 0;
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
if SimConnect_Open(connection, APPNAME, 0, 0, 0, 0) = S_OK then
|
|
||||||
try
|
|
||||||
UpdateMap(connection);
|
|
||||||
|
|
||||||
while not Task.Terminated do
|
|
||||||
begin
|
|
||||||
if SimConnect_GetNextDispatch(connection, data, dataSize) = S_OK then
|
|
||||||
HandleDispatch(data);
|
|
||||||
|
|
||||||
ProcessMessages;
|
|
||||||
Sleep(1);
|
|
||||||
end;
|
|
||||||
finally
|
|
||||||
SimConnect_Close(connection);
|
|
||||||
end else
|
|
||||||
begin
|
|
||||||
Task.SetExitStatus(EXIT_ERROR_CONNECT, 'Connection to Flight Simulator could not be established');
|
|
||||||
Task.Terminate;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TFSXLEDStateProvider.UpdateMap(AConnection: THandle);
|
procedure TFSXLEDStateProvider.ProcessMessages;
|
||||||
var
|
var
|
||||||
functionMap: TLEDFunctionMap;
|
data: PSimConnectRecv;
|
||||||
|
dataSize: Cardinal;
|
||||||
function HasFunction(AFunction: Integer): Boolean;
|
|
||||||
var
|
|
||||||
ledIndex: Integer;
|
|
||||||
|
|
||||||
begin
|
|
||||||
Result := False;
|
|
||||||
|
|
||||||
for ledIndex := 0 to Pred(functionMap.Count) do
|
|
||||||
if functionMap.GetFunction(ledIndex) = AFunction then
|
|
||||||
begin
|
|
||||||
Result := True;
|
|
||||||
break;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
SimConnect_ClearDataDefinition(AConnection, DEFINITION_GEAR);
|
inherited;
|
||||||
|
|
||||||
functionMap := LockFunctionMap;
|
while SimConnect_GetNextDispatch(SimConnectHandle, data, dataSize) = S_OK do
|
||||||
try
|
HandleDispatch(data);
|
||||||
if HasFunction(FUNCTION_FSX_GEAR) then
|
end;
|
||||||
begin
|
|
||||||
SimConnect_AddToDataDefinition(AConnection, DEFINITION_GEAR,
|
|
||||||
FSX_VARIABLE_GEARTOTALPCTEXTENDED,
|
procedure TFSXLEDStateProvider.SetInitialState;
|
||||||
FSX_UNIT_PERCENT);
|
begin
|
||||||
SimConnect_RequestDataOnSimObject(AConnection, REQUEST_GEAR,
|
// if FUseFunctionGear then
|
||||||
DEFINITION_GEAR,
|
// begin
|
||||||
SIMCONNECT_OBJECT_ID_USER,
|
// SimConnect_RequestDataOnSimObject(SimConnectHandle, REQUEST_GEAR,
|
||||||
SIMCONNECT_PERIOD_SIM_FRAME,
|
// DEFINITION_GEAR,
|
||||||
SIMCONNECT_DATA_REQUEST_FLAG_CHANGED);
|
// SIMCONNECT_OBJECT_ID_USER,
|
||||||
end;
|
// SIMCONNECT_PERIOD_ONCE,
|
||||||
finally
|
// SIMCONNECT_DATA_REQUEST_FLAG_DEFAULT);
|
||||||
UnlockFunctionMap;
|
// end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TFSXLEDStateProvider.UpdateMap;
|
||||||
|
begin
|
||||||
|
if FUseFunctionGear then
|
||||||
|
SimConnect_ClearDataDefinition(SimConnectHandle, DEFINITION_GEAR);
|
||||||
|
|
||||||
|
FUseFunctionGear := Consumer.FunctionMap.HasFunction(FUNCTION_FSX_GEAR);
|
||||||
|
if FUseFunctionGear then
|
||||||
|
begin
|
||||||
|
SimConnect_AddToDataDefinition(SimConnectHandle, DEFINITION_GEAR,
|
||||||
|
FSX_VARIABLE_GEARTOTALPCTEXTENDED,
|
||||||
|
FSX_UNIT_PERCENT);
|
||||||
|
SimConnect_RequestDataOnSimObject(SimConnectHandle, REQUEST_GEAR,
|
||||||
|
DEFINITION_GEAR,
|
||||||
|
SIMCONNECT_OBJECT_ID_USER,
|
||||||
|
SIMCONNECT_PERIOD_SECOND,
|
||||||
|
SIMCONNECT_DATA_REQUEST_FLAG_CHANGED);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -144,16 +146,16 @@ begin
|
|||||||
REQUEST_GEAR:
|
REQUEST_GEAR:
|
||||||
begin
|
begin
|
||||||
case Trunc(GetDataDouble(simObjectData^.dwData) * 100) of
|
case Trunc(GetDataDouble(simObjectData^.dwData) * 100) of
|
||||||
0: SetStateByFunction(FUNCTION_FSX_GEAR, lsRed);
|
0: Consumer.SetStateByFunction(FUNCTION_FSX_GEAR, lsRed);
|
||||||
100: SetStateByFunction(FUNCTION_FSX_GEAR, lsGreen);
|
100: Consumer.SetStateByFunction(FUNCTION_FSX_GEAR, lsGreen);
|
||||||
else SetStateByFunction(FUNCTION_FSX_GEAR, lsAmber);
|
else Consumer.SetStateByFunction(FUNCTION_FSX_GEAR, lsAmber);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
SIMCONNECT_RECV_ID_QUIT:
|
SIMCONNECT_RECV_ID_QUIT:
|
||||||
Task.Terminate;
|
Terminate;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -163,4 +165,10 @@ begin
|
|||||||
Result := PDouble(@AData)^;
|
Result := PDouble(@AData)^;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TFSXLEDStateProvider.GetProcessMessagesInterval: Integer;
|
||||||
|
begin
|
||||||
|
Result := 50;
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
190
G940LEDControl/Units/G940LEDStateConsumer.pas
Normal file
190
G940LEDControl/Units/G940LEDStateConsumer.pas
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
unit G940LEDStateConsumer;
|
||||||
|
|
||||||
|
interface
|
||||||
|
uses
|
||||||
|
Classes,
|
||||||
|
|
||||||
|
DirectInput,
|
||||||
|
OtlComm,
|
||||||
|
OtlTaskControl,
|
||||||
|
|
||||||
|
LEDFunctionMap,
|
||||||
|
LEDStateConsumer;
|
||||||
|
|
||||||
|
|
||||||
|
const
|
||||||
|
MSG_FINDTHROTTLEDEVICE = MSG_CONSUMER_OFFSET + 1;
|
||||||
|
|
||||||
|
|
||||||
|
type
|
||||||
|
TG940LEDStateConsumer = class(TLEDStateConsumer)
|
||||||
|
private
|
||||||
|
FDirectInput: IDirectInput8;
|
||||||
|
FThrottleDevice: IDirectInputDevice8;
|
||||||
|
protected
|
||||||
|
procedure MsgFindThrottleDevice(var msg: TOmniMessage); message MSG_FINDTHROTTLEDEVICE;
|
||||||
|
protected
|
||||||
|
function Initialize: Boolean; override;
|
||||||
|
procedure LEDStateChanged(ALEDIndex: Integer; AState: TLEDState); override;
|
||||||
|
|
||||||
|
procedure FindThrottleDevice;
|
||||||
|
procedure FoundThrottleDevice(ADeviceGUID: TGUID);
|
||||||
|
|
||||||
|
procedure SetDeviceState(AState: Integer);
|
||||||
|
|
||||||
|
property DirectInput: IDirectInput8 read FDirectInput;
|
||||||
|
property ThrottleDevice: IDirectInputDevice8 read FThrottleDevice;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
const
|
||||||
|
MSG_NOTIFY_DEVICESTATE = 1;
|
||||||
|
|
||||||
|
DEVICESTATE_SEARCHING = 0;
|
||||||
|
DEVICESTATE_FOUND = 1;
|
||||||
|
DEVICESTATE_NOTFOUND = 2;
|
||||||
|
|
||||||
|
EXIT_ERROR_LOGIJOYSTICKDLL = 1;
|
||||||
|
EXIT_ERROR_DIRECTINPUT = 2;
|
||||||
|
|
||||||
|
|
||||||
|
implementation
|
||||||
|
uses
|
||||||
|
SysUtils,
|
||||||
|
Windows,
|
||||||
|
|
||||||
|
LogiJoystickDLL;
|
||||||
|
|
||||||
|
|
||||||
|
function EnumDevicesProc(var lpddi: TDIDeviceInstanceA; pvRef: Pointer): BOOL; stdcall;
|
||||||
|
var
|
||||||
|
vendorID: Word;
|
||||||
|
productID: Word;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Result := True;
|
||||||
|
|
||||||
|
vendorID := LOWORD(lpddi.guidProduct.D1);
|
||||||
|
productID := HIWORD(lpddi.guidProduct.D1);
|
||||||
|
|
||||||
|
if (vendorID = VENDOR_LOGITECH) and
|
||||||
|
(productID = PRODUCT_G940_THROTTLE) then
|
||||||
|
begin
|
||||||
|
TG940LEDStateConsumer(pvRef).FoundThrottleDevice(lpddi.guidInstance);
|
||||||
|
Result := False;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{ TG940LEDStateConsumer }
|
||||||
|
function TG940LEDStateConsumer.Initialize: Boolean;
|
||||||
|
begin
|
||||||
|
Result := inherited Initialize;
|
||||||
|
if not Result then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
Result := False;
|
||||||
|
|
||||||
|
if not LogiJoystickDLLInitialized then
|
||||||
|
begin
|
||||||
|
Task.SetExitStatus(EXIT_ERROR_LOGIJOYSTICKDLL, 'Could not load LogiJoystickDLL.dll');
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// btnRetry.Visible := False;
|
||||||
|
// SetState(STATE_SEARCHING, False);
|
||||||
|
|
||||||
|
if DirectInput8Create(SysInit.HInstance, DIRECTINPUT_VERSION, IDirectInput8, FDirectInput, nil) <> S_OK then
|
||||||
|
begin
|
||||||
|
Task.SetExitStatus(EXIT_ERROR_DIRECTINPUT, 'Failed to initialize DirectInput');
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Result := True;
|
||||||
|
Task.Comm.OtherEndpoint.Send(MSG_FINDTHROTTLEDEVICE);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TG940LEDStateConsumer.LEDStateChanged(ALEDIndex: Integer; AState: TLEDState);
|
||||||
|
var
|
||||||
|
color: TLogiColor;
|
||||||
|
|
||||||
|
begin
|
||||||
|
// ToDo SetLEDs gebruiken (vereist override van SetStateByFunction om te groeperen)
|
||||||
|
if Assigned(ThrottleDevice) then
|
||||||
|
begin
|
||||||
|
color := LOGI_GREEN;
|
||||||
|
|
||||||
|
case AState of
|
||||||
|
lsOff: color := LOGI_OFF;
|
||||||
|
lsGreen: color := LOGI_GREEN;
|
||||||
|
lsAmber: color := LOGI_AMBER;
|
||||||
|
lsRed: color := LOGI_RED;
|
||||||
|
|
||||||
|
// ToDo timers voor warning / error
|
||||||
|
lsWarning: color := LOGI_RED;
|
||||||
|
lsError: color := LOGI_RED;
|
||||||
|
end;
|
||||||
|
|
||||||
|
SetButtonColor(ThrottleDevice, TLogiPanelButton(ALEDIndex), color);
|
||||||
|
ProcessMessages;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TG940LEDStateConsumer.FindThrottleDevice;
|
||||||
|
begin
|
||||||
|
SetDeviceState(DEVICESTATE_SEARCHING);
|
||||||
|
DirectInput.EnumDevices(DI8DEVCLASS_GAMECTRL,
|
||||||
|
EnumDevicesProc,
|
||||||
|
Pointer(Self),
|
||||||
|
DIEDFL_ATTACHEDONLY);
|
||||||
|
|
||||||
|
if not Assigned(ThrottleDevice) then
|
||||||
|
SetDeviceState(DEVICESTATE_NOTFOUND);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TG940LEDStateConsumer.FoundThrottleDevice(ADeviceGUID: TGUID);
|
||||||
|
begin
|
||||||
|
if DirectInput.CreateDevice(ADeviceGUID, FThrottleDevice, nil) = S_OK then
|
||||||
|
SetDeviceState(DEVICESTATE_FOUND);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TG940LEDStateConsumer.SetDeviceState(AState: Integer);
|
||||||
|
begin
|
||||||
|
Task.Comm.Send(MSG_NOTIFY_DEVICESTATE, AState);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TG940LEDStateConsumer.MsgFindThrottleDevice(var msg: TOmniMessage);
|
||||||
|
begin
|
||||||
|
FindThrottleDevice;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
//procedure TCustomLEDStateProvider.SetStateByFunction(AFunction: Integer; AState: TLEDState);
|
||||||
|
//var
|
||||||
|
// functionMap: TLEDFunctionMap;
|
||||||
|
// ledIndex: Integer;
|
||||||
|
//
|
||||||
|
//begin
|
||||||
|
// functionMap := LockFunctionMap;
|
||||||
|
// try
|
||||||
|
// for ledIndex := 0 to Pred(functionMap.Count) do
|
||||||
|
// if functionMap.GetFunction(ledIndex) = AFunction then
|
||||||
|
// begin
|
||||||
|
// if AState <> FState[ledIndex] then
|
||||||
|
// begin
|
||||||
|
// FState[ledIndex] := AState;
|
||||||
|
// ConsumerChannel.Send(MSG_STATECHANGED, [ledIndex, Ord(AState)]);
|
||||||
|
// end;
|
||||||
|
// end;
|
||||||
|
// finally
|
||||||
|
// UnlockFunctionMap;
|
||||||
|
// end;
|
||||||
|
//end;
|
||||||
|
|
||||||
|
end.
|
174
G940LEDControl/Units/LEDFunctionMap.pas
Normal file
174
G940LEDControl/Units/LEDFunctionMap.pas
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
unit LEDFunctionMap;
|
||||||
|
|
||||||
|
interface
|
||||||
|
uses
|
||||||
|
Classes,
|
||||||
|
SyncObjs,
|
||||||
|
|
||||||
|
X2UtHashes;
|
||||||
|
|
||||||
|
|
||||||
|
type
|
||||||
|
TLEDState = (lsOff, lsGreen, lsAmber, lsRed, lsWarning, lsError);
|
||||||
|
|
||||||
|
TLEDFunctionMap = class(TObject)
|
||||||
|
private
|
||||||
|
FFunctions: TX2IIHash;
|
||||||
|
protected
|
||||||
|
function Find(AFunction: Integer; out ALEDIndex: Integer): Boolean;
|
||||||
|
public
|
||||||
|
constructor Create;
|
||||||
|
destructor Destroy; override;
|
||||||
|
|
||||||
|
procedure Clear;
|
||||||
|
|
||||||
|
procedure SetFunction(ALEDIndex, AFunction: Integer);
|
||||||
|
function GetFunction(ALEDIndex: Integer): Integer;
|
||||||
|
|
||||||
|
function HasFunction(AFunction: Integer): Boolean;
|
||||||
|
|
||||||
|
function FindFirst(AFunction: Integer; out ALEDIndex: Integer): Boolean;
|
||||||
|
function FindNext(AFunction: Integer; out ALEDIndex: Integer): Boolean;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
TLEDStateMap = class(TObject)
|
||||||
|
private
|
||||||
|
FStates: TX2IIHash;
|
||||||
|
public
|
||||||
|
constructor Create;
|
||||||
|
destructor Destroy; override;
|
||||||
|
|
||||||
|
procedure Clear;
|
||||||
|
|
||||||
|
function GetState(ALEDIndex: Integer; ADefault: TLEDState = lsGreen): TLEDState;
|
||||||
|
function SetState(ALEDIndex: Integer; AState: TLEDState): Boolean;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
const
|
||||||
|
FUNCTION_NONE = 0;
|
||||||
|
|
||||||
|
|
||||||
|
implementation
|
||||||
|
uses
|
||||||
|
SysUtils;
|
||||||
|
|
||||||
|
|
||||||
|
{ TLEDFunctionMap }
|
||||||
|
constructor TLEDFunctionMap.Create;
|
||||||
|
begin
|
||||||
|
inherited;
|
||||||
|
|
||||||
|
FFunctions := TX2IIHash.Create;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
destructor TLEDFunctionMap.Destroy;
|
||||||
|
begin
|
||||||
|
FreeAndNil(FFunctions);
|
||||||
|
|
||||||
|
inherited;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TLEDFunctionMap.Clear;
|
||||||
|
begin
|
||||||
|
FFunctions.Clear;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TLEDFunctionMap.SetFunction(ALEDIndex, AFunction: Integer);
|
||||||
|
begin
|
||||||
|
FFunctions[ALEDIndex] := AFunction;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TLEDFunctionMap.GetFunction(ALEDIndex: Integer): Integer;
|
||||||
|
begin
|
||||||
|
Result := FFunctions[ALEDIndex];
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TLEDFunctionMap.HasFunction(AFunction: Integer): Boolean;
|
||||||
|
var
|
||||||
|
ledIndex: Integer;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Result := FindFirst(AFunction, ledIndex);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TLEDFunctionMap.FindFirst(AFunction: Integer; out ALEDIndex: Integer): Boolean;
|
||||||
|
begin
|
||||||
|
FFunctions.First;
|
||||||
|
Result := Find(AFunction, ALEDIndex);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TLEDFunctionMap.FindNext(AFunction: Integer; out ALEDIndex: Integer): Boolean;
|
||||||
|
begin
|
||||||
|
Result := Find(AFunction, ALEDIndex);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function TLEDFunctionMap.Find(AFunction: Integer; out ALEDIndex: Integer): Boolean;
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
|
||||||
|
while FFunctions.Next do
|
||||||
|
begin
|
||||||
|
if FFunctions.CurrentValue = AFunction then
|
||||||
|
begin
|
||||||
|
ALEDIndex := FFunctions.CurrentKey;
|
||||||
|
Result := True;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{ TLEDStateMap }
|
||||||
|
constructor TLEDStateMap.Create;
|
||||||
|
begin
|
||||||
|
inherited;
|
||||||
|
|
||||||
|
FStates := TX2IIHash.Create;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
destructor TLEDStateMap.Destroy;
|
||||||
|
begin
|
||||||
|
FreeAndNil(FStates);
|
||||||
|
|
||||||
|
inherited;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TLEDStateMap.Clear;
|
||||||
|
begin
|
||||||
|
FStates.Clear;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TLEDStateMap.GetState(ALEDIndex: Integer; ADefault: TLEDState): TLEDState;
|
||||||
|
begin
|
||||||
|
Result := ADefault;
|
||||||
|
if FStates.Exists(ALEDIndex) then
|
||||||
|
Result := TLEDState(FStates[ALEDIndex]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TLEDStateMap.SetState(ALEDIndex: Integer; AState: TLEDState): Boolean;
|
||||||
|
begin
|
||||||
|
if FStates.Exists(ALEDIndex) then
|
||||||
|
Result := (FStates[ALEDIndex] <> Ord(AState))
|
||||||
|
else
|
||||||
|
Result := True;
|
||||||
|
|
||||||
|
if Result then
|
||||||
|
FStates[ALEDIndex] := Ord(AState);
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
@ -2,202 +2,204 @@ unit LEDStateConsumer;
|
|||||||
|
|
||||||
interface
|
interface
|
||||||
uses
|
uses
|
||||||
DirectInput,
|
|
||||||
OtlComm,
|
OtlComm,
|
||||||
OtlTaskControl,
|
OtlTaskControl,
|
||||||
|
|
||||||
CustomLEDStateProvider;
|
LEDFunctionMap,
|
||||||
|
LEDStateProvider;
|
||||||
|
|
||||||
|
|
||||||
const
|
const
|
||||||
MSG_FINDTHROTTLEDEVICE = 1;
|
MSG_CLEAR_FUNCTIONS = 1;
|
||||||
MSG_NOTIFY_DEVICESTATE = 2;
|
MSG_SET_FUNCTION = 2;
|
||||||
|
MSG_INITIALIZE_PROVIDER = 3;
|
||||||
|
MSG_FINALIZE_PROVIDER = 4;
|
||||||
|
MSG_PROCESS_MESSAGES = 5;
|
||||||
|
|
||||||
|
MSG_CONSUMER_OFFSET = MSG_PROCESS_MESSAGES;
|
||||||
|
|
||||||
|
TIMER_PROCESSMESSAGES = 1;
|
||||||
|
|
||||||
|
|
||||||
type
|
type
|
||||||
TG940LEDStateConsumer = class(TOmniWorker)
|
TLEDStateConsumer = class(TOmniWorker, ILEDStateConsumer)
|
||||||
private
|
private
|
||||||
FProviderChannel: IOmniCommunicationEndpoint;
|
|
||||||
FDirectInput: IDirectInput8;
|
|
||||||
FThrottleDevice: IDirectInputDevice8;
|
|
||||||
FFunctionMap: TLEDFunctionMap;
|
FFunctionMap: TLEDFunctionMap;
|
||||||
|
FStateMap: TLEDStateMap;
|
||||||
|
FProvider: TLEDStateProvider;
|
||||||
|
FTimerSet: Boolean;
|
||||||
protected
|
protected
|
||||||
procedure MsgFindThrottleDevice(var msg: TOmniMessage); message MSG_FINDTHROTTLEDEVICE;
|
procedure MsgClearFunctions(var msg: TOmniMessage); message MSG_CLEAR_FUNCTIONS;
|
||||||
procedure MsgUpdateFunctionMap(var msg: TOmniMessage); message MSG_UPDATEFUNCTIONMAP;
|
procedure MsgSetFunction(var msg: TOmniMessage); message MSG_SET_FUNCTION;
|
||||||
procedure MsgSetStateByFunction(var msg: TOmniMessage); message MSG_SETSTATEBYFUNCTION;
|
procedure MsgInitializeProvider(var msg: TOmniMessage); message MSG_INITIALIZE_PROVIDER;
|
||||||
protected
|
procedure MsgFinalizeProvider(var msg: TOmniMessage); message MSG_FINALIZE_PROVIDER;
|
||||||
function Initialize: Boolean; override;
|
procedure MsgProcessMessages(var msg: TOmniMessage); message MSG_PROCESS_MESSAGES;
|
||||||
|
|
||||||
procedure FindThrottleDevice;
|
procedure InitializeProvider(AProviderClass: TLEDStateProviderClass);
|
||||||
procedure FoundThrottleDevice(ADeviceGUID: TGUID);
|
procedure FinalizeProvider;
|
||||||
|
|
||||||
procedure SetDeviceState(AState: Integer);
|
procedure LEDStateChanged(ALEDIndex: Integer; AState: TLEDState); virtual;
|
||||||
|
|
||||||
property DirectInput: IDirectInput8 read FDirectInput;
|
{ ILEDStateConsumer }
|
||||||
property ThrottleDevice: IDirectInputDevice8 read FThrottleDevice;
|
function GetFunctionMap: TLEDFunctionMap;
|
||||||
|
procedure SetStateByFunction(AFunction: Integer; AState: TLEDState);
|
||||||
|
|
||||||
|
property FunctionMap: TLEDFunctionMap read GetFunctionMap;
|
||||||
|
property StateMap: TLEDStateMap read FStateMap;
|
||||||
|
property Provider: TLEDStateProvider read FProvider;
|
||||||
public
|
public
|
||||||
constructor Create(AProviderChannel: IOmniCommunicationEndpoint);
|
constructor Create;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
|
|
||||||
|
class procedure ClearFunctions(AConsumer: IOmniTaskControl);
|
||||||
|
class procedure SetFunction(AConsumer: IOmniTaskControl; ALEDIndex, AFunction: Integer);
|
||||||
|
class procedure InitializeStateProvider(AConsumer: IOmniTaskControl; AProviderClass: TLEDStateProviderClass);
|
||||||
|
class procedure FinalizeStateProvider(AConsumer: IOmniTaskControl);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
const
|
|
||||||
EXIT_ERROR_LOGIJOYSTICKDLL = 1;
|
|
||||||
EXIT_ERROR_DIRECTINPUT = 2;
|
|
||||||
|
|
||||||
|
|
||||||
DEVICESTATE_SEARCHING = 0;
|
|
||||||
DEVICESTATE_FOUND = 1;
|
|
||||||
DEVICESTATE_NOTFOUND = 2;
|
|
||||||
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
uses
|
uses
|
||||||
SysUtils,
|
SysUtils,
|
||||||
Windows,
|
|
||||||
|
|
||||||
LogiJoystickDLL;
|
OtlCommon;
|
||||||
|
|
||||||
|
|
||||||
function EnumDevicesProc(var lpddi: TDIDeviceInstanceA; pvRef: Pointer): BOOL; stdcall;
|
{ TLEDStateConsumer }
|
||||||
var
|
constructor TLEDStateConsumer.Create;
|
||||||
vendorID: Word;
|
|
||||||
productID: Word;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Result := True;
|
inherited;
|
||||||
|
|
||||||
vendorID := LOWORD(lpddi.guidProduct.D1);
|
|
||||||
productID := HIWORD(lpddi.guidProduct.D1);
|
|
||||||
|
|
||||||
if (vendorID = VENDOR_LOGITECH) and
|
|
||||||
(productID = PRODUCT_G940_THROTTLE) then
|
|
||||||
begin
|
|
||||||
TG940LEDStateConsumer(pvRef).FoundThrottleDevice(lpddi.guidInstance);
|
|
||||||
Result := False;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{ TG940LEDStateConsumer }
|
|
||||||
constructor TG940LEDStateConsumer.Create(AProviderChannel: IOmniCommunicationEndpoint);
|
|
||||||
begin
|
|
||||||
inherited Create;
|
|
||||||
|
|
||||||
FProviderChannel := AProviderChannel;
|
|
||||||
FFunctionMap := TLEDFunctionMap.Create;
|
FFunctionMap := TLEDFunctionMap.Create;
|
||||||
|
FStateMap := TLEDStateMap.Create;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
destructor TG940LEDStateConsumer.Destroy;
|
destructor TLEDStateConsumer.Destroy;
|
||||||
begin
|
begin
|
||||||
|
FinalizeProvider;
|
||||||
|
|
||||||
|
FreeAndNil(FStateMap);
|
||||||
FreeAndNil(FFunctionMap);
|
FreeAndNil(FFunctionMap);
|
||||||
|
|
||||||
inherited;
|
inherited;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function TG940LEDStateConsumer.Initialize: Boolean;
|
function TLEDStateConsumer.GetFunctionMap: TLEDFunctionMap;
|
||||||
begin
|
begin
|
||||||
Result := False;
|
Result := FFunctionMap;
|
||||||
|
|
||||||
if not LogiJoystickDLLInitialized then
|
|
||||||
begin
|
|
||||||
Task.SetExitStatus(EXIT_ERROR_LOGIJOYSTICKDLL, 'Could not load LogiJoystickDLL.dll');
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
// btnRetry.Visible := False;
|
|
||||||
// SetState(STATE_SEARCHING, False);
|
|
||||||
|
|
||||||
if DirectInput8Create(SysInit.HInstance, DIRECTINPUT_VERSION, IDirectInput8, FDirectInput, nil) <> S_OK then
|
|
||||||
begin
|
|
||||||
Task.SetExitStatus(EXIT_ERROR_DIRECTINPUT, 'Failed to initialize DirectInput');
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
Result := True;
|
|
||||||
|
|
||||||
Task.RegisterComm(FProviderChannel);
|
|
||||||
FindThrottleDevice;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TG940LEDStateConsumer.FindThrottleDevice;
|
procedure TLEDStateConsumer.SetStateByFunction(AFunction: Integer; AState: TLEDState);
|
||||||
begin
|
|
||||||
SetDeviceState(DEVICESTATE_SEARCHING);
|
|
||||||
DirectInput.EnumDevices(DI8DEVCLASS_GAMECTRL,
|
|
||||||
EnumDevicesProc,
|
|
||||||
Pointer(Self),
|
|
||||||
DIEDFL_ATTACHEDONLY);
|
|
||||||
|
|
||||||
if not Assigned(ThrottleDevice) then
|
|
||||||
SetDeviceState(DEVICESTATE_NOTFOUND);
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
procedure TG940LEDStateConsumer.FoundThrottleDevice(ADeviceGUID: TGUID);
|
|
||||||
begin
|
|
||||||
if DirectInput.CreateDevice(ADeviceGUID, FThrottleDevice, nil) = S_OK then
|
|
||||||
SetDeviceState(DEVICESTATE_FOUND);
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
procedure TG940LEDStateConsumer.SetDeviceState(AState: Integer);
|
|
||||||
begin
|
|
||||||
Task.Comm.Send(MSG_NOTIFY_DEVICESTATE, AState);
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
procedure TG940LEDStateConsumer.MsgFindThrottleDevice(var msg: TOmniMessage);
|
|
||||||
begin
|
|
||||||
FindThrottleDevice;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
procedure TG940LEDStateConsumer.MsgUpdateFunctionMap(var msg: TOmniMessage);
|
|
||||||
var
|
var
|
||||||
provider: TCustomLEDStateProvider;
|
ledIndex: Integer;
|
||||||
functionMap: TLEDFunctionMap;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
provider := (msg.MsgData.AsObject as TCustomLEDStateProvider);
|
if FunctionMap.FindFirst(AFunction, ledIndex) then
|
||||||
functionMap := provider.LockFunctionMap;
|
repeat
|
||||||
try
|
if StateMap.SetState(ledIndex, AState) then
|
||||||
FFunctionMap.Assign(functionMap);
|
LEDStateChanged(ledIndex, AState);
|
||||||
finally
|
until not FunctionMap.FindNext(AFunction, ledIndex);
|
||||||
provider.UnlockFunctionMap;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
procedure TLEDStateConsumer.MsgClearFunctions(var msg: TOmniMessage);
|
||||||
|
begin
|
||||||
|
FunctionMap.Clear;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TLEDStateConsumer.MsgSetFunction(var msg: TOmniMessage);
|
||||||
|
var
|
||||||
|
values: TOmniValueContainer;
|
||||||
|
|
||||||
|
begin
|
||||||
|
values := msg.MsgData.AsArray;
|
||||||
|
FunctionMap.SetFunction(values[0], values[1]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TLEDStateConsumer.MsgInitializeProvider(var msg: TOmniMessage);
|
||||||
|
begin
|
||||||
|
InitializeProvider(TLEDStateProviderClass(msg.MsgData.AsPointer));
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TLEDStateConsumer.MsgFinalizeProvider(var msg: TOmniMessage);
|
||||||
|
begin
|
||||||
|
FinalizeProvider;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TLEDStateConsumer.MsgProcessMessages(var msg: TOmniMessage);
|
||||||
|
begin
|
||||||
|
Provider.ProcessMessages;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TLEDStateConsumer.InitializeProvider(AProviderClass: TLEDStateProviderClass);
|
||||||
|
begin
|
||||||
|
FinalizeProvider;
|
||||||
|
|
||||||
|
FProvider := AProviderClass.Create(Self);
|
||||||
|
// ToDo exception handlign
|
||||||
|
Provider.Initialize;
|
||||||
|
|
||||||
|
if Provider.ProcessMessagesInterval > -1 then
|
||||||
|
begin
|
||||||
|
Task.SetTimer(TIMER_PROCESSMESSAGES, Provider.ProcessMessagesInterval, MSG_PROCESS_MESSAGES);
|
||||||
|
FTimerSet := True;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TG940LEDStateConsumer.MsgSetStateByFunction(var msg: TOmniMessage);
|
procedure TLEDStateConsumer.FinalizeProvider;
|
||||||
begin
|
begin
|
||||||
//
|
if Assigned(Provider) then
|
||||||
|
begin
|
||||||
|
if FTimerSet then
|
||||||
|
begin
|
||||||
|
Task.ClearTimer(TIMER_PROCESSMESSAGES);
|
||||||
|
FTimerSet := False;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Provider.Terminate;
|
||||||
|
Provider.Finalize;
|
||||||
|
FreeAndNil(FProvider);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
//procedure TCustomLEDStateProvider.SetStateByFunction(AFunction: Integer; AState: TLEDState);
|
procedure TLEDStateConsumer.LEDStateChanged(ALEDIndex: Integer; AState: TLEDState);
|
||||||
//var
|
begin
|
||||||
// functionMap: TLEDFunctionMap;
|
end;
|
||||||
// ledIndex: Integer;
|
|
||||||
//
|
|
||||||
//begin
|
class procedure TLEDStateConsumer.ClearFunctions(AConsumer: IOmniTaskControl);
|
||||||
// functionMap := LockFunctionMap;
|
begin
|
||||||
// try
|
AConsumer.Comm.Send(MSG_CLEAR_FUNCTIONS);
|
||||||
// for ledIndex := 0 to Pred(functionMap.Count) do
|
end;
|
||||||
// if functionMap.GetFunction(ledIndex) = AFunction then
|
|
||||||
// begin
|
|
||||||
// if AState <> FState[ledIndex] then
|
class procedure TLEDStateConsumer.SetFunction(AConsumer: IOmniTaskControl; ALEDIndex, AFunction: Integer);
|
||||||
// begin
|
begin
|
||||||
// FState[ledIndex] := AState;
|
AConsumer.Comm.Send(MSG_SET_FUNCTION, [ALEDIndex, AFunction]);
|
||||||
// ConsumerChannel.Send(MSG_STATECHANGED, [ledIndex, Ord(AState)]);
|
end;
|
||||||
// end;
|
|
||||||
// end;
|
|
||||||
// finally
|
class procedure TLEDStateConsumer.InitializeStateProvider(AConsumer: IOmniTaskControl; AProviderClass: TLEDStateProviderClass);
|
||||||
// UnlockFunctionMap;
|
begin
|
||||||
// end;
|
AConsumer.Comm.Send(MSG_INITIALIZE_PROVIDER, Pointer(AProviderClass));
|
||||||
//end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
class procedure TLEDStateConsumer.FinalizeStateProvider(AConsumer: IOmniTaskControl);
|
||||||
|
begin
|
||||||
|
AConsumer.Comm.Send(MSG_FINALIZE_PROVIDER);
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
111
G940LEDControl/Units/LEDStateProvider.pas
Normal file
111
G940LEDControl/Units/LEDStateProvider.pas
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
unit LEDStateProvider;
|
||||||
|
|
||||||
|
interface
|
||||||
|
uses
|
||||||
|
Classes,
|
||||||
|
SyncObjs,
|
||||||
|
SysUtils,
|
||||||
|
|
||||||
|
LEDFunctionMap;
|
||||||
|
|
||||||
|
type
|
||||||
|
EInitializeError = class(Exception)
|
||||||
|
private
|
||||||
|
FExitCode: Integer;
|
||||||
|
public
|
||||||
|
constructor Create(const Msg: string; ExitCode: Integer = 0);
|
||||||
|
|
||||||
|
property ExitCode: Integer read FExitCode write FExitCode;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
ILEDStateConsumer = interface
|
||||||
|
['{6E630C92-7C5C-4D16-8BED-AE27559FA584}']
|
||||||
|
function GetFunctionMap: TLEDFunctionMap;
|
||||||
|
procedure SetStateByFunction(AFunction: Integer; AState: TLEDState);
|
||||||
|
|
||||||
|
property FunctionMap: TLEDFunctionMap read GetFunctionMap;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
TLEDStateProvider = class(TObject)
|
||||||
|
private
|
||||||
|
FConsumer: ILEDStateConsumer;
|
||||||
|
FTerminated: Boolean;
|
||||||
|
protected
|
||||||
|
procedure Execute; virtual; abstract;
|
||||||
|
|
||||||
|
function GetProcessMessagesInterval: Integer; virtual;
|
||||||
|
|
||||||
|
property Consumer: ILEDStateConsumer read FConsumer;
|
||||||
|
public
|
||||||
|
constructor Create(AConsumer: ILEDStateConsumer);
|
||||||
|
destructor Destroy; override;
|
||||||
|
|
||||||
|
procedure Initialize; virtual;
|
||||||
|
procedure Finalize; virtual;
|
||||||
|
procedure ProcessMessages; virtual;
|
||||||
|
|
||||||
|
procedure Terminate; virtual;
|
||||||
|
|
||||||
|
property ProcessMessagesInterval: Integer read GetProcessMessagesInterval;
|
||||||
|
property Terminated: Boolean read FTerminated;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TLEDStateProviderClass = class of TLEDStateProvider;
|
||||||
|
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
|
||||||
|
{ TCustomLEDStateProvider }
|
||||||
|
constructor TLEDStateProvider.Create(AConsumer: ILEDStateConsumer);
|
||||||
|
begin
|
||||||
|
inherited Create;
|
||||||
|
|
||||||
|
FConsumer := AConsumer;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
destructor TLEDStateProvider.Destroy;
|
||||||
|
begin
|
||||||
|
inherited;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TLEDStateProvider.Initialize;
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TLEDStateProvider.Finalize;
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TLEDStateProvider.ProcessMessages;
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TLEDStateProvider.Terminate;
|
||||||
|
begin
|
||||||
|
FTerminated := True;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TLEDStateProvider.GetProcessMessagesInterval: Integer;
|
||||||
|
begin
|
||||||
|
Result := -1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{ EInitializeError }
|
||||||
|
constructor EInitializeError.Create(const Msg: string; ExitCode: Integer);
|
||||||
|
begin
|
||||||
|
inherited Create(Msg);
|
||||||
|
|
||||||
|
FExitCode := ExitCode;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
Loading…
Reference in New Issue
Block a user