浏览代码

item factory

melon.yin 2 年之前
父节点
当前提交
0b844993ba

+ 2 - 2
lib/interfaces/process/items/item_metas.dart

@@ -18,7 +18,7 @@ class ItemMeta {
   String? multiMethod;
 
   /// 计算输出元信息
-  ItemOutputMeta outputMeta;
+  List<ItemOutputMeta> outputs;
 
   /// 子项元信息集合
   List<ItemMeta> childItems;
@@ -27,7 +27,7 @@ class ItemMeta {
     this.name,
     this.measureType, {
     required this.description,
-    required this.outputMeta,
+    required this.outputs,
     this.briefAnnotation = '',
     this.multiMethod,
     this.childItems = const [],

+ 1 - 1
lib/interfaces/process/items/measure_terms.dart → lib/interfaces/process/items/types.dart

@@ -1,6 +1,6 @@
 // ignore_for_file: constant_identifier_names
 
-class MeasureTerms {
+class MeasureTypes {
   /* Tissue */
 
   /// 深度

+ 5 - 5
lib/measure_page_test.dart

@@ -2,7 +2,7 @@ import 'dart:typed_data';
 
 import 'package:fis_jsonrpc/rpc.dart';
 import 'package:fis_measure/interfaces/enums/annotation.dart';
-import 'package:fis_measure/interfaces/process/items/measure_terms.dart';
+import 'package:fis_measure/interfaces/process/items/types.dart';
 import 'package:fis_measure/interfaces/process/player/play_controller.dart';
 import 'package:fis_measure/interfaces/process/standard_line/calibration.dart';
 import 'package:fis_measure/interfaces/process/workspace/application.dart';
@@ -301,10 +301,10 @@ class _MeasureLeftBoard extends StatefulWidget {
 class _MeasureLeftBoardState extends State<_MeasureLeftBoard> {
   // ignore: non_constant_identifier_names
   static final C_SUPPORTED_ITEMS = <String>[
-    MeasureTerms.Distance,
-    MeasureTerms.Perimeter,
-    MeasureTerms.Area,
-    MeasureTerms.Depth,
+    MeasureTypes.Distance,
+    MeasureTypes.Perimeter,
+    MeasureTypes.Area,
+    MeasureTypes.Depth,
   ];
 
   final scrollController = ScrollController();

+ 2 - 2
lib/process/calcuators/area.dart

@@ -1,7 +1,7 @@
 import 'dart:math' as math;
 import 'package:fis_measure/interfaces/date_types/point.dart';
 import 'package:fis_measure/interfaces/process/calculators/output.dart';
-import 'package:fis_measure/interfaces/process/items/measure_terms.dart';
+import 'package:fis_measure/interfaces/process/items/types.dart';
 import 'package:fis_measure/process/primitives/ellipse.dart';
 import 'package:vid/us/vid_us_unit.dart';
 
@@ -21,7 +21,7 @@ class PolyLineAreaCal extends Calculator<PolyLine, double> {
         ref.feature!.innerPoints.map((e) => viewport.convert(e)).toList();
 
     double value = clacArea(points);
-    final outputItem = createOutput(MeasureTerms.Area, value, VidUsUnit.cm2);
+    final outputItem = createOutput(MeasureTypes.Area, value, VidUsUnit.cm2);
     final description = "${ref.description}: ${roundDouble(value)}cm²";
     outputItem.updateDescription(description: description);
     output = outputItem;

+ 3 - 3
lib/process/calcuators/depth.dart

@@ -1,6 +1,6 @@
 import 'package:fis_measure/interfaces/date_types/point.dart';
 import 'package:fis_measure/interfaces/process/calculators/output.dart';
-import 'package:fis_measure/interfaces/process/items/measure_terms.dart';
+import 'package:fis_measure/interfaces/process/items/types.dart';
 import 'package:vid/us/vid_us_unit.dart';
 
 import '../physical_coordinates/convex_tissue.dart';
@@ -20,7 +20,7 @@ class TissueDepthCal extends Calculator<Location, double> {
     final physicalPoint = viewport.physical!.convert(point);
     final depth = physicalPoint.y * viewport.region.height;
 
-    final outputItem = createOutput(MeasureTerms.Depth, depth, VidUsUnit.cm);
+    final outputItem = createOutput(MeasureTypes.Depth, depth, VidUsUnit.cm);
     final description =
         "${ref.description}: ${roundDouble(depth)}${VidUsUnit.cm.name}";
     outputItem.updateDescription(description: description);
@@ -54,7 +54,7 @@ class TissueConvexDepthCal extends Calculator<Location, double> {
 
     final double outputValue = depth < 0 ? 0 : depth;
     final outputItem =
-        createOutput(MeasureTerms.Depth, outputValue, VidUsUnit.cm);
+        createOutput(MeasureTypes.Depth, outputValue, VidUsUnit.cm);
 
     outputItem.updateDescription(description: description);
     output = outputItem;

+ 2 - 2
lib/process/calcuators/distance.dart

@@ -1,6 +1,6 @@
 import 'package:fis_measure/interfaces/date_types/point.dart';
 import 'package:fis_measure/interfaces/process/calculators/output.dart';
-import 'package:fis_measure/interfaces/process/items/measure_terms.dart';
+import 'package:fis_measure/interfaces/process/items/types.dart';
 import 'package:vid/us/vid_us_unit.dart';
 
 import '../primitives/straightline.dart';
@@ -26,7 +26,7 @@ class DistanceCal extends Calculator<StraightLine, double> {
 
     final value = (pp2 - pp1).length.abs();
     // final value =  ref.feature!.length;
-    final outputItem = createOutput(MeasureTerms.Distance, value, VidUsUnit.cm);
+    final outputItem = createOutput(MeasureTypes.Distance, value, VidUsUnit.cm);
     final description =
         "${ref.description}: ${roundDouble(value)}${VidUsUnit.cm.name}";
     outputItem.updateDescription(description: description);

+ 2 - 2
lib/process/calcuators/perimeter.dart

@@ -1,6 +1,6 @@
 import 'package:fis_measure/interfaces/date_types/point.dart';
 import 'package:fis_measure/interfaces/process/calculators/output.dart';
-import 'package:fis_measure/interfaces/process/items/measure_terms.dart';
+import 'package:fis_measure/interfaces/process/items/types.dart';
 import 'package:fis_measure/process/primitives/ellipse.dart';
 import 'package:vid/us/vid_us_unit.dart';
 
@@ -26,7 +26,7 @@ class PolyLinePerimeterCal extends Calculator<PolyLine, double> {
     // }
     double value = calcPerimeter(points, ref.feature!.isClosed, threshold);
     final outputItem =
-        createOutput(MeasureTerms.Perimeter, value, VidUsUnit.cm);
+        createOutput(MeasureTypes.Perimeter, value, VidUsUnit.cm);
     final description =
         "${ref.description}: ${roundDouble(value)}${VidUsUnit.cm.name}";
     outputItem.updateDescription(description: description);

+ 57 - 0
lib/process/items/factory.dart

@@ -0,0 +1,57 @@
+import 'package:fis_measure/interfaces/process/items/item.dart';
+import 'package:fis_measure/interfaces/process/items/item_metas.dart';
+import 'package:fis_measure/interfaces/process/items/types.dart';
+import 'package:fis_measure/process/items/item.dart';
+import 'package:fis_measure/process/primitives/straightline.dart';
+
+/// 测量项创建器
+///
+/// [meta] 测量项元信息
+///
+/// [parent] 父项
+typedef MeasureItemCreator = MeasureItem Function(
+  ItemMeta meta,
+  IMeasureItem? parent,
+);
+
+/// 测量项工厂
+class MeasureItemFactory {
+  static MeasureItemFactory? _singletonInstance;
+  static MeasureItemFactory get _singleton {
+    if (_singletonInstance == null) {
+      _singletonInstance = MeasureItemFactory();
+      _registerItemCreators();
+    }
+    return _singletonInstance!;
+  }
+
+  final _itemCreatorMap = <String, MeasureItemCreator>{};
+
+  void _register(String typeName, MeasureItemCreator creator) {
+    _itemCreatorMap[typeName] = creator;
+  }
+
+  MeasureItemCreator? _findCreator(String typeName) {
+    if (_itemCreatorMap.containsKey(typeName)) {
+      return _itemCreatorMap[typeName];
+    }
+    return null;
+  }
+
+  /// 创建测量项
+  ///
+  /// [meta] 元信息
+  ///
+  /// [parent] 父项
+  static MeasureItem? createItem(ItemMeta meta, IMeasureItem? parent) {
+    final creator = _singleton._findCreator(meta.measureType);
+    if (creator == null) return null;
+
+    final item = creator.call(meta, parent);
+    return item;
+  }
+
+  static void _registerItemCreators() {
+    _singleton._register(MeasureTypes.Distance, StraightLine.createDistance);
+  }
+}

+ 42 - 0
lib/process/items/top_item.dart

@@ -0,0 +1,42 @@
+import 'package:fis_common/event/event_type.dart';
+import 'package:fis_measure/interfaces/process/items/item.dart';
+import 'package:fis_measure/interfaces/process/items/item_metas.dart';
+import 'package:flutter/foundation.dart';
+
+import 'item.dart';
+import 'item_feature.dart';
+
+abstract class TopMeasureItem<T extends MeasureItemFeature>
+    extends MeasureItem<T> implements ITopMeasureItem {
+  final List<IMeasureItem> _childItems = [];
+  int _childIndex = 0;
+
+  TopMeasureItem(ItemMeta meta) : super(meta) {
+    workingChildChanged = FEventHandler<int>();
+  }
+
+  @override
+  List<IMeasureItem> get childItems => _childItems;
+
+  @override
+  IMeasureItem get workingChild => _childItems[_childIndex];
+
+  @override
+  late final FEventHandler<int> workingChildChanged;
+
+  @override
+  void switchChild(int index) {
+    _childIndex = index;
+  }
+
+  @protected
+  void nextChild() {
+    final count = _childItems.length;
+    for (var i = 0; i < count; i++) {
+      final child = _childItems[i];
+      if (child.measuredFeatures.isEmpty) {
+        switchChild(i);
+      }
+    }
+  }
+}

+ 5 - 5
lib/process/primitives/combos/straightline.dart → lib/process/primitives/combos/lwh_straightline.dart

@@ -3,11 +3,11 @@ import 'dart:ui';
 import 'package:fis_measure/interfaces/process/items/item.dart';
 import 'package:fis_measure/interfaces/process/items/item_metas.dart';
 import 'package:fis_measure/interfaces/process/workspace/point_info.dart';
-import 'package:fis_measure/process/items/item.dart';
 import 'package:fis_measure/process/items/item_feature.dart';
+import 'package:fis_measure/process/items/top_item.dart';
 
-class MultiStraightline extends MeasureItem<MultiStraightlineFeature> {
-  MultiStraightline(ItemMeta meta) : super(meta);
+class LWHStraightline extends TopMeasureItem<LWHStraightlineFeature> {
+  LWHStraightline(ItemMeta meta) : super(meta);
 
   @override
   bool onExecuteMouse(PointInfo args) {
@@ -22,8 +22,8 @@ class MultiStraightline extends MeasureItem<MultiStraightlineFeature> {
   }
 }
 
-class MultiStraightlineFeature extends MeasureItemFeature {
-  MultiStraightlineFeature(
+class LWHStraightlineFeature extends MeasureItemFeature {
+  LWHStraightlineFeature(
     IMeasureItem refItem,
   ) : super(refItem);
 

+ 32 - 26
lib/process/workspace/application.dart

@@ -4,7 +4,7 @@ import 'package:fis_measure/interfaces/process/annotations/annotation.dart';
 import 'package:fis_measure/interfaces/process/items/item.dart';
 import 'package:fis_measure/interfaces/process/items/item_feature.dart';
 import 'package:fis_measure/interfaces/process/items/item_metas.dart';
-import 'package:fis_measure/interfaces/process/items/measure_terms.dart';
+import 'package:fis_measure/interfaces/process/items/types.dart';
 import 'package:fis_measure/interfaces/process/visuals/visual_area.dart';
 import 'package:fis_measure/interfaces/process/visuals/visual.dart';
 import 'package:fis_measure/interfaces/process/viewports/viewport.dart';
@@ -251,59 +251,65 @@ class Application implements IApplication {
     _updateOperateType(MeasureOperateType.measure);
     activeMeasureItem?.finishOnce();
     // TODO: create from map
-    if (name == MeasureTerms.Distance) {
+    if (name == MeasureTypes.Distance) {
       activeMeasureItem = StraightLine.createDistance(
         ItemMeta(
-          MeasureTerms.Distance,
-          MeasureTerms.Distance,
-          description: MeasureTerms.Distance,
+          MeasureTypes.Distance,
+          MeasureTypes.Distance,
+          description: MeasureTypes.Distance,
           briefAnnotation: "D",
-          outputMeta:
-              ItemOutputMeta(MeasureTerms.Distance, "Distance", VidUsUnit.cm),
+          outputs: [
+            ItemOutputMeta(MeasureTypes.Distance, "Distance", VidUsUnit.cm),
+          ],
         ),
       );
       return;
     }
 
-    if (name == MeasureTerms.Perimeter) {
+    if (name == MeasureTypes.Perimeter) {
       activeMeasureItem = PolyLine.createPerimeter(
         ItemMeta(
-          MeasureTerms.Perimeter,
-          MeasureTerms.Perimeter,
-          description: MeasureTerms.Perimeter,
-          briefAnnotation: MeasureTerms.Perimeter,
-          outputMeta:
-              ItemOutputMeta(MeasureTerms.Perimeter, "Perimeter", VidUsUnit.cm),
+          MeasureTypes.Perimeter,
+          MeasureTypes.Perimeter,
+          description: MeasureTypes.Perimeter,
+          briefAnnotation: MeasureTypes.Perimeter,
+          outputs: [
+            ItemOutputMeta(MeasureTypes.Perimeter, "Perimeter", VidUsUnit.cm),
+          ],
         ),
         null,
       );
       return;
     }
-    if (name == MeasureTerms.Area) {
+    if (name == MeasureTypes.Area) {
       activeMeasureItem = PolyLine.createArea(
         ItemMeta(
-          MeasureTerms.Area,
-          MeasureTerms.Area,
-          description: MeasureTerms.Area,
-          briefAnnotation: MeasureTerms.Area,
-          outputMeta: ItemOutputMeta(MeasureTerms.Area, "Area", VidUsUnit.cm2),
+          MeasureTypes.Area,
+          MeasureTypes.Area,
+          description: MeasureTypes.Area,
+          briefAnnotation: MeasureTypes.Area,
+          outputs: [
+            ItemOutputMeta(MeasureTypes.Area, "Area", VidUsUnit.cm2),
+          ],
         ),
         null,
       );
       return;
     }
-    if (name == MeasureTerms.Depth) {
+    if (name == MeasureTypes.Depth) {
       final isProbeConvex = (currentVisualArea as TissueArea).isConvex;
       final Location Function(ItemMeta, [IMeasureItem?]) fn = isProbeConvex
           ? Location.createTissueConvexDepth
           : Location.createTissueDepth;
       activeMeasureItem = fn(
         ItemMeta(
-          MeasureTerms.Depth,
-          MeasureTerms.Depth,
-          description: MeasureTerms.Depth,
-          briefAnnotation: MeasureTerms.Depth,
-          outputMeta: ItemOutputMeta(MeasureTerms.Depth, "Depth", VidUsUnit.cm),
+          MeasureTypes.Depth,
+          MeasureTypes.Depth,
+          description: MeasureTypes.Depth,
+          briefAnnotation: MeasureTypes.Depth,
+          outputs: [
+            ItemOutputMeta(MeasureTypes.Depth, "Depth", VidUsUnit.cm),
+          ],
         ),
         null,
       );