Files
BadNote/lib/diagnostics/pen_event_ring.dart

122 lines
2.9 KiB
Dart
Raw Permalink Normal View History

// Rolling ring of recent pen / arbiter events for diagnostic export.
class PenEventRecord {
PenEventRecord({
required this.at,
required this.kind,
required this.pointerId,
this.pressure,
this.tiltX,
this.tiltY,
this.barrel = false,
this.eraser = false,
this.inverted = false,
this.decision,
this.note,
});
final DateTime at;
final String kind; // down|move|up|hw|arbiter
final int pointerId;
final double? pressure;
final double? tiltX;
final double? tiltY;
final bool barrel;
final bool eraser;
final bool inverted;
final String? decision; // draw|pan|reject
final String? note;
Map<String, Object?> toJson() => {
'at': at.toIso8601String(),
'kind': kind,
'pointerId': pointerId,
if (pressure != null) 'pressure': pressure,
if (tiltX != null) 'tiltX': tiltX,
if (tiltY != null) 'tiltY': tiltY,
'barrel': barrel,
'eraser': eraser,
'inverted': inverted,
if (decision != null) 'decision': decision,
if (note != null) 'note': note,
};
}
class PenEventRing {
PenEventRing._();
static final PenEventRing instance = PenEventRing._();
static const int capacity = 2000;
final List<PenEventRecord> _events = <PenEventRecord>[];
void add(PenEventRecord event) {
_events.add(event);
if (_events.length > capacity) {
_events.removeRange(0, _events.length - capacity);
}
}
void recordPointer({
required String kind,
required int pointerId,
required String deviceKind,
double? pressure,
String? decision,
String? note,
}) {
add(PenEventRecord(
at: DateTime.now(),
kind: kind,
pointerId: pointerId,
pressure: pressure,
decision: decision,
note: note ?? deviceKind,
));
}
void recordHardware({
required bool barrel,
required bool eraser,
required bool inverted,
required double tiltX,
required double tiltY,
}) {
add(PenEventRecord(
at: DateTime.now(),
kind: 'hw',
pointerId: -1,
barrel: barrel,
eraser: eraser,
inverted: inverted,
tiltX: tiltX,
tiltY: tiltY,
));
}
void recordArbiter({
required int activeCount,
required String deviceKind,
required bool draw,
required bool fingerDrawing,
}) {
add(PenEventRecord(
at: DateTime.now(),
kind: 'arbiter',
pointerId: -1,
decision: draw ? 'draw' : 'pan',
note: 'count=$activeCount kind=$deviceKind finger=$fingerDrawing',
));
}
List<PenEventRecord> recent({Duration? window}) {
if (window == null) return List.unmodifiable(_events);
final cut = DateTime.now().subtract(window);
return _events.where((e) => e.at.isAfter(cut)).toList(growable: false);
}
List<Map<String, Object?>> toJsonList({Duration? window}) =>
recent(window: window).map((e) => e.toJson()).toList(growable: false);
void clear() => _events.clear();
}