Flutter功能未知插件hisma的探索使用
Flutter功能未知插件hisma的探索使用
介绍
hisma
是一个用于 Dart 和 Flutter 的声明式分层状态机实现。它松散地遵循了 UML 状态机规范,该规范基于 Harel 的状态图。以下是 hisma
包及其相关包的简要概述:
Package on pub.dev | GitHub | Description |
---|---|---|
hisma | repo | 核心包,用于创建分层状态机。 |
hisma_extra | repo | 提供额外类以简化 hisma 的使用。 |
hisma_console_monitor | repo | 在控制台监控状态机状态。 |
hisma_visual_monitor | repo | 将状态机状态报告给 visma 。 |
visma | repo | 可视化由 hisma_visual_monitor 报告的状态机状态。 |
hisma_flutter | repo | 将状态机转换为 Flutter 路由引擎。 |
fb_auth_hisma | repo | 使用 hisma 实现的 Firebase 认证状态机。 |
特性
功能概述
- 基础
- 状态
- OnEntry 和 OnExit 动作
- 事务
- 外部和内部转换
- minInterval 检查
- 守卫
- 优先级
- onAction 动作
- onError 动作
- 状态
- 层次结构
- 区域
- 通过层次结构连接状态机
- 入口点和入口连接器
- 出口点和出口连接器
- 历史记录
- 浅历史
- 深历史
- 监控
- 控制台监控
- 可视化监控
快速入门
您可以直接开始使用此包,无需任何先决条件。
使用方法
最小状态机声明
让我们从最小的步骤开始:创建一个只有名称定义的状态机。
final machine = StateMachine(
name: 'minimal',
initialStateId: null,
states: {},
transitions: {},
);
简单状态机
创建一个更实用的状态机:一个灯的状态机。这个典型的例子声明了一个具有两个状态(on
和 off
)的机器,用户可以通过 turnOn
和 turnOff
事件在这两个状态之间切换。
首先创建表示状态、事件和转换的枚举:
enum S { on, off }
enum E { turnOn, turnOff }
enum T { toOn, toOff }
接下来定义一个函数来创建状态机,并使用该函数创建我们的 lightMachine
:
StateMachine<S, E, T> createLightMachine({
RegionList<S, E, T>? regions,
}) =>
StateMachine<S, E, T>(
name: 'lightMachine',
events: E.values,
initialStateId: S.off,
states: {
S.off: State(
etm: {
E.turnOn: [T.toOn],
},
onEntry: Action(
description: 'Turning off.',
action: (machine, arg) async => print('OFF'),
),
),
S.on: State(
etm: {
E.turnOff: [T.toOff],
},
regions: regions,
onEntry: Action(
description: 'Turning on.',
action: (machine, arg) async => print('ON'),
),
),
},
transitions: {
T.toOn: Transition(to: S.on),
T.toOff: Transition(to: S.off),
},
);
final lightMachine = createLightMachine();
运行状态机
创建一个 play
函数来测试状态机:
Future<void> play() async {
while (true) {
await Future<void>.delayed(const Duration(seconds: 1));
await lightMachine.fire(E.turnOn);
await Future<void>.delayed(const Duration(seconds: 1));
await lightMachine.fire(E.turnOff);
}
}
在 main
函数中启动状态机并调用 play
函数:
Future<void> main() async {
StateMachine.monitorCreators = [
(machine) => VisualMonitor(machine),
];
await lightMachine.start();
play();
}
更多关于转换
外部转换
外部转换是从一个状态到另一个状态的转换。当转换发生时,相应的 onExit 和 onEntry 活动将被执行。
T.toStop: Transition(
to: S.stop,
minInterval: const Duration(seconds: 1),
guard: Guard(
description: 'If not empty.',
condition: (machine, arg) async => true,
),
priority: 10,
onAction: Action(
description: 'Closing.',
action: (machine, arg) async => print('Closing'),
),
onError: OnErrorAction(
description: 'Print error message.',
action: (machine, onErrorData) async => print(onErrorData.message),
),
),
内部转换
内部转换是在响应事件时执行某个动作,但不改变状态。
T.timedOn: InternalTransition(
onAction: Action(
description: 'Turn on in 3 sec.',
action: (machine, arg) async {
print('Initiating timer to turn on in 3 sec.');
await Future.delayed(
const Duration(seconds: 3),
() {
print('Fire timedOn.');
machine.fire(E.turnOn);
},
);
},
),
),
复合状态机 - 单个区域
构建一个简单的复合状态机,其中父状态机包含一个子状态机(区域)。
首先定义亮度状态机的状态、事件和转换:
enum S { half, full }
enum E { change }
enum T { toHalf, toFull }
定义亮度状态机:
const brightnessMachineName = 'brightnessMachine';
StateMachine<S, E, T> createBrightnessMachine({
RegionList<S, E, T>? regions,
}) =>
StateMachine<S, E, T>(
name: brightnessMachineName,
events: E.values,
initialStateId: S.half,
states: {
S.half: State(
etm: {
E.change: [T.toFull],
},
onEntry: Action(
description: 'Half light.',
action: (machine, arg) async => print('HALF'),
),
),
S.full: State(
etm: {
E.change: [T.toHalf],
},
onEntry: Action(
description: 'Full light.',
action: (machine, arg) async => print('FULL'),
),
),
},
transitions: {
T.toFull: Transition(to: S.full),
T.toHalf: Transition(to: S.half),
},
);
将亮度状态机添加到 lightMachine
的区域中:
final lightMachine = createLightMachine(
regions: [Region(machine: createBrightnessMachine())],
);
创建 play
函数来测试新的两层分层状态机:
Future<void> play() async {
while (true) {
await Future<void>.delayed(const Duration(seconds: 1));
await lightMachine.fire(E.turnOn);
for (var i = 0; i < 5; i++) {
await Future<void>.delayed(const Duration(seconds: 1));
await lightMachine.find<S, E, T>(brightnessMachineName).fire(E.change);
await Future<void>.delayed(const Duration(seconds: 1));
await lightMachine.find<S, E, T>(brightnessMachineName).fire(E.change);
}
await Future<void>.delayed(const Duration(seconds: 1));
await lightMachine.fire(E.turnOff);
}
}
复合状态机 - 多个区域
在同一个状态下添加多个区域。这些区域也可以称为并发区域,因为它们(或更准确地说是与它们对应的状态机)可以同时处于活动状态。
入口和出口点
入口和出口点用于在某些情况下,而不是激活这些机器的 initialStateId
所定义的状态,我们希望另一个状态被激活。此外,从这些机器内部,我们希望某些事件触发父状态机中的事件。
入口连接器和入口点
入口连接器映射定义了在父状态机中某个触发器(由父状态机的状态 id、转换 id 和事件 id 组成的三元组)激活时,需要使用子状态机中的哪个入口点。
Region(
machine: childMachine,
entryConnectors: {
Trigger(source: SP.first, event: EP.e1, transition: TP.toSecond): SC.ep1,
},
),
出口连接器和出口点
出口连接器映射定义了当子状态机达到某个出口点时,父状态机中应触发的事件。
Region(
machine: childMachine,
exitConnectors: {SC.exit: EP.turnOff},
),
历史记录
历史记录允许状态机在重新启动时恢复到其上次活动的状态。
- 浅历史:仅恢复当前状态机的最后活动状态。
- 深历史:恢复当前状态机及其所有子状态机的最后活动状态。
完整示例
以下是一个完整的示例,展示了如何使用 hisma
创建一个分层状态机:
import 'package:hisma/hisma.dart';
import 'package:hisma_visual_monitor/visual_monitor.dart';
// 定义状态、事件和转换
enum S { on, off }
enum E { turnOn, turnOff }
enum T { toOn, toOff }
// 创建状态机
StateMachine<S, E, T> createLightMachine({
RegionList<S, E, T>? regions,
}) =>
StateMachine<S, E, T>(
name: 'lightMachine',
events: E.values,
initialStateId: S.off,
states: {
S.off: State(
etm: {
E.turnOn: [T.toOn],
},
onEntry: Action(
description: 'Turning off.',
action: (machine, arg) async => print('OFF'),
),
),
S.on: State(
etm: {
E.turnOff: [T.toOff],
},
regions: regions,
onEntry: Action(
description: 'Turning on.',
action: (machine, arg) async => print('ON'),
),
),
},
transitions: {
T.toOn: Transition(to: S.on),
T.toOff: Transition(to: S.off),
},
);
// 创建亮度状态机
enum BrightnessS { half, full }
enum BrightnessE { change }
enum BrightnessT { toHalf, toFull }
const brightnessMachineName = 'brightnessMachine';
StateMachine<BrightnessS, BrightnessE, BrightnessT> createBrightnessMachine({
RegionList<BrightnessS, BrightnessE, BrightnessT>? regions,
}) =>
StateMachine<BrightnessS, BrightnessE, BrightnessT>(
name: brightnessMachineName,
events: BrightnessE.values,
initialStateId: BrightnessS.half,
states: {
BrightnessS.half: State(
etm: {
BrightnessE.change: [BrightnessT.toFull],
},
onEntry: Action(
description: 'Half light.',
action: (machine, arg) async => print('HALF'),
),
),
BrightnessS.full: State(
etm: {
BrightnessE.change: [BrightnessT.toHalf],
},
onEntry: Action(
description: 'Full light.',
action: (machine, arg) async => print('FULL'),
),
),
},
transitions: {
BrightnessT.toFull: Transition(to: BrightnessS.full),
BrightnessT.toHalf: Transition(to: BrightnessS.half),
},
);
// 创建主状态机
final lightMachine = createLightMachine(
regions: [Region(machine: createBrightnessMachine())],
);
// 创建 play 函数
Future<void> play() async {
while (true) {
await Future<void>.delayed(const Duration(seconds: 1));
await lightMachine.fire(E.turnOn);
for (var i = 0; i < 5; i++) {
await Future<void>.delayed(const Duration(seconds: 1));
await lightMachine.find<BrightnessS, BrightnessE, BrightnessT>(brightnessMachineName).fire(BrightnessE.change);
await Future<void>.delayed(const Duration(seconds: 1));
await lightMachine.find<BrightnessS, BrightnessE, BrightnessT>(brightnessMachineName).fire(BrightnessE.change);
}
await Future<void>.delayed(const Duration(seconds: 1));
await lightMachine.fire(E.turnOff);
}
}
// 主函数
Future<void> main() async {
StateMachine.monitorCreators = [
(machine) => VisualMonitor(machine),
];
await lightMachine.start();
play();
}
总结
通过上述示例,您可以看到如何使用 hisma
创建和管理分层状态机。hisma
提供了丰富的功能,包括状态、转换、层次结构、入口和出口点以及历史记录等,可以帮助您更好地管理和可视化复杂的状态机逻辑。希望这些示例对您有所帮助!
更多关于Flutter功能未知插件hisma的探索使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter功能未知插件hisma的探索使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在探索和使用Flutter中未知的插件(如hisma)时,理解插件的功能和API是至关重要的。由于hisma并非一个广为人知的Flutter插件,并且我无法直接访问最新的第三方库或特定插件的文档,我将提供一个通用的Flutter插件使用模板,并假设你已经从某个源(比如GitHub、pub.dev或其他可信平台)获取了hisma插件的基本信息和用法。
通常,Flutter插件的使用流程包括以下几个步骤:
-
在
pubspec.yaml
中添加依赖: 首先,你需要在你的Flutter项目的pubspec.yaml
文件中添加hisma插件的依赖。请注意,这里我使用的是假设的依赖名和版本号,你需要根据实际的hisma插件信息替换。dependencies: flutter: sdk: flutter hisma: ^x.y.z # 替换为实际的版本号
-
运行
flutter pub get
: 添加依赖后,运行以下命令来安装依赖:flutter pub get
-
导入插件并在代码中使用: 接下来,在你的Dart文件中导入hisma插件,并根据其API文档使用其功能。以下是一个假设的示例,展示了如何导入并使用一个名为
Hisma
的类(这完全基于假设,因为实际的hisma插件可能有不同的API):import 'package:flutter/material.dart'; import 'package:hisma/hisma.dart'; // 假设hisma插件的主文件是hisma.dart void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(), ); } } class MyHomePage extends StatefulWidget { @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { Hisma? hisma; @override void initState() { super.initState(); // 初始化hisma插件,这里假设有一个初始化方法init hisma = Hisma(); hisma!.init(); // 假设init是初始化方法 } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Hisma Plugin Demo'), ), body: Center( child: ElevatedButton( onPressed: () { // 假设hisma插件有一个doSomething方法 hisma!.doSomething().then((result) { // 处理结果 print('Result from hisma: $result'); }).catchError((error) { // 处理错误 print('Error: $error'); }); }, child: Text('Do Something with Hisma'), ), ), ); } @override void dispose() { // 清理资源,如果hisma插件有dispose方法的话 hisma?.dispose(); super.dispose(); } }
注意:
- 上述代码是一个假设的示例,实际的hisma插件可能有完全不同的API和初始化流程。
- 在使用任何第三方插件之前,务必查阅其官方文档或源代码,以了解正确的使用方法和API。
- 如果hisma插件在pub.dev上有页面,通常会有详细的安装和使用指南,以及示例代码。
由于我无法直接访问hisma插件的具体信息,建议你在使用前仔细研究其文档和示例代码,以确保正确集成和使用。