예제 #1
0
        /// <summary>
        /// Get the newest copy of the screen buffer once, for use in all calculations for a while.
        /// This was added when telnet clients were added.  The execution cost of obtaining a buffer snapshot
        /// from the ScreenBuffer class is non-trivial, and therefore shouldn't be done over and over
        /// for each telnet client that needs it within the span of a short time.  This gets it
        /// once for all of them to borrow.  All calls will re-use this copy for a while,
        /// until the next terminal refresh (1/20th of a second, at the moment).
        /// </summary>
        void GetNewestBuffer()
        {
            DateTime newTime = DateTime.Now;

            // Throttle it back so the faster Update() rates don't cause pointlessly repeated work:
            // Needs to be no faster than the fastest theoretical typist or script might change the view.
            if (newTime > lastBufferGet + TimeSpan.FromMilliseconds(50)) // = 1/20th second.
            {
                mostRecentScreen = new ScreenSnapShot(shared.Screen);
                lastBufferGet    = newTime;
            }
        }
예제 #2
0
        //Printing
        public void GetNewestBuffer()
        {
            DateTime newTime = DateTime.Now;

            // Throttle it back so the faster Update() rates don't cause pointlessly repeated work:
            // Needs to be no faster than the fastest theoretical typist or script might change the view.
            if (newTime > lastBufferGet + TimeSpan.FromMilliseconds(50)) // = 1/20th second.
            {
                mostRecentScreen = new ScreenSnapShot(processor_shares[current_processor_id].Screen);
                lastBufferGet = newTime;
            }
        }
예제 #3
0
 void GetNewestBuffer()
 {
     mostRecentScreen = new ScreenSnapShot(processor_shares[current_processor_id].Screen);
 }
예제 #4
0
        /// <summary>
        /// Get a list of the operations that would make a terminal window look like this snapshot
        /// if you assume that beforehand it looked like the older snapshot you pass in.
        /// </summary>
        /// <param name="older">the older snapshot of a screen to diff from</param>
        /// <returns>the string that if output in order, will give you the desired changes</returns>
        public string DiffFrom(IScreenSnapShot older)
        {
            StringBuilder output = new StringBuilder();
            
            int verticalScroll = TopRow - older.TopRow;
            int trackCursorColumn = older.CursorColumn; // track the movements that will occur as the outputs happen.
            int trackCursorRow = older.CursorRow; // track the movements that will occur as the outputs happen.

            // First, output the command to make the terminal scroll to match:
            if (verticalScroll > 0) // scrolling text up (eyeballs panning down)
                output.Append(new String((char)UnicodeCommand.SCROLLSCREENUPONE, verticalScroll)); // A run of scrollup chars
            else if (verticalScroll < 0) // scrolling text down (eyeballs panning up)
                output.Append(new String((char)UnicodeCommand.SCROLLSCREENDOWNONE, -verticalScroll)); // A run of scrolldown chars

            // Check each row:
            for (int newRowNum = 0 ; newRowNum < RowCount ; ++newRowNum)
            {
                // Account for the diff due to the scrolling:
                int oldRowNum = newRowNum + verticalScroll;

                IScreenBufferLine newRow = Buffer[newRowNum];
                bool oldRowExists = (oldRowNum >= 0 && oldRowNum < older.Buffer.Count);
                IScreenBufferLine olderRow = oldRowExists ? older.Buffer[oldRowNum] : new ScreenBufferLine(0);
                
                // if new row is an empty dummy, then pad it out so it gets properly diffed against the old row:
                if (newRow.Length == 0)
                    newRow = new ScreenBufferLine(olderRow.Length);
                // If the old row is a dummy pad or if the new row is newer than the old row, then it needs checking for diffs:
                if (olderRow.Length == 0 || newRow.LastChangeTick > olderRow.LastChangeTick)
                {
                    List<DiffChunk> diffs = new List<DiffChunk>();
                    
                    for (int newCol = 0 ; newCol < newRow.Length ; ++newCol)
                    {
                        // Check if they differ, but in a way that treats ' ' and 0x00 as identical, and treats a shorter
                        // old row as if it has been padded with spaces:
                        bool oldRowTooShort = newCol >= olderRow.Length;
                        char newChar = (newRow[newCol] == '\0' ? ' ' : newRow[newCol]);
                        char oldChar = (oldRowTooShort ? ' ' : (olderRow[newCol] == '\0' ? ' ' : olderRow[newCol]));
                        if (newChar != oldChar)
                        {
                            // Start a new diff chunk if there isn't one yet, or the diff is a long enough distance from the existing one:
                            if (diffs.Count == 0 || diffs[diffs.Count-1].EndCol < newCol - JOIN_DIFF_DIST)
                            {
                                DiffChunk newChunk = new DiffChunk
                                {
                                    StartCol = newCol, 
                                    EndCol = newCol
                                };
                                diffs.Add(newChunk);
                            }
                            else // stretch the existing diff chunk to here.
                            {
                                diffs[diffs.Count-1].EndCol = newCol;
                            }
                        }
                    }
                    
                    string newRowText = newRow.ToString();

                    foreach (DiffChunk diff in diffs)
                    {
                        /* comment-out -----------------
                        // If we're lucky enough that the current cursor happens to be right where we need it to
                        // be, some of these are more efficient.  Else it does TELEPORTCURSOR's:
                        
                        // Just one char removed to the left of current cursor pos - do a backspace instead of the ugly work:
                        if (trackCursorRow == newRowNum && (diff.EndCol == trackCursorColumn - 1 && diff.StartCol == diff.EndCol))
                        {
                            output.Append(String.Format("{0}{1}{2}", (char)0x08, newRowText.Substring(diff.StartCol,1), (char)0x08));
                            trackCursorColumn = diff.EndCol;
                            trackCursorRow = newRowNum;
                        }
                        else
                        {
                        --------------------------- */
                            // If the change starts right where the cursor happens to be (i.e. when typing, one char
                            // at current cursor position will typically be the only diff from one update to the next),
                            // then don't bother moving the cursor first, else move it to the new pos:
                            string moveString;
                            if (trackCursorRow == newRowNum && diff.StartCol == trackCursorColumn)
                                moveString = "";
                            else
                                moveString = String.Format("{0}{1}{2}",
                                                           (char)UnicodeCommand.TELEPORTCURSOR,
                                                           (char)diff.StartCol,
                                                           (char)newRowNum);
                            
                            // content = the bit of string to print at this location, with nulls made into spaces so the 
                            // telnet terminal will print correctly.
                            string content = newRowText.Substring(diff.StartCol, diff.EndCol - diff.StartCol + 1).Replace('\0',' ');

                            output.Append(String.Format("{0}{1}", moveString, content));
 
                            trackCursorColumn = diff.EndCol+1;
                            trackCursorRow = newRowNum;
                        /* comment-out -----------------
                        }
                        --------------------------- */
                    }
                    
                }
                    
            }
                    
            // Now set the cursor back to the right spot one more time, unless it's already there:
            if (trackCursorRow != CursorRow || trackCursorColumn != CursorColumn)
            {
                output.Append(String.Format("{0}{1}{2}",
                                            (char)UnicodeCommand.TELEPORTCURSOR,
                                            (char)CursorColumn,
                                            (char)CursorRow));
            }
            return output.ToString();
        }
예제 #5
0
        /// <summary>
        /// Get a list of the operations that would make a terminal window look like this snapshot
        /// if you assume that beforehand it looked like the older snapshot you pass in.
        /// </summary>
        /// <param name="older">the older snapshot of a screen to diff from</param>
        /// <returns>the string that if output in order, will give you the desired changes</returns>
        public string DiffFrom(IScreenSnapShot older)
        {
            StringBuilder output = new StringBuilder();

            int verticalScroll    = TopRow - older.TopRow;
            int trackCursorColumn = older.CursorColumn; // track the movements that will occur as the outputs happen.
            int trackCursorRow    = older.CursorRow;    // track the movements that will occur as the outputs happen.

            // First, output the command to make the terminal scroll to match:
            if (verticalScroll > 0)                                                                   // scrolling text up (eyeballs panning down)
            {
                output.Append(new String((char)UnicodeCommand.SCROLLSCREENUPONE, verticalScroll));    // A run of scrollup chars
            }
            else if (verticalScroll < 0)                                                              // scrolling text down (eyeballs panning up)
            {
                output.Append(new String((char)UnicodeCommand.SCROLLSCREENDOWNONE, -verticalScroll)); // A run of scrolldown chars
            }
            // Check each row:
            for (int newRowNum = 0; newRowNum < RowCount; ++newRowNum)
            {
                // Account for the diff due to the scrolling:
                int oldRowNum = newRowNum + verticalScroll;

                IScreenBufferLine newRow   = Buffer[newRowNum];
                bool oldRowExists          = (oldRowNum >= 0 && oldRowNum < older.Buffer.Count);
                IScreenBufferLine olderRow = oldRowExists ? older.Buffer[oldRowNum] : new ScreenBufferLine(0);

                // if new row is an empty dummy, then pad it out so it gets properly diffed against the old row:
                if (newRow.Length == 0)
                {
                    newRow = new ScreenBufferLine(olderRow.Length);
                }
                // If the old row is a dummy pad or if the new row is newer than the old row, then it needs checking for diffs:
                if (olderRow.Length == 0 || newRow.LastChangeTick > olderRow.LastChangeTick)
                {
                    List <DiffChunk> diffs = new List <DiffChunk>();

                    for (int newCol = 0; newCol < newRow.Length; ++newCol)
                    {
                        // Check if they differ, but in a way that treats ' ' and 0x00 as identical, and treats a shorter
                        // old row as if it has been padded with spaces:
                        bool oldRowTooShort = newCol >= olderRow.Length;
                        char newChar        = (newRow[newCol] == '\0' ? ' ' : newRow[newCol]);
                        char oldChar        = (oldRowTooShort ? ' ' : (olderRow[newCol] == '\0' ? ' ' : olderRow[newCol]));
                        if (newChar != oldChar)
                        {
                            // Start a new diff chunk if there isn't one yet, or the diff is a long enough distance from the existing one:
                            if (diffs.Count == 0 || diffs[diffs.Count - 1].EndCol < newCol - JOIN_DIFF_DIST)
                            {
                                DiffChunk newChunk = new DiffChunk
                                {
                                    StartCol = newCol,
                                    EndCol   = newCol
                                };
                                diffs.Add(newChunk);
                            }
                            else // stretch the existing diff chunk to here.
                            {
                                diffs[diffs.Count - 1].EndCol = newCol;
                            }
                        }
                    }

                    string newRowText = newRow.ToString();

                    foreach (DiffChunk diff in diffs)
                    {
                        /* comment-out -----------------
                         * // If we're lucky enough that the current cursor happens to be right where we need it to
                         * // be, some of these are more efficient.  Else it does TELEPORTCURSOR's:
                         *
                         * // Just one char removed to the left of current cursor pos - do a backspace instead of the ugly work:
                         * if (trackCursorRow == newRowNum && (diff.EndCol == trackCursorColumn - 1 && diff.StartCol == diff.EndCol))
                         * {
                         *  output.Append(String.Format("{0}{1}{2}", (char)0x08, newRowText.Substring(diff.StartCol,1), (char)0x08));
                         *  trackCursorColumn = diff.EndCol;
                         *  trackCursorRow = newRowNum;
                         * }
                         * else
                         * {
                         * --------------------------- */
                        // If the change starts right where the cursor happens to be (i.e. when typing, one char
                        // at current cursor position will typically be the only diff from one update to the next),
                        // then don't bother moving the cursor first, else move it to the new pos:
                        string moveString;
                        if (trackCursorRow == newRowNum && diff.StartCol == trackCursorColumn)
                        {
                            moveString = "";
                        }
                        else
                        {
                            moveString = String.Format("{0}{1}{2}",
                                                       (char)UnicodeCommand.TELEPORTCURSOR,
                                                       (char)diff.StartCol,
                                                       (char)newRowNum);
                        }

                        // content = the bit of string to print at this location, with nulls made into spaces so the
                        // telnet terminal will print correctly.
                        string content = newRowText.Substring(diff.StartCol, diff.EndCol - diff.StartCol + 1).Replace('\0', ' ');

                        output.Append(String.Format("{0}{1}", moveString, content));

                        trackCursorColumn = diff.EndCol + 1;
                        trackCursorRow    = newRowNum;

                        /* comment-out -----------------
                         * }
                         * --------------------------- */
                    }
                }
            }

            // Now set the cursor back to the right spot one more time, unless it's already there:
            if (trackCursorRow != CursorRow || trackCursorColumn != CursorColumn)
            {
                output.Append(String.Format("{0}{1}{2}",
                                            (char)UnicodeCommand.TELEPORTCURSOR,
                                            (char)CursorColumn,
                                            (char)CursorRow));
            }
            return(output.ToString());
        }