Exemple #1
0
        // On the server disconnecting
        private static void Disconnected(Connection Sender, DisconnectMessage Message)
        {
            // Unhook handlers
            Server.MessageReceived -= MessageReceived;
            Server.Disconnect      -= Disconnected;

            // Reset the signals
            InitialisedEvent.Dispose();
            InitialisedEvent = null;
            UserEvent.Dispose();
            UserEvent = null;
        }
Exemple #2
0
        // Handler for when the server receives a message
        private static void MessageReceived(Connection Sender, Message Msg)
        {
            bool Locked = true;

            Monitor.Enter(Lock);

            // Don't echo changes back to the server - changes made in this
            // function have been sent to us by the server
            ReportModelChanges = false;

            if (Msg is InitialiseMessage)
            {
                // Initialisation of the client - load in the data
                LoadSnapshot((Msg as InitialiseMessage).Snapshot, false);

                // Signal that we've received the initial data
                InitialisedEvent.Set();
            }
            else if (Msg is UserInformationMessage)
            {
                // Information on the User and their Room

                UserInformationMessage m = (Msg as UserInformationMessage);
                User User = m.User;
                Room Room = m.Room;

                if (User == null)
                {
                    throw new ArgumentNullException("Received a null user.");
                }
                if (Room == null)
                {
                    throw new ArgumentNullException("Received a null room.");
                }

                // Acquire references to the actual user/room
                DataSnapshot Frame = TakeSnapshot(false);
                CurrentUser = Frame.Users.SingleOrDefault(u => u.Id == User.Id);
                CurrentRoom = Frame.Rooms.SingleOrDefault(r => r.Id == Room.Id);

                // Signal that we've received the user data
                UserEvent.Set();
            }
            else if (Msg is DataMessage)
            {
                DataMessage Data = (DataMessage)Msg;

                // Get references to linked objects
                using (DataRepository Repo = new DataRepository(false))
                    Data.Item.Expand(Repo);

                // If we're not deleting it, set references to this item
                if (!Data.Delete)
                {
                    Data.Item.Attach();
                }
                else // Otherwise remove references
                {
                    Data.Item.Detach();
                }

                // Store the type of the received data
                Type t = Data.Item.GetType();
                // Get the right table from the dictionary (match received type to key)
                IList Table = Tables.Single(p => t == p.Key || t.IsSubclassOf(p.Key)).Value;

                // Find the index of the item in the table
                int Index = -1;
                for (int x = 0; x < Table.Count; x++)
                {
                    if (((DataModel)Table[x]).Id == Data.Item.Id)
                    {
                        Index = x;
                        break;
                    }
                }

                if (!Data.Delete)
                {
                    if (Index < 0) // Doesn't already exist, add it
                    {
                        Table.Add(Data.Item);
                    }
                    else // Already exists, update it
                    {
                        ((DataModel)Table[Index]).Update(Data.Item);
                    }
                }
                else // Delete it
                {
                    Table.RemoveAt(Index);
                }

                // Release the lock
                Monitor.Exit(Lock);
                // Note that we've already released it
                Locked = false;

                // Fire the change of data handler
                DataChanged(Data.Item.GetType());
            }

            ReportModelChanges = true; // Continue reporting changes

            if (Locked)                // Release the lock if we haven't already
            {
                Monitor.Exit(Lock);
            }
        }
Exemple #3
0
        // Initialise the database model from the server
        public static Tuple <User, Room> Initialise(Connection Server, ConnectMessage Msg)
        {
            try
            {
                // Thread safe
                Monitor.Enter(Lock);

                // Reset the signal that's set when the data's received
                if (InitialisedEvent == null)
                {
                    InitialisedEvent = new ManualResetEvent(false);
                }
                InitialisedEvent.Reset();

                // Reset the signal that's set when the user information's received
                if (UserEvent == null)
                {
                    UserEvent = new ManualResetEvent(false);
                }
                UserEvent.Reset();

                // Set the current server
                DataRepository.Server = Server;

                // Hook up network events
                Server.MessageReceived += MessageReceived;
                Server.Disconnect      += Disconnected;

                // Hook up data changed events
                _Bookings.CollectionChanged    += Data_CollectionChanged;
                _Departments.CollectionChanged += Data_CollectionChanged;
                _Rooms.CollectionChanged       += Data_CollectionChanged;
                _Users.CollectionChanged       += Data_CollectionChanged;
                _Subjects.CollectionChanged    += Data_CollectionChanged;
                _Periods.CollectionChanged     += Data_CollectionChanged;
                _Classes.CollectionChanged     += Data_CollectionChanged;

                // Send the connection message
                Server.Send(Msg);
            }
            catch
            {
                return(null);
            }
            finally
            {
                // Release the lock
                Monitor.Exit(Lock);
            }

            try
            {
                // Wait for both signals to fire, signalling completion
                InitialisedEvent.WaitOne();
                UserEvent.WaitOne();
            }
            catch
            {
                // Disconnected during initialise
                return(null);
            }

            // Return the User and their Room (grouped together for easy return value)
            return(new Tuple <User, Room>(CurrentUser, CurrentRoom));
        }