/// <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; } }
//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; } }
void GetNewestBuffer() { mostRecentScreen = new ScreenSnapShot(processor_shares[current_processor_id].Screen); }
/// <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(); }
/// <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()); }