2022-01-27 13:40:04 +00:00
using MSFSPopoutPanelManager.FsConnector ;
using MSFSPopoutPanelManager.Shared ;
using System ;
2022-06-22 16:31:41 +00:00
using System.Collections.Generic ;
2022-01-27 13:40:04 +00:00
using System.Diagnostics ;
2022-06-22 16:31:41 +00:00
using System.Linq ;
2022-01-27 13:40:04 +00:00
using System.Threading ;
using System.Timers ;
namespace MSFSPopoutPanelManager.Provider
{
public class SimConnectManager
{
private const int MSFS_DATA_REFRESH_TIMEOUT = 1000 ;
private SimConnector _simConnector ;
private dynamic _simData ;
private System . Timers . Timer _requestDataTimer ;
private SimConnectSystemEvent _lastSystemEvent ;
private bool _isPowerOnForPopOut ;
2022-05-04 15:11:04 +00:00
private bool _isTrackIRManaged ;
2022-01-27 13:40:04 +00:00
public event EventHandler OnConnected ;
public event EventHandler OnDisconnected ;
public event EventHandler < EventArgs < dynamic > > OnSimConnectDataRefreshed ;
public event EventHandler OnFlightStarted ;
public event EventHandler OnFlightStopped ;
public bool IsSimConnectStarted { get ; set ; }
public SimConnectManager ( )
{
_simConnector = new SimConnector ( ) ;
_simConnector . OnConnected + = ( sender , e ) = > { OnConnected ? . Invoke ( this , null ) ; } ;
_simConnector . OnDisconnected + = ( sender , e ) = > { OnDisconnected ? . Invoke ( this , null ) ; } ;
_simConnector . OnReceivedData + = HandleDataReceived ;
_simConnector . OnReceiveSystemEvent + = HandleReceiveSystemEvent ;
_simConnector . OnConnected + = ( sender , e ) = >
{
_requestDataTimer = new System . Timers . Timer ( ) ;
_requestDataTimer . Interval = MSFS_DATA_REFRESH_TIMEOUT ;
_requestDataTimer . Enabled = true ;
_requestDataTimer . Elapsed + = HandleDataRequested ;
_requestDataTimer . Elapsed + = HandleMessageReceived ;
} ;
_simConnector . Start ( ) ;
}
public void Stop ( )
{
_simConnector . Stop ( ) ;
}
public void Restart ( )
{
_simConnector . StopAndReconnect ( ) ;
}
public void TurnOnPower ( bool isRequiredForColdStart )
{
if ( isRequiredForColdStart & & _simData ! = null & & ! _simData . ElectricalMasterBattery )
{
_isPowerOnForPopOut = true ;
_simConnector . TransmitActionEvent ( ActionEvent . KEY_MASTER_BATTERY_SET , 1 ) ;
Thread . Sleep ( 100 ) ;
_simConnector . TransmitActionEvent ( ActionEvent . KEY_ALTERNATOR_SET , 1 ) ;
Thread . Sleep ( 100 ) ;
_simConnector . TransmitActionEvent ( ActionEvent . KEY_AVIONICS_MASTER_SET , 1 ) ;
2022-04-18 19:52:39 +00:00
Thread . Sleep ( 100 ) ;
_simConnector . TransmitActionEvent ( ActionEvent . KEY_AVIONICS_MASTER_2_SET , 1 ) ;
2022-01-27 13:40:04 +00:00
}
}
public void TurnOffpower ( )
{
if ( _isPowerOnForPopOut )
{
2022-04-18 19:52:39 +00:00
_simConnector . TransmitActionEvent ( ActionEvent . KEY_AVIONICS_MASTER_2_SET , 0 ) ;
2022-01-27 13:40:04 +00:00
Thread . Sleep ( 100 ) ;
_simConnector . TransmitActionEvent ( ActionEvent . KEY_AVIONICS_MASTER_SET , 0 ) ;
Thread . Sleep ( 100 ) ;
_simConnector . TransmitActionEvent ( ActionEvent . KEY_ALTERNATOR_SET , 0 ) ;
Thread . Sleep ( 100 ) ;
_simConnector . TransmitActionEvent ( ActionEvent . KEY_MASTER_BATTERY_SET , 0 ) ;
_isPowerOnForPopOut = false ;
}
}
2022-05-04 15:11:04 +00:00
public void TurnOffTrackIR ( )
{
2022-05-04 20:42:02 +00:00
if ( _simData ! = null & & _simData . TrackIREnable )
2022-05-04 15:11:04 +00:00
{
SetTrackIREnable ( false ) ;
_isTrackIRManaged = true ;
}
}
public void TurnOnTrackIR ( )
{
2022-05-04 20:42:02 +00:00
if ( _isTrackIRManaged & & _simData ! = null & & ! _simData . TrackIREnable )
2022-05-04 15:11:04 +00:00
{
SetTrackIREnable ( true ) ;
_isTrackIRManaged = false ;
}
}
private void SetTrackIREnable ( bool enable )
{
2022-06-22 16:31:41 +00:00
// Wait for _simData.ElectricalMasterBattery to refresh
Thread . Sleep ( MSFS_DATA_REFRESH_TIMEOUT + 250 ) ;
2022-05-04 15:11:04 +00:00
// It is prop3 in SimConnectStruct (by DataDefinitions.cs)
SimConnectStruct simConnectStruct = new SimConnectStruct ( ) ;
2022-06-22 16:31:41 +00:00
2022-05-31 15:45:35 +00:00
simConnectStruct . Prop01 = _simData . Title ; // must set "Title" for TrackIR variable to write correctly
2022-06-22 16:31:41 +00:00
simConnectStruct . Prop02 = _simData . ElectricalMasterBattery ? Convert . ToDouble ( 1 ) : Convert . ToDouble ( 0 ) ; // must set "ElectricalMasterBattery" for TrackIR variable to write correctly
2022-05-31 15:45:35 +00:00
simConnectStruct . Prop03 = enable ? Convert . ToDouble ( 1 ) : Convert . ToDouble ( 0 ) ; // this is the TrackIR variable
2022-05-04 15:11:04 +00:00
_simConnector . SetDataObject ( simConnectStruct ) ;
}
2022-01-27 13:40:04 +00:00
private void HandleDataRequested ( object sender , ElapsedEventArgs e )
{
try
{
_simConnector . RequestData ( ) ;
}
catch { }
}
private void HandleMessageReceived ( object sender , ElapsedEventArgs e )
{
try
{
_simConnector . ReceiveMessage ( ) ;
}
catch { }
}
public void HandleDataReceived ( object sender , EventArgs < dynamic > e )
{
_simData = e . Value ;
OnSimConnectDataRefreshed ? . Invoke ( this , new EventArgs < dynamic > ( e . Value ) ) ;
}
2022-06-22 16:31:41 +00:00
private List < SimConnectSystemEvent > _systemEventBuffer ;
private List < SimConnectSystemEvent > FlightRestartBeginBufferDef = new List < SimConnectSystemEvent > ( ) { SimConnectSystemEvent . SIMSTOP , SimConnectSystemEvent . VIEW } ;
private List < SimConnectSystemEvent > FlightRestartEndBufferDef = new List < SimConnectSystemEvent > ( ) { SimConnectSystemEvent . SIMSTART , SimConnectSystemEvent . VIEW } ;
private List < SimConnectSystemEvent > FlightStartBufferDef = new List < SimConnectSystemEvent > ( ) { SimConnectSystemEvent . SIMSTOP , SimConnectSystemEvent . SIMSTART , SimConnectSystemEvent . SIMSTOP , SimConnectSystemEvent . SIMSTART , SimConnectSystemEvent . VIEW } ;
private List < SimConnectSystemEvent > FlightEndBufferDef = new List < SimConnectSystemEvent > ( ) { SimConnectSystemEvent . SIMSTOP , SimConnectSystemEvent . SIMSTART , SimConnectSystemEvent . VIEW , SimConnectSystemEvent . SIMSTOP , SimConnectSystemEvent . SIMSTART } ;
private bool _systemEventInFlightRestartSequence ;
2022-04-25 15:26:28 +00:00
private void HandleReceiveSystemEvent ( object sender , EventArgs < SimConnectSystemEvent > e )
2022-01-27 13:40:04 +00:00
{
2022-06-22 16:31:41 +00:00
if ( _systemEventBuffer = = null )
_systemEventBuffer = new List < SimConnectSystemEvent > ( ) ;
2022-04-25 15:26:28 +00:00
var systemEvent = e . Value ;
2022-04-18 03:38:33 +00:00
2022-06-22 16:31:41 +00:00
_systemEventBuffer . Add ( systemEvent ) ;
2022-04-25 15:26:28 +00:00
Debug . WriteLine ( $"SimConnectSystemEvent Received: {systemEvent}" ) ;
2022-04-18 03:38:33 +00:00
2022-06-22 16:31:41 +00:00
if ( _systemEventBuffer . TakeLast ( 2 ) . SequenceEqual ( FlightRestartBeginBufferDef ) )
{
OnFlightStopped ? . Invoke ( this , null ) ;
_systemEventBuffer = null ;
_systemEventInFlightRestartSequence = true ;
}
else if ( _systemEventInFlightRestartSequence & & _systemEventBuffer . TakeLast ( 2 ) . SequenceEqual ( FlightRestartEndBufferDef ) )
2022-04-18 03:38:33 +00:00
{
2022-01-27 13:40:04 +00:00
OnFlightStarted ? . Invoke ( this , null ) ;
2022-06-22 16:31:41 +00:00
_systemEventBuffer = null ;
_systemEventInFlightRestartSequence = false ;
2022-04-18 03:38:33 +00:00
}
2022-06-22 16:31:41 +00:00
else if ( _systemEventBuffer . TakeLast ( 5 ) . SequenceEqual ( FlightStartBufferDef ) )
{
OnFlightStarted ? . Invoke ( this , null ) ;
_systemEventBuffer = null ;
}
else if ( _systemEventBuffer . TakeLast ( 5 ) . SequenceEqual ( FlightEndBufferDef ) )
2022-04-18 03:38:33 +00:00
{
2022-01-27 13:40:04 +00:00
OnFlightStopped ? . Invoke ( this , null ) ;
2022-06-22 16:31:41 +00:00
_systemEventBuffer = null ;
2022-04-18 03:38:33 +00:00
}
2022-01-27 13:40:04 +00:00
}
}
}