当前位置: 首页 > news >正文

C# Unity FSM 状态机

C# Unity FSM 状态机

使用状态机可以降低代码耦合性,并且可以优化代码可读性,方便团队协作等。
对于游戏开发内容来讲游戏开发的流程控制玩家动画都可以使用FSM有限状态机来实现。

1.FsmState

每个状态的基类,泛型参数表示所拥有者

public abstract class FsmState<T> where T : class
{protected internal abstract void OnInit(IFsm<T> fsm);protected internal abstract void OnEnter(IFsm<T> fsm);protected internal abstract void OnUpdate(IFsm<T> fsm);protected internal abstract void OnLeave(IFsm<T> fsm);protected internal abstract void OnDestroy(IFsm<T> fsm);protected void ChangeState<TState>(IFsm<T> fsm) where TState : FsmState<T>{Fsm<T> fsmImplement = (Fsm<T>)fsm;if(fsmImplement == null){throw new Exception("FSM is invalid.");}fsmImplement.ChangeState<TState>();}protected void ChangeState(IFsm<T> fsm, Type stateType){Fsm<T> fsmImplement = (Fsm<T>)fsm;if (fsmImplement == null){throw new Exception("FSM is invalid.");}if (stateType == null){throw new Exception("State type is invalid.");}if (!typeof(FsmState<T>).IsAssignableFrom(stateType)){throw new Exception("State type is invalid.");}fsmImplement.ChangeState(stateType);}
}

2.IFsm

有限状态机的接口

public interface IFsm<T> where T : class
{string Name{get;}string FullName{get;}T Owner{get;}int FsmStateCount{get;}bool IsRunning{get;}bool IsDestroyed{get;}FsmState<T> CurrentState{get;}float CurrentStateTime{get;}void Start<TState>() where TState : FsmState<T>;bool HasState<TState>() where TState : FsmState<T>;TState GetState<TState>() where TState : FsmState<T>;FsmState<T> GetState(Type stateType);FsmState<T>[] GetAllStates();
}

3.IFsmManager

有限状态机管理器接口

public interface IFsmManager
{int Count { get; }bool HasFsm<T>() where T : class;bool HasFsm(Type ownerType);bool HasFsm<T>(string name) where T : class;bool HasFsm(Type ownerType, string name);IFsm<T> GetFsm<T>() where T : class;IFsm<T> GetFsm<T>(string name) where T : class;IFsm<T> CreateFsm<T>(T owner, params FsmState<T>[] fsmStates) where T : class;IFsm<T> CreateFsm<T>(string name, T owner, params FsmState<T>[] states) where T : class;IFsm<T> CreateFsm<T>(T owner, List<FsmState<T>> states) where T : class;IFsm<T> CreateFsm<T>(string name, T owner, List<FsmState<T>> states) where T : class;bool DestroyFsm<T>() where T : class;bool DestroyFsm(Type ownerType);bool DestroyFsm<T>(string name) where T : class;bool DestroyFsm(Type ownerType, string name);bool DestroyFsm<T>(IFsm<T> fsm) where T : class;
}

4.FsmBase

有限状态机的基类

public abstract class FsmBase
{private string m_Name;public FsmBase(){m_Name = string.Empty;}public string Name{get{return m_Name;}protected set{m_Name = value ?? string.Empty;}}public string FullName{get{return $"{OwnerType.FullName}.{Name}";}}public abstract Type OwnerType{get;}public abstract int FsmStateCount{get;}public abstract bool IsRunning{get;}public abstract bool IsDestroyed{get;}public abstract string CurrentStateName{get;}public abstract float CurrentStateTime{get;}public abstract void Update();public abstract void Shutdown();
}

5.Fsm

状态机类

public class Fsm<T> : FsmBase, IFsm<T> where T : class
{private T m_Owner;private readonly Dictionary<Type, FsmState<T>> m_States;private FsmState<T> m_CurrentState;private float m_CurrentStateTime;private bool m_IsDestroyed;public Fsm(){m_Owner = null;m_States = new Dictionary<Type, FsmState<T>>();m_CurrentState = null;m_CurrentStateTime = 0f;m_IsDestroyed = true;}public T Owner => m_Owner;public FsmState<T> CurrentState => m_CurrentState;public override Type OwnerType => typeof(T);public override int FsmStateCount => m_States.Count;public override bool IsRunning => m_CurrentState != null;public override bool IsDestroyed => m_IsDestroyed;public override string CurrentStateName => m_CurrentState != null ? m_CurrentState.GetType().FullName : null;public override float CurrentStateTime => m_CurrentStateTime;public static Fsm<T> Create(string name,T owner,params FsmState<T>[] states){if(owner == null){throw new Exception("FSM owner is invalid.");}if(states== null|| states.Length < 1){throw new Exception("FSM states is invalid.");}Fsm<T> fsm = Pool<Fsm<T>>.Rent();fsm.Name = name;fsm.m_Owner = owner;fsm.m_IsDestroyed = false;foreach (FsmState<T> oneState in states){if(oneState == null){throw new Exception("FSM states is invalid.");}Type stateType = oneState.GetType();if (fsm.m_States.ContainsKey(stateType)){throw new Exception($"{stateType} state is already exist");}fsm.m_States.Add(stateType, oneState);oneState.OnInit(fsm);}return fsm;}public static Fsm<T> Create(string name,T owner,List<FsmState<T>> states){if (owner == null){throw new Exception("FSM owner is invalid.");}if (states == null || states.Count < 1){throw new Exception("FSM states is invalid.");}Fsm<T> fsm = Pool<Fsm<T>>.Rent();fsm.Name = name;fsm.m_Owner = owner;fsm.m_IsDestroyed = false;foreach (FsmState<T> oneState in states){if (oneState == null){throw new Exception("FSM states is invalid.");}Type stateType = oneState.GetType();if (fsm.m_States.ContainsKey(stateType)){throw new Exception($"{stateType} state is already exist");}fsm.m_States.Add(stateType, oneState);oneState.OnInit(fsm);}return fsm;}public FsmState<T>[] GetAllStates(){int index = 0;FsmState<T>[] arr = new FsmState<T>[m_States.Count];foreach (FsmState<T> fsmState in m_States.Values){arr[index++] = fsmState;}return arr;}public bool HasState<TState>() where TState : FsmState<T>{return m_States.ContainsKey(typeof(TState));}public override void Shutdown(){Pool<Fsm<T>>.Return(this, (fsm) =>{if(m_CurrentState != null){m_CurrentState.OnLeave(this);}foreach (FsmState<T> oneState in m_States.Values){oneState.OnDestroy(this);}Name = null;m_Owner = null;m_States.Clear();m_CurrentState = null;m_CurrentStateTime = 0f;m_IsDestroyed = true;});}public void Start<TState>() where TState : FsmState<T>{if (IsRunning){throw new Exception("FSM is running, can not start again.");}FsmState<T> state = GetState<TState>();if (state == null){throw new Exception("can not start state");}m_CurrentStateTime = 0f;m_CurrentState = state;m_CurrentState.OnEnter(this);}public void Start(Type stateType){if (IsRunning){throw new Exception("FSM is running, can not start again.");}if (stateType == null){throw new Exception("State type is invalid.");}if (!typeof(FsmState<T>).IsAssignableFrom(stateType)){throw new Exception("State type is invalid.");}FsmState<T> state = GetState(stateType);if (state == null){throw new Exception("FSM can not start state which is not exist.");}m_CurrentStateTime = 0f;m_CurrentState = state;m_CurrentState.OnEnter(this);}public override void Update(){m_CurrentStateTime += Time.deltaTime;m_CurrentState.OnUpdate(this);}public TState GetState<TState>() where TState : FsmState<T>{if (m_States.TryGetValue(typeof(TState), out FsmState<T> fsmState)){return (TState)fsmState;}return null;}public FsmState<T> GetState(Type stateType){if (stateType == null){throw new Exception("State type is invalid.");}if (!typeof(FsmState<T>).IsAssignableFrom(stateType)){throw new Exception("State type is invalid.");}if (m_States.TryGetValue(stateType, out FsmState<T> fsmState)){return fsmState;}return null;}public void ChangeState<TState>(){ChangeState(typeof(TState));}public void ChangeState(Type stateType){if (m_CurrentState == null){throw new Exception("Current state is invalid.");}FsmState<T> state = GetState(stateType);if (state == null){throw new Exception("FSM can not change state which is not exist.");}m_CurrentState.OnLeave(this);m_CurrentStateTime = 0f;m_CurrentState = state;m_CurrentState.OnEnter(this);}
}

6.FsmManager

状态机管理器

public class FsmManager : Singleton<FsmManager>,IFsmManager,IUpdateSingleton
{private readonly Dictionary<string, FsmBase> m_FsmDic;private readonly List<FsmBase> m_TempFsms;public FsmManager(){m_FsmDic = new Dictionary<string, FsmBase>();m_TempFsms = new List<FsmBase>();}public int Count => m_FsmDic.Count;public IFsm<T> CreateFsm<T>(T owner, params FsmState<T>[] fsmStates) where T : class{return CreateFsm(string.Empty, owner, fsmStates);}public IFsm<T> CreateFsm<T>(string name, T owner, params FsmState<T>[] states) where T : class{if (HasFsm<T>(name)){throw new Exception("Already exist FSM");}Fsm<T> fsm = Fsm<T>.Create(name, owner, states);m_FsmDic.Add(fsm.FullName, fsm);return fsm;}public IFsm<T> CreateFsm<T>(T owner, List<FsmState<T>> states) where T : class{return CreateFsm(string.Empty, owner, states);}public IFsm<T> CreateFsm<T>(string name, T owner, List<FsmState<T>> states) where T : class{if (HasFsm<T>(name)){throw new Exception("Already exist FSM");}Fsm<T> fsm = Fsm<T>.Create(name, owner, states);m_FsmDic.Add(fsm.FullName, fsm);return fsm;}public bool DestroyFsm<T>() where T : class{return InternalDestroyFsm($"{typeof(T).FullName}.{string.Empty}");}public bool DestroyFsm(Type ownerType){if (ownerType == null){throw new Exception("Owner type is invalid.");}return InternalDestroyFsm($"{ownerType.FullName}.{string.Empty}");}public bool DestroyFsm<T>(string name) where T : class{return InternalDestroyFsm($"{typeof(T).FullName}.{name}");}public bool DestroyFsm(Type ownerType, string name){if (ownerType == null){throw new Exception("Owner type is invalid.");}return InternalDestroyFsm($"{ownerType.FullName}.{name}");}public bool DestroyFsm<T>(IFsm<T> fsm) where T : class{if (fsm == null){throw new Exception("FSM is invalid.");}return InternalDestroyFsm(fsm.FullName);}public IFsm<T> GetFsm<T>() where T : class{return (IFsm<T>)InternalGetFsm($"{typeof(T).FullName}.{string.Empty}");}public IFsm<T> GetFsm<T>(string name) where T : class{return (IFsm<T>)InternalGetFsm($"{typeof(T).FullName}.{name}");}public bool HasFsm<T>() where T : class{return InternalHasFsm($"{typeof(T).FullName}.{string.Empty}");}public bool HasFsm(Type ownerType){if(ownerType == null){throw new Exception("Owner type is invalid.");}return InternalHasFsm($"{ownerType.FullName}.{string.Empty}");}public bool HasFsm<T>(string name) where T : class{return InternalHasFsm($"{typeof(T).FullName}.{name}");}public bool HasFsm(Type ownerType, string name){if (ownerType == null){throw new Exception("Owner type is invalid.");}return InternalHasFsm($"{ownerType.FullName}.{name}");}private bool InternalDestroyFsm(string name){if(m_FsmDic.TryGetValue(name,out FsmBase fsmBase)){fsmBase.Shutdown();return m_FsmDic.Remove(name);}return false;}private FsmBase InternalGetFsm(string name){FsmBase fsm = null;if (m_FsmDic.TryGetValue(name, out fsm)){return fsm;}return null;}private bool InternalHasFsm(string name){return m_FsmDic.ContainsKey(name);}public void Update(){m_TempFsms.Clear();if (m_FsmDic.Count <= 0)return;foreach (FsmBase fsmBase in m_FsmDic.Values){m_TempFsms.Add(fsmBase);}foreach (FsmBase fsmBase in m_TempFsms){if (fsmBase.IsDestroyed)continue;fsmBase.Update();}}protected override void Load(int assemblyName){}protected override void UnLoad(int assemblyName){}
}

7.测试

(一)IdleState

public class IdleState : FsmState<FsmTest>
{protected internal override void OnDestroy(IFsm<FsmTest> fsm){Debug.Log("销毁 IdleState");}protected internal override void OnEnter(IFsm<FsmTest> fsm){Debug.Log("进入 IdleState");}protected internal override void OnInit(IFsm<FsmTest> fsm){}protected internal override void OnLeave(IFsm<FsmTest> fsm){Debug.Log("离开 IdleState");}protected internal override void OnUpdate(IFsm<FsmTest> fsm){if (Input.GetKeyDown(KeyCode.A)){ChangeState<WalkState>(fsm);}}
}

(二)WalkState

public class WalkState : FsmState<FsmTest>
{protected internal override void OnDestroy(IFsm<FsmTest> fsm){Debug.Log("销毁 WalkState");}protected internal override void OnEnter(IFsm<FsmTest> fsm){Debug.Log("进入 WalkState");}protected internal override void OnInit(IFsm<FsmTest> fsm){}protected internal override void OnLeave(IFsm<FsmTest> fsm){Debug.Log("离开 WalkState");}protected internal override void OnUpdate(IFsm<FsmTest> fsm){if (Input.GetKeyDown(KeyCode.B)){ChangeState<RunState>(fsm);}}
}

(三)RunState

public class RunState : FsmState<FsmTest>
{protected internal override void OnDestroy(IFsm<FsmTest> fsm){Debug.Log("销毁 RunState");}protected internal override void OnEnter(IFsm<FsmTest> fsm){Debug.Log("进入 RunState");}protected internal override void OnInit(IFsm<FsmTest> fsm){}protected internal override void OnLeave(IFsm<FsmTest> fsm){Debug.Log("离开 RunState");}protected internal override void OnUpdate(IFsm<FsmTest> fsm){if (Input.GetKeyDown(KeyCode.C)){ChangeState<IdleState>(fsm);}}
}

mono测试

public class FsmTest : MonoBehaviour
{private IFsm<FsmTest> m_TestFsm;void Start(){SingletonSystem.Initialize();AssemblyManager.Load(1, GetType().Assembly);m_TestFsm = FsmManager.Instance.CreateFsm<FsmTest>("MyTestFsm",this, new IdleState(),new WalkState(),new RunState());m_TestFsm.Start<IdleState>();}void Update(){SingletonSystem.Update();if (Input.GetKeyDown(KeyCode.P)){FsmManager.Instance.DestroyFsm(m_TestFsm);}}
}

相关文章:

C# Unity FSM 状态机

C# Unity FSM 状态机 使用状态机可以降低代码耦合性&#xff0c;并且可以优化代码可读性&#xff0c;方便团队协作等。 对于游戏开发内容来讲游戏开发的流程控制玩家动画都可以使用FSM有限状态机来实现。 1.FsmState 每个状态的基类&#xff0c;泛型参数表示所拥有者 publi…...

pytorch搭建squeezenet网络的整套工程,及其转tensorrt进行cuda加速

本来&#xff0c;前辈们用caffe搭建了一个squeezenet的工程&#xff0c;用起来也还行&#xff0c;但考虑到caffe的停更后续转trt应用在工程上时可能会有版本的问题所以搭建了一个pytorch版本的。 以下的环境搭建不再细说&#xff0c;主要就是pyorch&#xff0c;其余的需要什么p…...

【精读Uboot】SPL阶段的board_init_r详细分析

对于i.MX平台上的SPL来说&#xff0c;其不会直接跳转到Uboot&#xff0c;而是在SPL阶段借助BOOTROM跳转到ATF&#xff0c;然后再通过ATF跳转到Uboot。 board_init_f会初始化设备相关的硬件&#xff0c;最后进入board_init_r为镜像跳转做准备。下面是board_init_r调用的核心函数…...

canvas绘制渐变色三角形金字塔

项目需求:需要绘制渐变色三角形金字塔,并用折线添加标识 (其实所有直接用图片放上去也行,但是ui没切图,我也懒得找她要,正好也没啥事,直接自己用代码绘制算了,总结一句就是闲的) 最终效果如下图: (以上没用任何图片,都是代码绘制的) 在网上找了,有用canvas绘…...

企业电子招标采购系统源码Spring Boot + Mybatis + Redis + Layui + 前后端分离 构建企业电子招采平台之立项流程图

功能模块&#xff1a; 待办消息&#xff0c;招标公告&#xff0c;中标公告&#xff0c;信息发布 描述&#xff1a; 全过程数字化采购管理&#xff0c;打造从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理。通供应商门户具备内外协同的能力&#xff0c;为外部供…...

Debain JDK8 安装

Debain JDK8 安装 首先请安装依赖&#xff1a; sudo apt-get update && sudo apt-get install -y wget apt-transport-https然后信任 GPG 公钥&#xff1a; wget -O - https://packages.adoptium.net/artifactory/api/gpg/key/public | sudo tee /etc/apt/keyrings/…...

Python序列操作指南:列表、字符串和元组的基本用法和操作

文章目录 序列列表创建列表访问元素修改元素添加和删除元素 range()字符串创建字符串访问字符字符串切片修改字符串 元组创建元组访问元素获取元素数量元组的特点&#xff1a; 可变对象改变对象的值改变变量的指向比较运算符总结 python精品专栏推荐python基础知识&#xff08;…...

【已更新代码图表】2023数学建模国赛E题python代码--黄河水沙监测数据分析

E 题 黄河水沙监测数据分析 黄河是中华民族的母亲河。研究黄河水沙通量的变化规律对沿黄流域的环境治理、气候变 化和人民生活的影响&#xff0c;以及对优化黄河流域水资源分配、协调人地关系、调水调沙、防洪减灾 等方面都具有重要的理论指导意义。 附件 1 给出了位于小浪底水…...

【前端】CSS-Grid网格布局

目录 一、grid布局是什么二、grid布局的属性三、容器属性1、display①、语句②、属性值 2、grid-template-columns属性、grid-template-rows属性①、定义②、属性值1&#xff09;、固定的列宽和行高2&#xff09;、repeat()函数3&#xff09;、auto-fill关键字4&#xff09;、f…...

计算机竞赛 基于深度学习的动物识别 - 卷积神经网络 机器视觉 图像识别

文章目录 0 前言1 背景2 算法原理2.1 动物识别方法概况2.2 常用的网络模型2.2.1 B-CNN2.2.2 SSD 3 SSD动物目标检测流程4 实现效果5 部分相关代码5.1 数据预处理5.2 构建卷积神经网络5.3 tensorflow计算图可视化5.4 网络模型训练5.5 对猫狗图像进行2分类 6 最后 0 前言 &#…...

2023-9-8 求组合数(二)

题目链接&#xff1a;求组合数 II #include <iostream> #include <algorithm>using namespace std;typedef long long LL; const int mod 1e9 7; const int N 100010;// 阶乘&#xff0c;阶乘的逆 int fact[N], infact[N];LL qmi(int a, int k, int p) {int res…...

k8s service的一些特性

文章目录 Service分发负载的策略同一端口通过不同协议暴露Headless Service的负载分发策略 Service分发负载的策略 大家都知道&#xff0c;一个service可以对应多个pod&#xff0c;那么一定要有一些方法来把service接收到的请求&#xff08;负载&#xff09;转发到pod上。 一般…...

C++中std::enable_if和SFINAE介绍

作为一个标准的C++模板类,我们先看下enable_if的定义: // STRUCT TEMPLATE enable_if template <bool _Test, class _Ty = void> struct enable_if {}; // no member "type" when !_Testtemplate <class _Ty> struct enable_if<true, _Ty> { //…...

华为OD机考算法题:数字加减游戏

目录 题目部分 解读与分析 代码实现 题目部分 题目数字加减游戏难度难题目说明小明在玩一个数字加减游戏&#xff0c;只使用加法或者减法&#xff0c;将一个数字 s 变成数字 t 。 每个回合&#xff0c;小明可以用当前的数字加上或减去一个数字。 现在有两种数字可以用来加减…...

WPF命令

在设计良好的Windows应用程序中&#xff0c;应用程序逻辑不应位于事件处理程序中&#xff0c;而应在更高层的方法中编写代码。其中的每个方法都代表单独的应用程序任务。每个任务可能依赖其他库。 使用这种设计最明显的方式是在需要的地方添加事件处理程序&#xff0c;并使用各…...

Unity中Shader的屏幕抓取 GrabPass

文章目录 前言一、抓取1、抓取指令2、在使用抓取的屏幕前&#xff0c;需要像使用属性一样定义一下,_GrabTexture这个名字是Unity定义好的 前言 Unity中Shader的屏幕抓取 GrabPass 一、抓取 1、抓取指令 屏幕的抓取需要使用一个Pass GrabPass{} GrabPass{“NAME”} 2、在使用…...

手撕 队列

队列的基本概念 只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列具有先进先出 入队列&#xff1a;进行插入操作的一端称为队尾 出队列&#xff1a;进行删除操作的一端称为队头 队列用链表实现 队列的实现 队列的定义 队列…...

【autodl/linux配环境心得:conda/本地配cuda,cudnn及pytorch心得】-未完成

linux配环境心得&#xff1a;conda/本地配cuda&#xff0c;cudnn及pytorch心得 我们服务器遇到的大多数找不到包的问题一&#xff0c;服务器安装cuda和cudnn使用conda在线安装cuda和cudnn使用conda进行本地安装检查conda安装的cuda和cudnn本地直接安装cuda和cudnn方法一&#x…...

macOS Ventura 13.5.2(22G91)发布,附黑/白苹果镜像下载地址

系统介绍&#xff08;下载请百度搜索&#xff1a;黑果魏叔&#xff09; 黑果魏叔 9 月 8 日消息&#xff0c;苹果今日向 Mac 电脑用户推送了 macOS 13.5.2 更新&#xff08;内部版本号&#xff1a;22G91&#xff09;&#xff0c;本次更新距离上次发布隔了 21 天。 本次更新查…...

vue 子组件向父组件传递参数 子传父

子组件中写&#xff1a; this.$emit(RowCount,res.data.RowCount); 父组件中写&#xff1a; getMFGLRowCount(val){ //父组件中的方法: 接收子组件传过来的参数值赋值给父组件的变量 //this.totalCount val; alert("这…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂&#xff08;如抗体、抑制肽&#xff09;在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上&#xff0c;高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术&#xff0c;但这类方法普遍面临资源消耗巨大、研发周期冗长…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)

前言&#xff1a; 在Java编程中&#xff0c;类的生命周期是指类从被加载到内存中开始&#xff0c;到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期&#xff0c;让读者对此有深刻印象。 目录 ​…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...

华为OD机考-机房布局

import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...

【 java 虚拟机知识 第一篇 】

目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...

【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error

在前端开发中&#xff0c;JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作&#xff08;如 Promise、async/await 等&#xff09;&#xff0c;开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝&#xff08;r…...

tauri项目,如何在rust端读取电脑环境变量

如果想在前端通过调用来获取环境变量的值&#xff0c;可以通过标准的依赖&#xff1a; std::env::var(name).ok() 想在前端通过调用来获取&#xff0c;可以写一个command函数&#xff1a; #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...

水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关

在水泥厂的生产流程中&#xff0c;工业自动化网关起着至关重要的作用&#xff0c;尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关&#xff0c;为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多&#xff0c;其中不少设备采用Devicenet协议。Devicen…...