/// <summary> /// Handle our update data /// </summary> /// <typeparam name="T"></typeparam> /// <param name="IncomingData"></param> /// <param name="ArrayType"></param> /// <param name="DataSource"></param> /// <param name="OutgoingData"></param> /// <returns></returns> private static void HandleUpdateData <T>(Array InArray, ref T[] OutgoingData, String ArrayType, String DataSource) { T[] IncomingData = (T[])InArray; //Build our list of changes, and send out List <T> ChangedData = new List <T>(); T[] OldData = OutgoingData; int MinLength = Math.Min(OldData.Length, IncomingData.Length); if (OldData != null && OldData.Length > 0) { for (int a = 0; a < MinLength; a++) { if (!MM_Comparable.IsDataIdentical(IncomingData[a], OldData[a])) { ChangedData.Add(IncomingData[a]); } } //Based on the system design, this should never be necessary. //But, if we have additional lines, make sure to flag them as changes. if (IncomingData.Length > MinLength) { for (int a = MinLength; a < IncomingData.Length; a++) { ChangedData.Add(IncomingData[a]); } } } else { ChangedData.AddRange(IncomingData); } //Now, assign our new data OutgoingData = IncomingData; //If we have changed data, send it out. T[] UpdatesToSend = ChangedData.ToArray(); //Find our update command UpdateCommandAttribute UpdateCommand = null; foreach (object obj in typeof(T).GetCustomAttributes(false)) { if (obj is UpdateCommandAttribute) { UpdateCommand = (UpdateCommandAttribute)obj; } } //Update our timestamp MM_Server.UpdateTimestamp(typeof(T), IncomingData.Length); //Send out notifications to our clients DateTime StartTime = DateTime.Now; foreach (MM_WCF_Interface Interface in MM_Server.ConnectedUserList) { if (Interface.User.LoggedOnTime != default(DateTime) && Interface.User.UserName != "?") { try { MM_WCF_Interface.SendMessage(Interface.User.UserId, UpdateCommand.UpdateCommand, UpdatesToSend); } catch (Exception ex) { while (ex.InnerException != null) { ex = ex.InnerException; } MM_Notification.WriteLine(ConsoleColor.Red, "Unable to send {0} to {1} on {2}: {3}", UpdateCommand.UpdateCommand, Interface.User.UserName, Interface.User.IPAddress, ex.Message); } } } }
/// <summary> /// Handle our update data with a dictionary system /// </summary> /// <typeparam name="S"></typeparam> /// <typeparam name="T"></typeparam> /// <param name="IncomingData"></param> /// <param name="OutgoingData"></param> /// <param name="ArrayType"></param> /// <param name="DataSource"></param> private static void HandleUpdateData <S, T>(Array InArray, ref Dictionary <S, T> OutgoingData, String ArrayType, String DataSource) { T[] IncomingData = (T[])InArray; //Capture the old and new data //MM_Notification.WriteLine(ConsoleColor.Green, "Received {0:#,##0} {1} from {2} on {3}.", IncomingData.Length, ArrayType, DataSource, DateTime.Now); //First, find our attribute data for updates and removes UpdateCommandAttribute UpdateCommand = null; RemovalCommandAttribute RemoveCommand = null; DoNotRemoveAttribute DoNotRemoveCommand = null; foreach (object obj in typeof(T).GetCustomAttributes(false)) { if (obj is UpdateCommandAttribute) { UpdateCommand = (UpdateCommandAttribute)obj; } else if (obj is RemovalCommandAttribute) { RemoveCommand = (RemovalCommandAttribute)obj; } else if (obj is DoNotRemoveAttribute) { DoNotRemoveCommand = (DoNotRemoveAttribute)obj; } } //Make sure we have the proper index information for our remove command List <PropertyInfo> IndexInfo = new List <PropertyInfo>(); foreach (String str in RemoveCommand.IndexColumn.Split(',')) { if (!String.IsNullOrEmpty(str)) { IndexInfo.Add(typeof(T).GetProperty(str)); } } //Build our list of changes, and send out List <T> UpdatedData = new List <T>(); Dictionary <S, T> OldData = OutgoingData; Dictionary <S, T> NewData = new Dictionary <S, T>(); //Now, go line by line and check for our values T FoundT; foreach (T InLine in IncomingData) { S Index = default(S); if (typeof(S) == typeof(int)) { Index = (S)IndexInfo[0].GetValue(InLine); } else if (typeof(S) == typeof(String)) { String ThisIndex = ""; foreach (PropertyInfo pI in IndexInfo) { ThisIndex += pI.GetValue(InLine).ToString(); } Index = (S)(object)ThisIndex; } if (!OutgoingData.TryGetValue(Index, out FoundT)) { UpdatedData.Add(InLine); } else if (!MM_Comparable.IsDataIdentical(InLine, FoundT)) { UpdatedData.Add(InLine); } if (!NewData.ContainsKey(Index)) { NewData.Add(Index, InLine); } } //Now, swap in our new data and track anything missing - old data now is tracking anything left has been removed OutgoingData = NewData; if (DoNotRemoveCommand == null) { foreach (S Index in NewData.Keys) { OldData.Remove(Index); } } //If we have changed data, send it out. //if (UpdatedData.Count != 0 || OldData.Count != 0) T[] UpdatesToSend = UpdatedData.ToArray(); T[] RemovalsToHandle = OldData.Values.ToArray(); //Update our timestamp MM_Server.UpdateTimestamp(typeof(T), IncomingData.Length); //Send out notifications to our clients // if (UpdatesToSend.Length > 0) foreach (MM_WCF_Interface Interface in MM_Server.ConnectedUserList) { if (Interface.User.LoggedOnTime != default(DateTime)) { try { MM_WCF_Interface.SendMessage(Interface.User.UserId, UpdateCommand.UpdateCommand, UpdatesToSend); } catch (Exception ex) { MM_Notification.WriteLine(ConsoleColor.Red, "Unable to send {0} to {1}: {2}", UpdateCommand.UpdateCommand, Interface.User.UserName, ex); } } } if (RemovalsToHandle.Length > 0 && !String.IsNullOrEmpty(RemoveCommand.RemovalCommand) && DoNotRemoveCommand == null) { foreach (MM_WCF_Interface Interface in MM_Server.ConnectedUserList) { if (Interface.User.LoggedOnTime != default(DateTime)) { try { MM_WCF_Interface.SendMessage(Interface.User.UserId, RemoveCommand.RemovalCommand, RemovalsToHandle); } catch (Exception ex) { MM_Notification.WriteLine(ConsoleColor.Red, "Unable to send {0} to {1}: {2}", RemoveCommand.RemovalCommand, Interface.User.UserName, ex); } } } } }