- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我经常需要实现一个能够根据用户命令切换其行为的对象。例如,这可能是连接到 PC 并由用户通过 GUI 控制的类表示设备的情况。更一般地说,设备必须独立存在,有自己的操作调度。 由于我想从特定设备类中“提取”此行为以增强代码重用,因此我在这里提出了一个使用 Qt 的模板化有限状态机类。我还在 A 类中报告了一个示例用法。您(比我更有经验的程序员 :) 对此有何看法?这是设计这样一个类的“正确”方法吗?是否存在性能问题?
template < class Base,
typename T,
class ThreadPolicy>
class FSM
{
public:
typedef bool (Base::*my_func)();
struct SState {
SState(){}
SState(const T& id_arg,
const T& next_arg,
const T& error_arg,
const QList<T>& branches_arg,
const my_func& op_arg) :
id(id_arg),
next(next_arg),
error(error_arg),
branches(branches_arg),
op(op_arg)
{}
T id; // state ID
T next; // next state
T error; // in case of error
QList<T> branches; // allowed state switching from current
my_func op; // operation associated with current state
};
typedef QMap<T ,SState> SMap;
bool switchState(const T& ns){
return _checkAllowed(ns);
}
bool addState(const T& id, const SState& s){
return _register(id, s);
}
protected:
void _loop(Base* ptr){
if ((ptr->*m_states[m_state].op)()) {
ThreadPolicy::Lock();
if(m_externalSwitch){
m_externalSwitch = false;
ThreadPolicy::Unlock();
return;
}
m_state = m_states[m_state].next;
ThreadPolicy::Unlock();
} else {
ThreadPolicy::Lock();
if(m_externalSwitch){
m_externalSwitch = false;
ThreadPolicy::Unlock();
return;
}
m_state = m_states[m_state].error;
ThreadPolicy::Unlock();
}
}
bool _checkAllowed(const T& cmd){
if (!m_states[m_state].branches.contains(cmd)) { return false;}
ThreadPolicy::Lock();
m_state = cmd;
m_externalSwitch = true;
ThreadPolicy::Unlock();
return true;
}
bool _register(const SState& s){
if(m_states.find(s.id) != m_states.end()) { return false; } // state with same ID already exist
m_states[s.id] = s; // add the new state to the map
return true;
}
SMap m_states; // map states to Baseclass methods
T m_state; // holds my current state
bool m_externalSwitch; // check if user request a state switch
};
class A :
public QObject,
public FSM< A, QString, MultiThreaded >
{
Q_OBJECT
A(){
// SState startState; myState.branches << "start" << "stop";
_register(SState("start",
"start",
"stop",QStringList(("start","stop")),
&A::_doStart));
_register(SState("stop",
"stop",
"stop",QStringList(("stop","start")),
&A::_doStop));
}
private slots:
void run(){
for(;;){
_loop(this);
QCoreApplication::processEvents();
}
}
private:
bool _doStart(){ return true;}
bool _doStop(){ return true;}
};
最佳答案
A. What do you ( more experienced programmers than me :) think about that? Is it the "correct" way to design such a class? Are there performance issues ?
好的!我粗略地查看了您的设计,对于通用 FSM 框架,我真的感觉不太好。这太狭窄了,无法在更广泛的上下文中使用。批评的一些要点:
一般来说,我建议遵循 GoF State Pattern用于 FSM 实现。对于非常简单的状态图 switch(event)
case <event>: changeState(newState)
可能就够了。但是将事件呈现为 FSM 的方法条目,并将这些委托(delegate)给当前状态类实例,使整个构造更加灵活。考虑随特定事件一起出现的可选参数,您需要为这些扩展您的状态机设计。
一般来说,您使用 CRTP 的方法对于您的状态机来说是个好主意,但对于您所演示的内容,简单的动态多态性(使用虚拟成员函数)也可以很好地工作。
关于性能问题,不要认为您会在当前环境中遇到问题,但这完全取决于您要部署的位置和环境。
我想推荐你看看我的状态机类模板框架 STTCL ,它提供了符合 UML 2.0 的状态机的各种基于 C++ 模板的方面,遵循已经提到的 GoF 状态模式。
关于c++ - "generalized"有限状态机实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20720195/
崩溃报告: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_UIConc
我的 Google Charts 信息中心有问题。目前一切正常,除了柱形图在 Y 轴上显示字符串而不是整数。 我发现 Google 图表页面上的文档很难理解,所以如果我的代码中有错误,或者如果有更简单
我在 VS 项目编译中收到警告。尽管编译成功,但我无法获得文件的输出。您知道如何设置上述每一项吗? 它是在谈论哪个命令和outfile文件?应该给出什么路径? //testlib.h #include
有问题的设置: 我知道: xcode构建 -parallelizeTargets -maximum-concurrent-test-device-destinations NUMBER -maximu
我开始学习 UML,并且有一个关于 Actor 泛化的问题: 假设我正在为某所大学的某种应用程序编写用例图。我已经确定有两个 Actor ;学生和老师。 现在,为了简单起见,假设要求相当简单(对我的问
我经常需要实现一个能够根据用户命令切换其行为的对象。例如,这可能是连接到 PC 并由用户通过 GUI 控制的类表示设备的情况。更一般地说,设备必须独立存在,有自己的操作调度。 由于我想从特定设备类中“
题目地址:https://leetcode-cn.com/problems/generalized-abbreviation/ 题目描述 Write a function to generate
我刚刚在我的程序中添加了一个 ui 搜索栏,每次我重新运行该程序时,我都会收到错误消息 -[一般] 与守护程序的连接无效尽管如此,我的应用程序仍能完美运行,而且我似乎无法分辨出哪里出了问题。 有谁知道
这可能是一个简单的问题,但我找不到解决方案。我有一个带有 PostDate 列的 Excel 电子表格,其值为:VLOOKUP(E2,upload!A:H,2,FALSE)它显示为日期。我将此电子表格
我一直在尝试学习使用 Isabelle 2016。虽然原则上我喜欢异步证明检查的想法,但我不喜欢 Isabelle/jEdit 的原因有很多,其中最严重的是它使用了太多内存(为了我)。 如果我能在 I
我想弄清楚如何修改单个产品选项,以便产品管理员可以从下拉列表中选择产品的状况,即新的/二手的。 以下是允许产品管理员手动输入产品条件的代码。 // Enabling and Displaying Fi
这很清楚 destruct H如果 H包含连词或析取。但我无法弄清楚它在一般情况下的作用。它做了一些奇怪的事情,特别是如果 H: a -> b . 一些例子: Lemma demo : forall
这是我项目的例子: [ https://codepen.io/adan96/pen/ExaRgOe][1] 如您所见,我的 html 代码中有三个按钮。每次刷新页面或一段时间后打开项目时,是否应单击第
我有一个方法想将一个自定义枚举类型的数组作为参数。 看起来像这样的东西: public void DoSomething(WhatDoIPutHere[] parameters) 我想将 Enum1[
我正在构建一个网站,用户可以在其中清点项目并向其应用各种属性,例如。照片、网址、评论等。 我有一个包含三个表的数据库结构: users , entries , associations . 这些表具有
我正在寻找有关构建程序的最佳方式的建议。这是我现在所拥有的,以及我在设计中看到的问题: 我有一个带有私有(private)构造函数和 submit() 方法的类,用于仔细控制创建的对象,并将创建的每个
假设我有一个 4 维张量 A,我想按以下方式将它与 3 维张量 B 相乘: C[i,k,a,b] = sum_{j,l} A[i,j,k,l]*B[a,j,b,l] 这是矩阵乘法的推广: z[i,k]
我试图理解最坏情况分析,想知道在最坏情况运行时间分析中使用时是否有某种方式可以解释术语广义示例? 我的第一个想法是它是根据输入的特征来分析性能,但我觉得应该有更正式的方式来解释它,也许使用顺序符号?
NXN 矩阵中的“广义对角线”是 N 个单元格的选择,这样: 从每一行和每一列中只选择一个单元格 每个选定的单元格都包含一个非零值 我正在寻找一种算法来在 O(n^3) 中找到广义对角线。在我看来,以
Realm 新手,我想知道如何使用 RealmSwift 构建树结构... 我倾向于认为这是对文件系统文件夹概念的模仿,所以, class Folder: Object { dynamic v
我是一名优秀的程序员,十分优秀!