Simplified listening to multi part messages

This commit is contained in:
unknown 2014-07-31 00:59:47 -07:00
parent b2e4d7c2a6
commit 2fba15f6d9
3 changed files with 49 additions and 16 deletions

View file

@ -4,8 +4,8 @@ using System.Text;
namespace NmeaParser
{
interface IMultiPartMessage<T> : IEnumerable<T>
{
interface IMultiPartMessage : System.Collections.IEnumerable
{
/// <summary>
/// Total number of messages of this type in this cycle
/// </summary>
@ -16,4 +16,7 @@ namespace NmeaParser
/// </summary>
int MessageNumber { get; }
}
interface IMultiPartMessage<T> : IMultiPartMessage, IEnumerable<T>
{
}
}

View file

@ -40,6 +40,7 @@ namespace NmeaParser
tcs = new System.Threading.CancellationTokenSource();
m_stream = await OpenStreamAsync();
StartParser();
MultiPartMessageCache.Clear();
}
private void StartParser()
@ -82,6 +83,7 @@ namespace NmeaParser
}
await closeTask.Task;
await CloseStreamAsync(m_stream);
MultiPartMessageCache.Clear();
m_stream = null;
}
protected abstract Task CloseStreamAsync(Stream stream);
@ -98,7 +100,7 @@ namespace NmeaParser
if (lineEnd > -1)
{
line = message.Substring(0, lineEnd).Trim();
message = message.Substring(lineEnd);
message = message.Substring(lineEnd + 1);
}
}
if (!string.IsNullOrEmpty(line))
@ -118,10 +120,46 @@ namespace NmeaParser
private void OnMessageReceived(Nmea.NmeaMessage msg)
{
var args = new NmeaMessageReceivedEventArgs(msg);
if (msg is IMultiPartMessage)
{
args.IsMultiPart = true;
var multi = (IMultiPartMessage)msg;
if (MultiPartMessageCache.ContainsKey(msg.MessageType))
{
var dic = MultiPartMessageCache[msg.MessageType];
if (dic.ContainsKey(multi.MessageNumber - 1) && !dic.ContainsKey(multi.MessageNumber))
{
dic[multi.MessageNumber] = msg;
}
else //Something is out of order. Clear cache
MultiPartMessageCache.Remove(msg.MessageType);
}
else if (multi.MessageNumber == 1)
{
MultiPartMessageCache[msg.MessageType] = new Dictionary<int, Nmea.NmeaMessage>(multi.TotalMessages);
MultiPartMessageCache[msg.MessageType][1] = msg;
}
if (MultiPartMessageCache.ContainsKey(msg.MessageType))
{
var dic = MultiPartMessageCache[msg.MessageType];
if (dic.Count == multi.TotalMessages) //We have a full list
{
MultiPartMessageCache.Remove(msg.MessageType);
args.MessageParts = dic.Values.ToArray();
}
}
}
if (MessageReceived != null)
MessageReceived(this, new NmeaMessageReceivedEventArgs(msg));
{
MessageReceived(this, args);
}
}
private Dictionary<string, Dictionary<int, Nmea.NmeaMessage>> MultiPartMessageCache
= new Dictionary<string,Dictionary<int,Nmea.NmeaMessage>>();
public event EventHandler<NmeaMessageReceivedEventArgs> MessageReceived;
public void Dispose()
@ -147,10 +185,9 @@ namespace NmeaParser
{
internal NmeaMessageReceivedEventArgs(Nmea.NmeaMessage message) {
Message = message;
MessageList = new[] { message };
}
public Nmea.NmeaMessage Message { get; private set; }
public bool IsMultiPart { get; internal set; }
public Nmea.NmeaMessage[] MessageList { get; internal set; }
public Nmea.NmeaMessage[] MessageParts { get; internal set; }
}
}

View file

@ -28,25 +28,18 @@ namespace SampleApp.WinDesktop
var _ = device.OpenAsync();
}
Dictionary<int, NmeaParser.Nmea.Gps.Gpgsv> gpgsvList = new Dictionary<int,NmeaParser.Nmea.Gps.Gpgsv>();
private void device_MessageReceived(object sender, NmeaParser.NmeaMessageReceivedEventArgs args)
{
Dispatcher.BeginInvoke((Action) delegate()
{
output.Text += args.Message.MessageType + ": " + args.ToString() + '\n';
output.Text += args.Message.MessageType + ": " + args.Message.ToString() + '\n';
output.Select(output.Text.Length - 1, 0); //scroll to bottom
//Merge all gpgsv satellite messages
if(args.Message is NmeaParser.Nmea.Gps.Gpgsv)
{
var gpgsv = (NmeaParser.Nmea.Gps.Gpgsv)args.Message;
if(gpgsv.MessageNumber == 1)
{
gpgsvList = new Dictionary<int,NmeaParser.Nmea.Gps.Gpgsv>(); //first one. Replace list
}
gpgsvList[gpgsv.MessageNumber] = gpgsv;
if(gpgsv.MessageNumber == gpgsv.TotalMessages)
satView.GpgsvMessages = gpgsvList.Values;
if(args.IsMultiPart && args.MessageParts != null)
satView.GpgsvMessages = args.MessageParts.OfType<NmeaParser.Nmea.Gps.Gpgsv>();
}
});
}