C#图形化逻辑控制软件的设计(FSM)

C#图形化逻辑控制软件的设计(FSM)

效果演示

点击StartAll启动执行,每一个单元完成后根据连接关系决定下一步需要执行的单元。
在这里插入图片描述

代码结构

1、DirectUI模块用于绘制图形界面,如上图右边的逻辑图,可以实时显示各个单元的执行状态。
2、FSM模块用于实现有限状态机的执行逻辑。
3、ThreadMessage用于在执行过程中显示一些消息。
在这里插入图片描述

核心执行器代码

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Test1.DirectUI;
using Test1.DirectUI.LogicCompoments;
using Test1.FSM.DataManage;
using Test1.FSM.Items;
using Doraemon.Helper;

namespace Test1.FSM
{
    public class FSMExecuter
    {
        private FSMEditor editor;
        private List<Context> starts = new List<Context>();
        private List<Task> tasks = new List<Task>();
        private bool stopFlag = false;
        private Database database = new Database();

        public FSMExecuter(FSMEditor editor)
        {
            this.editor = editor;
        }

        public void Run()
        {
            lock (this)
            {
                if (IsRunning)
                    return;
                stopFlag = false;
            }
            ResetAllItemAndFindStarts();
            foreach (Context st in starts)
            {
                Task task = new Task(new Action<object>((s) =>
                {
                    RunStart(s);
                }), st);
                task.Start();
                tasks.Add(task);
            }
            RemoveCompletedTask();
        }

        private void RunStart(object s)
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            float scanTicks = 0;
            int scanCount = 0;

            List<Context> nextSts = new List<Context>();
            Context start = s as Context;
            nextSts.Add(start);
            foreach (Context curSt in nextSts)
                curSt.StateItem.ResetStatus();
            List<Context> nextList = new List<Context>();
            do
            {
                long startTicks = SystemHelper.SystemTicks;
                nextList.Clear();
                foreach (Context curSt in nextSts)
                {
                    List<Context> tmp = curSt.StateItem.Handle(curSt);
                    nextList.AddRange(tmp);
                }
                nextSts.Clear();
                nextSts.AddRange(nextList);
                //删除已经完成的StateItem
                List<Context> delList = new List<Context>();
                foreach (Context next in nextSts)
                {
                    if (next.StateItem.IsFinished)
                        delList.Add(next);
                }
                foreach (Context next in delList)
                {
                    if (next.StateItem.IsFinished)
                        nextSts.Remove(next);
                }
                Thread.Sleep(0);
                scanTicks += (SystemHelper.SystemTicks - startTicks)/1000.0f;
                scanCount++;
                if (sw.ElapsedMilliseconds > 500)
                {
                    scanTicks /= scanCount;
                    sw.Restart();
                    (start.StateItem as Start).ScanTicks = scanTicks;
                    scanTicks = 0;
                    scanCount = 0;
                }
            } while (nextSts.Count > 0 && !stopFlag);
            foreach(Context curSt in nextList)
            {
                curSt.StateItem.Stop();
            }
        }

        private void ResetAllItemAndFindStarts()
        {
            starts.Clear();
            foreach (Control c in editor.FSMDesignner.RootControl.Controls)
            {
                if (c is LogicUnit)
                {
                    (c as LogicUnit).StateItem.ResetStatus();
                    Start start = (c as LogicUnit).StateItem as Start;
                    if (start != null)
                        starts.Add(new Context(this, start));
                }
            }
        }

        public bool IsRunning
        {
            get
            {
                RemoveCompletedTask();
                return tasks.Count != 0;
            }
        }

        public Database Database
        {
            get
            {
                return database;
            }
        }

        private void RemoveCompletedTask()
        {
            List<Task> delTaskList = new List<Task>();
            foreach (Task t in tasks)
            {
                if (t.IsCompleted)
                    delTaskList.Add(t);
            }
            foreach (Task t in delTaskList)
            {
                tasks.Remove(t);
            }
        }

        internal void Stop()
        {
            lock(this)
            {
                stopFlag = true;               
            }
        }
    }
}

其中RunStart为整体执行逻辑,其接受一个传入的Start对象,使得程序可以从Start对象开始执行,整个流程执行完成后线程便会终止,是否结束主要看当前完成单元的输出口是否连接有其他单元,并且此输出口是当前要转移的输出口。参考上面的动图,在弹窗单元选择了OK后便从OK输出口转移出去,如果选择了Cancel则从Cancel输出口转移出去。

代码链接

test1项目代码下载

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
有限状态机(Finite State Machine,简称FSM)是一种描述系统行为的数学模型,可以用来描述离散事件系统的状态演变。下面是关于FSM设计的一些建议: 1. 定义清晰的状态:在设计FSM时,需要明确各个状态的含义和转换条件,确保状态的定义清晰且不重叠。每个状态应该唯一表示一个系统或对象的具体情况,以便于理解和再现。 2. 考虑全面的事件:FSM的转换依赖于事件的发生,因此需要考虑到系统可能遇到的所有可能事件。对系统可能的输入进行分析,以确保设计FSM可以适应各种情况的变化。 3. 确定状态转换条件:每个状态之间的转换需要定义明确的条件,这些条件通常与特定的输入事件相关。在设计过程中,需要详细考虑这些条件,以确保状态之间的转换符合系统的要求。 4. 简化FSM设计:尽可能地简化FSM设计,避免过度复杂化。可以通过减少不必要的状态和转换来简化FSM,提高系统的可读性和可维护性。 5. 考虑FSM的扩展性:在设计FSM时,应该考虑到系统可能的扩展需求。确保FSM设计具有良好的扩展性和灵活性,以便未来可以方便地进行修改和扩展。 6. 进行充分的测试:设计FSM后,进行充分的测试以验证其正确性。通过提供各种输入和事件的组合,确保FSM能够按照设计预期的方式行为,并正确处理各种情况。 以上是关于FSM设计的一些建议,通过遵循这些建议,可以设计出高效、可靠的FSM,有效地描述系统的行为和状态变化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值