예제 #1
0
        /// <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);
                    }
                }
            }
        }
예제 #2
0
        /// <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);
                        }
                    }
                }
            }
        }