Browse Source

performance tweak

xuty 4 years ago
parent
commit
cc802c339b
4 changed files with 71 additions and 81 deletions
  1. 13 14
      lib/terminal/ansi.dart
  2. 37 34
      lib/terminal/csi.dart
  3. 7 9
      lib/terminal/osc.dart
  4. 14 24
      lib/terminal/terminal.dart

+ 13 - 14
lib/terminal/ansi.dart

@@ -1,14 +1,13 @@
-import 'dart:async';
+import 'dart:collection';
 
-import 'package:async/async.dart';
 import 'package:xterm/terminal/csi.dart';
 import 'package:xterm/terminal/osc.dart';
 import 'package:xterm/terminal/terminal.dart';
 
-typedef AnsiHandler = FutureOr<void> Function(StreamQueue<int>, Terminal);
+typedef AnsiHandler = void Function(Queue<int>, Terminal);
 
-Future<void> ansiHandler(StreamQueue<int> queue, Terminal terminal) async {
-  final charAfterEsc = String.fromCharCode(await queue.next);
+void ansiHandler(Queue<int> queue, Terminal terminal) {
+  final charAfterEsc = String.fromCharCode(queue.removeFirst());
 
   final handler = _ansiHandlers[charAfterEsc];
   if (handler != null) {
@@ -47,38 +46,38 @@ AnsiHandler _voidHandler(int sequenceLength) {
   };
 }
 
-void _unsupportedHandler(StreamQueue<int> queue, Terminal terminal) async {
+void _unsupportedHandler(Queue<int> queue, Terminal terminal) async {
   // print('unimplemented ansi sequence.');
 }
 
-void _ansiSaveCursorHandler(StreamQueue<int> queue, Terminal terminal) {
+void _ansiSaveCursorHandler(Queue<int> queue, Terminal terminal) {
   terminal.buffer.saveCursor();
 }
 
-void _ansiRestoreCursorHandler(StreamQueue<int> queue, Terminal terminal) {
+void _ansiRestoreCursorHandler(Queue<int> queue, Terminal terminal) {
   terminal.buffer.restoreCursor();
 }
 
-void _ansiIndexHandler(StreamQueue<int> queue, Terminal terminal) {
+void _ansiIndexHandler(Queue<int> queue, Terminal terminal) {
   terminal.buffer.index();
 }
 
-void _ansiReverseIndexHandler(StreamQueue<int> queue, Terminal terminal) {
+void _ansiReverseIndexHandler(Queue<int> queue, Terminal terminal) {
   terminal.buffer.reverseIndex();
 }
 
 AnsiHandler _scsHandler(int which) {
-  return (StreamQueue<int> queue, Terminal terminal) async {
-    final name = String.fromCharCode(await queue.next);
+  return (Queue<int> queue, Terminal terminal) {
+    final name = String.fromCharCode(queue.removeFirst());
     terminal.buffer.charset.designate(which, name);
   };
 }
 
-void _ansiNextLineHandler(StreamQueue<int> queue, Terminal terminal) {
+void _ansiNextLineHandler(Queue<int> queue, Terminal terminal) {
   terminal.buffer.newLine();
   terminal.buffer.setCursorX(0);
 }
 
-void _ansiTabSetHandler(StreamQueue<int> queue, Terminal terminal) {
+void _ansiTabSetHandler(Queue<int> queue, Terminal terminal) {
   terminal.tabSetAtCursor();
 }

+ 37 - 34
lib/terminal/csi.dart

@@ -1,38 +1,39 @@
-import 'package:async/async.dart';
+import 'dart:collection';
+
 import 'package:xterm/terminal/modes.dart';
 import 'package:xterm/terminal/sgr.dart';
 import 'package:xterm/terminal/terminal.dart';
 
 typedef CsiSequenceHandler = void Function(CSI, Terminal);
 
-final _csiHandlers = <String, CsiSequenceHandler>{
-  'c': csiSendDeviceAttributesHandler,
-  'd': csiLinePositionAbsolute,
-  'f': csiCursorPositionHandler,
-  'g': csiTabClearHandler,
-  'h': csiModeHandler,
-  'l': csiModeHandler,
-  'm': sgrHandler,
-  'n': csiDeviceStatusReportHandler,
-  'r': csiSetMarginsHandler,
-  't': csiWindowManipulation,
-  'A': csiCursorUpHandler,
-  'B': csiCursorDownHandler,
-  'C': csiCursorForwardHandler,
-  'D': csiCursorBackwardHandler,
-  'E': csiCursorNextLineHandler,
-  'F': csiCursorPrecedingLineHandler,
-  'G': csiCursorHorizontalAbsoluteHandler,
-  'H': csiCursorPositionHandler,
-  'J': csiEraseInDisplayHandler,
-  'K': csiEraseInLineHandler,
-  'L': csiInsertLinesHandler,
-  'M': csiDeleteLinesHandler,
-  'P': csiDeleteHandler,
-  'S': csiScrollUpHandler,
-  'T': csiScrollDownHandler,
-  'X': csiEraseCharactersHandler,
-  '@': csiInsertBlankCharactersHandler,
+final _csiHandlers = <int, CsiSequenceHandler>{
+  'c'.codeUnitAt(0): csiSendDeviceAttributesHandler,
+  'd'.codeUnitAt(0): csiLinePositionAbsolute,
+  'f'.codeUnitAt(0): csiCursorPositionHandler,
+  'g'.codeUnitAt(0): csiTabClearHandler,
+  'h'.codeUnitAt(0): csiModeHandler,
+  'l'.codeUnitAt(0): csiModeHandler,
+  'm'.codeUnitAt(0): sgrHandler,
+  'n'.codeUnitAt(0): csiDeviceStatusReportHandler,
+  'r'.codeUnitAt(0): csiSetMarginsHandler,
+  't'.codeUnitAt(0): csiWindowManipulation,
+  'A'.codeUnitAt(0): csiCursorUpHandler,
+  'B'.codeUnitAt(0): csiCursorDownHandler,
+  'C'.codeUnitAt(0): csiCursorForwardHandler,
+  'D'.codeUnitAt(0): csiCursorBackwardHandler,
+  'E'.codeUnitAt(0): csiCursorNextLineHandler,
+  'F'.codeUnitAt(0): csiCursorPrecedingLineHandler,
+  'G'.codeUnitAt(0): csiCursorHorizontalAbsoluteHandler,
+  'H'.codeUnitAt(0): csiCursorPositionHandler,
+  'J'.codeUnitAt(0): csiEraseInDisplayHandler,
+  'K'.codeUnitAt(0): csiEraseInLineHandler,
+  'L'.codeUnitAt(0): csiInsertLinesHandler,
+  'M'.codeUnitAt(0): csiDeleteLinesHandler,
+  'P'.codeUnitAt(0): csiDeleteHandler,
+  'S'.codeUnitAt(0): csiScrollUpHandler,
+  'T'.codeUnitAt(0): csiScrollDownHandler,
+  'X'.codeUnitAt(0): csiEraseCharactersHandler,
+  '@'.codeUnitAt(0): csiInsertBlankCharactersHandler,
 };
 
 class CSI {
@@ -52,12 +53,14 @@ class CSI {
   }
 }
 
-Future<CSI> _parseCsi(StreamQueue<int> queue) async {
+CSI _parseCsi(Queue<int> queue) {
   final paramBuffer = StringBuffer();
   final intermediates = <int>[];
 
   while (true) {
-    final char = await queue.next;
+    // TODO: handle special case when queue is empty as this time.
+
+    final char = queue.removeFirst();
 
     if (char >= 0x30 && char <= 0x3F) {
       paramBuffer.writeCharCode(char);
@@ -83,12 +86,12 @@ Future<CSI> _parseCsi(StreamQueue<int> queue) async {
   }
 }
 
-Future<void> csiHandler(StreamQueue<int> queue, Terminal terminal) async {
-  final csi = await _parseCsi(queue);
+void csiHandler(Queue<int> queue, Terminal terminal) {
+  final csi = _parseCsi(queue);
 
   terminal.debug.onCsi(csi);
 
-  final handler = _csiHandlers[String.fromCharCode(csi.finalByte)];
+  final handler = _csiHandlers[csi.finalByte];
 
   if (handler != null) {
     handler(csi, terminal);

+ 7 - 9
lib/terminal/osc.dart

@@ -1,4 +1,5 @@
-import 'package:async/async.dart';
+import 'dart:collection';
+
 import 'package:xterm/terminal/terminal.dart';
 
 // bool _isOscTerminator(int codePoint) {
@@ -7,15 +8,12 @@ import 'package:xterm/terminal/terminal.dart';
 //   return terminator.contains(codePoint);
 // }
 
-Future<List<String>> _parseOsc(
-  StreamQueue<int> queue,
-  Set<int> terminators,
-) async {
+List<String> _parseOsc(Queue<int> queue, Set<int> terminators) {
   final params = <String>[];
   final param = StringBuffer();
 
-  while (true) {
-    final char = await queue.next;
+  while (queue.isNotEmpty) {
+    final char = queue.removeFirst();
 
     if (terminators.contains(char)) {
       params.add(param.toString());
@@ -35,8 +33,8 @@ Future<List<String>> _parseOsc(
   return params;
 }
 
-Future<void> oscHandler(StreamQueue<int> queue, Terminal terminal) async {
-  final params = await _parseOsc(queue, terminal.platform.oscTerminators);
+void oscHandler(Queue<int> queue, Terminal terminal) {
+  final params = _parseOsc(queue, terminal.platform.oscTerminators);
   terminal.debug.onOsc(params);
 
   if (params.isEmpty) {

+ 14 - 24
lib/terminal/terminal.dart

@@ -1,7 +1,6 @@
-import 'dart:async';
+import 'dart:collection';
 import 'dart:math' show max, min;
 
-import 'package:async/async.dart';
 import 'package:xterm/buffer/buffer.dart';
 import 'package:xterm/buffer/buffer_line.dart';
 import 'package:xterm/buffer/cell_attr.dart';
@@ -41,12 +40,8 @@ class Terminal with Observable {
     _altBuffer = Buffer(this);
     _buffer = _mainBuffer;
 
-    _input = StreamController<int>();
-    _queue = StreamQueue<int>(_input.stream);
-
     tabs.reset();
 
-    _processInput();
     // _buffer.write('this is magic!');
   }
 
@@ -99,8 +94,8 @@ class Terminal with Observable {
   Buffer _mainBuffer;
   Buffer _altBuffer;
 
-  StreamController<int> _input;
-  StreamQueue<int> _queue;
+  /// Queue of input characters. addLast() to add, removeFirst() to consume.
+  final _queue = Queue<int>();
 
   bool _slowMotion = false;
   bool get slowMotion => _slowMotion;
@@ -122,11 +117,6 @@ class Terminal with Observable {
   final IconChangeHandler onIconChange;
   final PlatformBehavior platform;
 
-  void close() {
-    _input.close();
-    _queue.cancel();
-  }
-
   Buffer get buffer {
     return _buffer;
   }
@@ -136,30 +126,30 @@ class Terminal with Observable {
   int get scrollOffset => buffer.scrollOffsetFromBottom;
 
   void write(String text) async {
-    for (var char in text.runes) {
-      writeChar(char);
-    }
+    _queue.addAll(text.runes);
+    _processInput();
   }
 
   void writeChar(int codePoint) {
-    _input.add(codePoint);
+    _queue.addLast(codePoint);
+    _processInput();
   }
 
   List<BufferLine> getVisibleLines() {
     return _buffer.getVisibleLines();
   }
 
-  void _processInput() async {
-    while (true) {
-      if (_slowMotion) {
-        await Future.delayed(Duration(milliseconds: 100));
-      }
+  void _processInput() {
+    while (_queue.isNotEmpty) {
+      // if (_slowMotion) {
+      //   await Future.delayed(Duration(milliseconds: 100));
+      // }
 
       const esc = 0x1b;
-      final char = await _queue.next;
+      final char = _queue.removeFirst();
 
       if (char == esc) {
-        await ansiHandler(_queue, this);
+        ansiHandler(_queue, this);
         refresh();
         continue;
       }