122 lines
2.9 KiB
Dart
122 lines
2.9 KiB
Dart
|
|
// 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();
|
||
|
|
}
|