Version 2.3.0 (#102)

* Version 2.3.0

 - Update SDK requirement to Dart 3.2.

 - Add a ScoreEmitterV2 interface, that the ScoreEmitter interface
   will be changed to in the next major release, a breaking change.

 - Add `PerfBenchmarkBase` class which runs the 'perf stat' command from
   linux-tools on a benchmark and reports metrics from the hardware
   performance counters and the benchmark iteration count.

The breaking change to ScoreEmitter in 2.2.3 is reverted, and version
2.2.3 is retracted from pub.

* Update version number

* Improve documentation
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ec69baf..e1836bc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,9 @@
-## 2.2.3
+## 2.3.0
 
 - Require Dart 3.2.
+- Add ScoreEmitterV2 interface, documented with the intention to change
+ScoreEmitter interface to match it in the next major release,
+ a breaking change.
 - Add `PerfBenchmarkBase` class which runs the 'perf stat' command from
 linux-tools on a benchmark and reports metrics from the hardware
 performance counters and the iteration count, as well as the run time
diff --git a/lib/src/async_benchmark_base.dart b/lib/src/async_benchmark_base.dart
index b342a3d..1472ee7 100644
--- a/lib/src/async_benchmark_base.dart
+++ b/lib/src/async_benchmark_base.dart
@@ -64,6 +64,6 @@
 
   /// Run the benchmark and report results on the [emitter].
   Future<void> report() async {
-    emitter.emit(name, await measure(), unit: 'us.');
+    emitter.emit(name, await measure());
   }
 }
diff --git a/lib/src/benchmark_base.dart b/lib/src/benchmark_base.dart
index 51a89bb..bc874f5 100644
--- a/lib/src/benchmark_base.dart
+++ b/lib/src/benchmark_base.dart
@@ -58,7 +58,7 @@
   }
 
   void report() {
-    emitter.emit(name, measure(), unit: 'us.');
+    emitter.emit(name, measure());
   }
 }
 
diff --git a/lib/src/perf_benchmark_base.dart b/lib/src/perf_benchmark_base.dart
index 3c4a5a1..1b7fb92 100644
--- a/lib/src/perf_benchmark_base.dart
+++ b/lib/src/perf_benchmark_base.dart
@@ -18,7 +18,10 @@
   late final Process perfProcess;
   late final List<String> perfProcessArgs;
 
-  PerfBenchmarkBase(super.name, {super.emitter = const PrintEmitter()});
+  PerfBenchmarkBase(super.name,
+      {ScoreEmitterV2 super.emitter = const PrintEmitterV2()});
+
+  ScoreEmitterV2 get _emitterV2 => emitter as ScoreEmitterV2;
 
   Future<void> _createFifos() async {
     perfControlFifo = '${fifoDir.path}/perf_control_fifo';
@@ -81,11 +84,11 @@
             String event && ('cycles' || 'page-faults'),
             ...
           ]) {
-        emitter.emit(name, double.parse(counter) / totalIterations,
+        _emitterV2.emit(name, double.parse(counter) / totalIterations,
             metric: metrics[event]!);
       }
     }
-    emitter.emit('$name.totalIterations', totalIterations.toDouble(),
+    _emitterV2.emit('$name.totalIterations', totalIterations.toDouble(),
         metric: 'Count');
   }
 
@@ -118,7 +121,7 @@
   }
 
   Future<void> reportPerf() async {
-    emitter.emit(name, await measurePerf(), unit: 'us.');
+    _emitterV2.emit(name, await measurePerf(), unit: 'us.');
   }
 
   void _waitForAck() {
diff --git a/lib/src/score_emitter.dart b/lib/src/score_emitter.dart
index 43ea7aa..4407118 100644
--- a/lib/src/score_emitter.dart
+++ b/lib/src/score_emitter.dart
@@ -3,14 +3,34 @@
 // BSD-style license that can be found in the LICENSE file.
 
 abstract class ScoreEmitter {
-  void emit(String testName, double value,
-      {String metric = 'RunTime', String unit});
+  void emit(String testName, double value);
 }
 
 class PrintEmitter implements ScoreEmitter {
   const PrintEmitter();
 
   @override
+  void emit(String testName, double value) {
+    print('$testName(RunTime): $value us.');
+  }
+}
+
+/// New interface for [ScoreEmitter]. [ScoreEmitter] will be changed to
+/// this interface in the next major version release, and this class will
+/// be deprecated and removed.  That release will be a breaking change.
+abstract class ScoreEmitterV2 implements ScoreEmitter {
+  @override
+  void emit(String testName, double value,
+      {String metric = 'RunTime', String unit});
+}
+
+/// New implementation of [PrintEmitter] implementing the [ScoreEmitterV2]
+/// interface.  [PrintEmitter] will be changed to this implementation in the
+/// next major version release.
+class PrintEmitterV2 implements ScoreEmitterV2 {
+  const PrintEmitterV2();
+
+  @override
   void emit(String testName, double value,
       {String metric = 'RunTime', String unit = ''}) {
     print(['$testName($metric):', value, if (unit.isNotEmpty) unit].join(' '));
diff --git a/pubspec.yaml b/pubspec.yaml
index 465d274..76298d4 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: benchmark_harness
-version: 2.2.3
+version: 2.3.0
 description: The official Dart project benchmark harness.
 repository: https://github.com/dart-lang/benchmark_harness
 
diff --git a/test/result_emitter_test.dart b/test/result_emitter_test.dart
index bfbce4e..e2cd1ea 100644
--- a/test/result_emitter_test.dart
+++ b/test/result_emitter_test.dart
@@ -13,8 +13,7 @@
   int emitCount = 0;
 
   @override
-  void emit(String name, double value,
-      {String metric = 'RunTime', String unit = ''}) {
+  void emit(String name, double value) {
     emitCount++;
   }
 }