/// <summary>
 /// Called when [sensor impact].
 /// </summary>
 /// <param name="sensorImpactData">The sensor impact data.</param>
 private void OnSensorHit(ReceiverEvents.SensorHit e)
 {
     if (_clockRunning)
     {
         using (ReaderWriterLockMgr lockMgr = new ReaderWriterLockMgr(_dataLog.Impacts.Lock))
         {
             lockMgr.EnterWriteLock();
             _dataLog.Impacts.AddImpactsRow(
                 DateTime.Now,                           // Current datetime stamp
                 e.SensorId,                             // Sensor ID
                 _game.GameNumber,                       // Game number
                 _game.RoundNumber,                      // Round number
                 DateTime.Now - _countdownStartedTime,   // Elapsed time
                 (_meterNames.ContainsKey(e.SensorId) ? _meterNames[e.SensorId] : string.Empty), // Meter Name
                 e.OpCode,                               // Data Source Type
                 _config.RequiredImpactLevel,             // required impact level
                 e.ImpactLevel,                          // Actual impact level
                 e.Panel.ToString()                      // Sensor panel
             );
         }
     }
 }
 /// <summary>
 /// Called when [meter score changed].
 /// </summary>
 /// <param name="meterScoreData">The meter score data.</param>
 private void OnScoreChanged(GameEngineEvents.ScoreChanged e)
 {
     using (ReaderWriterLockMgr lockMgr = new ReaderWriterLockMgr(_dataLog.Scores.Lock))
     {
         lockMgr.EnterWriteLock();
         _dataLog.Scores.AddScoresRow(
             DateTime.Now,                           // Current datetime stamp
             e.SensorId,                             // Sensor ID
             _game.GameNumber,                       // Game number
             _game.RoundNumber,                      // Round number
             DateTime.Now - _countdownStartedTime,   // Elapsed time
             (_meterNames.ContainsKey(e.SensorId) ? _meterNames[e.SensorId] : string.Empty), // Meter Name
             _config.RequiredImpactLevel,             // required impact level
             e.ImpactLevel,                          // Actual impact level
             (int)(e.NewScore - e.OldScore),         // Number of points
             e.NewScore
         );
     }
 }
        /// <summary>
        /// Writes the database to disk.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.ComponentModel.DoWorkEventArgs"/> instance containing the event data.</param>
        private void WriteDatabaseToDisk()
        {
            if (_dataLog.HasChanges())
            {
                _logger.Log("Flushing dataset to disk", Category.Info, Priority.None);
                try
                {
                    string fileName = Path.Combine(CreateDataDirectory(), GetDataSetFileName());

                    using (ReaderWriterLockMgr impactLockMgr = new ReaderWriterLockMgr(_dataLog.Impacts.Lock))
                    using (ReaderWriterLockMgr scoreLockMgr = new ReaderWriterLockMgr(_dataLog.Scores.Lock))
                    {
                        impactLockMgr.EnterWriteLock();
                        scoreLockMgr.EnterWriteLock();
                        foreach (var row in _dataLog.Impacts.Where(row => row.Timestamp.Date != DateTime.Today).ToList()) _dataLog.Impacts.RemoveImpactsRow(row);
                        foreach (var row in _dataLog.Scores.Where(row => row.Timestamp.Date != DateTime.Today).ToList()) _dataLog.Scores.RemoveScoresRow(row);
                        _dataLog.AcceptChanges();
                        _dataLog.WriteXml(fileName, XmlWriteMode.WriteSchema);
                    }
                }
                catch (IOException ex)
                {
                    _logger.Log(ex.GetBaseException().ToString(), Category.Exception, Priority.High);
                    //FIXME: Need to handle this exception with a user notification
                }
            }
            else
            {
                _logger.Log("Skipping flushing of dataset (no changes)", Category.Info, Priority.None);
            }
        }