2022-01-27 13:40:04 +00:00
using MSFSPopoutPanelManager.FsConnector ;
using MSFSPopoutPanelManager.Shared ;
using System ;
using System.Diagnostics ;
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 ;
2022-04-18 03:38:33 +00:00
private bool _isSimActive ;
2022-01-27 13:40:04 +00:00
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 ;
} ;
2022-04-18 03:38:33 +00:00
_isSimActive = false ;
2022-01-27 13:40:04 +00:00
_simConnector . Start ( ) ;
}
public void Stop ( )
{
2022-04-18 03:38:33 +00:00
_isSimActive = false ;
2022-01-27 13:40:04 +00:00
_simConnector . Stop ( ) ;
}
public void Restart ( )
{
2022-04-18 03:38:33 +00:00
_isSimActive = false ;
2022-01-27 13:40:04 +00:00
_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 )
{
// It is prop3 in SimConnectStruct (by DataDefinitions.cs)
SimConnectStruct simConnectStruct = new SimConnectStruct ( ) ;
2022-05-31 15:45:35 +00:00
simConnectStruct . Prop01 = _simData . Title ; // must set "Title" for TrackIR variable to write correctly
simConnectStruct . Prop02 = _simData . ElectricalMasterBattery ? Convert . ToDouble ( 1 ) : Convert . ToDouble ( 0 ) ; // must set "ElectricalMasterBattery" for TrackIR variable to write correctly
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-04-25 15:26:28 +00:00
private void HandleReceiveSystemEvent ( object sender , EventArgs < SimConnectSystemEvent > e )
2022-01-27 13:40:04 +00:00
{
2022-04-25 15:26:28 +00:00
var systemEvent = e . Value ;
2022-04-18 03:38:33 +00:00
2022-04-25 15:26:28 +00:00
Debug . WriteLine ( $"SimConnectSystemEvent Received: {systemEvent}" ) ;
2022-04-18 03:38:33 +00:00
2022-01-27 13:40:04 +00:00
// to detect flight start at the "Ready to Fly" screen, it has a SIMSTART follows by a VIEW event
2022-04-25 15:26:28 +00:00
if ( _lastSystemEvent = = SimConnectSystemEvent . SIMSTART & & systemEvent = = SimConnectSystemEvent . VIEW )
2022-04-18 03:38:33 +00:00
{
_isSimActive = true ;
2022-04-18 04:52:43 +00:00
_lastSystemEvent = SimConnectSystemEvent . NONE ;
2022-01-27 13:40:04 +00:00
OnFlightStarted ? . Invoke ( this , null ) ;
2022-04-18 03:38:33 +00:00
return ;
}
// look for pair of events denoting sim ended after sim is active
2022-04-25 15:26:28 +00:00
if ( ( _isSimActive & & _lastSystemEvent = = SimConnectSystemEvent . SIMSTOP & & systemEvent = = SimConnectSystemEvent . VIEW ) | |
( _isSimActive & & _lastSystemEvent = = SimConnectSystemEvent . SIMSTOP & & systemEvent = = SimConnectSystemEvent . SIMSTART ) )
2022-04-18 03:38:33 +00:00
{
_isSimActive = false ;
_lastSystemEvent = SimConnectSystemEvent . NONE ;
2022-01-27 13:40:04 +00:00
OnFlightStopped ? . Invoke ( this , null ) ;
2022-04-18 03:38:33 +00:00
return ;
}
2022-01-27 13:40:04 +00:00
2022-04-18 03:38:33 +00:00
_lastSystemEvent = systemEvent ;
2022-01-27 13:40:04 +00:00
}
}
}