【SKFramework框架核心模块】3-6、FSM有限状态机模块
推荐阅读
- CSDN主页
- GitHub开源地址
- Unity3D插件分享
- QQ群:398291828
- 小红书
- 小破站
大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。
一、前言
【Unity3D框架】SKFramework框架完全教程《全网最全》-专栏文章目录:
https://blog.csdn.net/q764424567/article/details/143926557
二、正文
2-1、介绍
有限状态机(Finite State Machine,FSM)
,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。
有限状态机的核心原理是基于状态和状态之间的转换,可以用来描述系统的行为和流程,尤其是在处理离散事件和复杂逻辑时代码有较强的可维护性及健壮性。
有限状态机作为一种强大的工具,被广泛用于管理游戏对象的状态转换和行为。
本章就对SKFramework框架
的FSM有限状态机模块
进行讲解。
2-2、使用说明
使用示例:
using SK.Framework;
using SK.Framework.FSM;
using UnityEngine;public class UseFSM : MonoBehaviour
{FSM fsm;public class TestState : State{public string stringValue;}private void Start(){fsm = SKFramework.Module<FSM>();//创建状态机var machine = fsm.Create<StateMachine>("示例状态机")//构建状态一.Build<TestState>("状态一")//设置状态一初始化事件.OnInitialization(state => state.stringValue = "A")//设置状态一进入事件.OnEnter(state => Debug.Log("进入状态一"))//设置状态一停留事件.OnStay(state => Debug.Log("状态一"))//设置状态一推出事件.OnExit(state => Debug.Log("退出状态一"))//设置状态一销毁事件.OnTermination(state => state.stringValue = null)//状态一构建完成.Complete()//构建状态二.Build<State>("状态二")//设置状态二进入事件.OnEnter(state => Debug.Log("进入状态二"))//设置状态二停留事件.OnStay(state => Debug.Log("状态二"))//设置状态二退出事件.OnExit((state => Debug.Log("退出状态二")))//状态二构建完成.Complete()//构建状态三.Build<State>("状态三")//设置状态三进入事件.OnEnter(state => Debug.Log("进入状态三"))//设置状态三停留事件.OnStay(state => Debug.Log("状态三"))//设置状态三退出事件.OnExit((state => Debug.Log("退出状态三")))//状态三构建完成.Complete()//添加状态切换条件 当按下快捷键1时 切换至状态一.SwitchWhen(() => Input.GetKeyDown(KeyCode.Alpha1), "状态一")//添加状态切换条件 当按下快捷键2时 切换至状态二.SwitchWhen(() => Input.GetKeyDown(KeyCode.Alpha2), "状态二")//添加状态切换条件 当按下快捷键3时 切换至状态三.SwitchWhen(() => Input.GetKeyDown(KeyCode.Alpha3), "状态三")//为状态一至状态二添加切换条件:若当前状态为状态一时 按下快捷键4 切换至状态二.SwitchWhen(() => Input.GetKeyDown(KeyCode.Alpha4), "状态一", "状态二");}
}
运行结果:
2-3、实现及代码分析
状态接口类:
namespace FSM
{public interface IStateData { }
}
抽象接口类:
using FSM;
using System;namespace FSM
{/// <summary>/// 抽象状态类/// </summary>public class State{/// <summary>/// 状态名称/// </summary>public string Name { get; set; }/// <summary>/// 是否可切换至自身/// </summary>public virtual bool CanSwitch2Self { get; set; }/// <summary>/// 所属状态机/// </summary>public StateMachine Machine { get; internal set; }/// <summary>/// 状态初始化事件/// </summary>internal Action onInitialization;/// <summary>/// 状态进入事件/// </summary>internal Action onEnter;/// <summary>/// 状态停留事件/// </summary>internal Action onStay;/// <summary>/// 状态退出事件/// </summary>internal Action onExit;/// <summary>/// 状态终止事件/// </summary>internal Action onTermination;/// <summary>/// 状态初始化事件/// </summary>public virtual void OnInitialization(){onInitialization?.Invoke();}/// <summary>/// 状态进入事件/// </summary>public virtual void OnEnter(IStateData data = null){onEnter?.Invoke();}/// <summary>/// 状态停留事件/// </summary>public virtual void OnStay(){onStay?.Invoke();}/// <summary>/// 状态退出事件/// </summary>public virtual void OnExit(){onExit?.Invoke();}/// <summary>/// 状态终止事件/// </summary>public virtual void OnTermination(){onTermination?.Invoke();}/// <summary>/// 设置状态切换条件/// </summary>/// <param name="predicate">切换条件</param>/// <param name="targetStateName">目标状态名称</param>public void SwitchWhen(Func<bool> predicate, string targetStateName){Machine.SwitchWhen(predicate, Name, targetStateName);}}
}
核心事件:
- OnInitialization 状态初始化事件
- OnEnter 状态进入事件
- OnStay 状态停留事件
- OnExit 状态退出事件
- OnTermination 状态终止事件
状态切换类(StateSwitchCondition):
using System;namespace FSM
{public class StateSwitchCondition{public readonly Func<bool> predicate;public readonly string sourceStateName;public readonly string targetStateName;public StateSwitchCondition(Func<bool> predicate, string sourceStateName, string targetStateName){this.predicate = predicate;this.sourceStateName = sourceStateName;this.targetStateName = targetStateName;}}
}
状态构建器(StateBuilder):
using System;namespace FSM
{/// <summary>/// 状态构建器/// </summary>/// <typeparam name="T">状态类型</typeparam>public class StateBuilder<T> where T : State, new(){//构建的状态private readonly T state;//构建的状态所属的状态机private readonly StateMachine stateMachine;/// <summary>/// 构造函数/// </summary>/// <param name="state"></param>/// <param name="stateMachine"></param>public StateBuilder(T state, StateMachine stateMachine){this.state = state;this.stateMachine = stateMachine;}/// <summary>/// 设置状态初始化事件/// </summary>/// <param name="onInitialization">状态初始化事件</param>/// <returns>状态构建器</returns>public StateBuilder<T> OnInitialization(Action<T> onInitialization){state.onInitialization = () => onInitialization(state);return this;}/// <summary>/// 设置状态进入事件/// </summary>/// <param name="onEnter">状态进入事件</param>/// <returns>状态构建器</returns>public StateBuilder<T> OnEnter(Action<T> onEnter){state.onEnter = () => onEnter(state);return this;}/// <summary>/// 设置状态停留事件/// </summary>/// <param name="onStay">状态停留事件</param>/// <returns>状态构建器</returns>public StateBuilder<T> OnStay(Action<T> onStay){state.onStay = () => onStay(state);return this;}/// <summary>/// 设置状态退出事件/// </summary>/// <param name="onExit">状态退出事件</param>/// <returns>状态构建器</returns>public StateBuilder<T> OnExit(Action<T> onExit){state.onExit = () => onExit(state);return this;}/// <summary>/// 设置状态终止事件/// </summary>/// <param name="onTermination">状态终止事件</param>/// <returns>状态构建器</returns>public StateBuilder<T> OnTermination(Action<T> onTermination){state.onTermination = () => onTermination(state);return this;}/// <summary>/// 设置状态切换条件/// </summary>/// <param name="predicate">切换条件</param>/// <param name="targetStateName">目标状态名称</param>/// <returns>状态构建器</returns>public StateBuilder<T> SwitchWhen(Func<bool> predicate, string targetStateName){state.SwitchWhen(predicate, targetStateName);return this;}/// <summary>/// 构建完成/// </summary>/// <returns>状态机</returns>public StateMachine Complete(){state.OnInitialization();return stateMachine;}}
}
状态机:
using FSM;
using System;
using System.Collections.Generic;namespace FSM
{/// <summary>/// 状态机/// </summary>public class StateMachine{//状态列表 存储状态机内所有状态private readonly List<State> states = new List<State>();//状态切换条件列表private readonly List<StateSwitchCondition> conditions = new List<StateSwitchCondition>();/// <summary>/// 状态机名称/// </summary>public string Name { get; internal set; }/// <summary>/// 当前状态/// </summary>public State CurrentState { get; protected set; }/// <summary>/// 状态机初始化事件/// </summary>public virtual void OnInitialization() { }/// <summary>/// 添加状态/// </summary>/// <param name="state">状态</param>/// <returns>0:添加成功; -1:状态已存在,无需重复添加; -2:存在同名状态,添加失败</returns>public int Add(State state){//判断是否已经存在if (!states.Contains(state)){//判断是否存在同名状态if (states.Find(m => m.Name == state.Name) == null){//存储到列表states.Add(state);//执行状态初始化事件state.OnInitialization();//设置状态所属的状态机state.Machine = this;return 0;}return -2;}return -1;}/// <summary>/// 添加状态/// </summary>/// <typeparam name="T">状态类型</typeparam>/// <param name="stateName">状态命名</param>/// <returns>0:添加成功; -1:状态已存在,无需重复添加; -2:存在同名状态,添加失败</returns>public int Add<T>(string stateName = null) where T : State, new(){Type type = typeof(T);T t = (T)Activator.CreateInstance(type);t.Name = string.IsNullOrEmpty(stateName) ? type.Name : stateName;return Add(t);}/// <summary>/// 移除状态/// </summary>/// <param name="stateName">状态名称</param>/// <returns>true:移除成功; false:状态不存在,移除失败</returns>public bool Remove(string stateName){//根据状态名称查找目标状态var target = states.Find(m => m.Name == stateName);if (target != null){//如果要移除的状态为当前状态 首先执行当前状态退出事件if (CurrentState == target){CurrentState.OnExit();CurrentState = null;}//执行状态终止事件target.OnTermination();//从列表中移除states.Remove(target);return true;}return false;}/// <summary>/// 移除状态/// </summary>/// <param name="state">状态</param>/// <returns>true:移除成功; false:状态不存在,移除失败</returns>public bool Remove(State state){return Remove(state.Name);}/// <summary>/// 移除状态/// </summary>/// <typeparam name="T">状态类型</typeparam>/// <returns>true:移除成功; false:状态不存在,移除失败</returns>public bool Remove<T>() where T : State{return Remove(typeof(T).Name);}/// <summary>/// 切换状态/// </summary>/// <param name="stateName">状态名称</param>/// <param name="data">数据</param>/// <returns>0:切换成功; -1:状态不存在; -2:当前状态已经是切换的目标状态,并且该状态不可切换至自身</returns>public int Switch(string stateName, IStateData data = null){//根据状态名称在列表中查询var target = states.Find(m => m.Name == stateName);if (target == null) return -1;//如果当前状态已经是切换的目标状态 并且该状态不可切换至自身 无需切换 返回falseif (CurrentState == target && !target.CanSwitch2Self) return -2;//当前状态不为空则执行状态退出事件CurrentState?.OnExit();//更新当前状态CurrentState = target;//更新后 执行状态进入事件CurrentState.OnEnter(data);return 0;}/// <summary>/// 切换状态/// </summary>/// <param name="state">状态</param>/// <returns>0:切换成功; -1:状态不存在; -2:当前状态已经是切换的目标状态,并且该状态不可切换至自身</returns>public int Switch(State state){return Switch(state.Name);}/// <summary>/// 切换状态/// </summary>/// <typeparam name="T">状态类型</typeparam>/// <typeparam name="data">数据</typeparam>/// <returns>0:切换成功; -1:状态不存在; -2:当前状态已经是切换的目标状态,并且该状态不可切换至自身</returns>public int Switch<T>(IStateData data = null) where T : State{return Switch(typeof(T).Name, data);}/// <summary>/// 切换至下一状态/// </summary>/// <returns>true:切换成功; false:状态机中不存在任何状态,切换失败</returns>public bool Switch2Next(){if (states.Count != 0){//如果当前状态不为空 则根据当前状态找到下一个状态if (CurrentState != null){int index = states.IndexOf(CurrentState);//当前状态的索引值+1后若小于列表中的数量 则下一状态的索引为index+1//否则表示当前状态已经是列表中的最后一个 下一状态则回到列表中的第一个状态 索引为0index = index + 1 < states.Count ? index + 1 : 0;State targetState = states[index];//首先执行当前状态的退出事件 再更新到目标状态CurrentState.OnExit();CurrentState = targetState;}//当前状态为空 则直接进入列表中的第一个状态else{CurrentState = states[0];}//执行状态进入事件CurrentState.OnEnter();return true;}return false;}/// <summary>/// 切换至上一状态/// </summary>/// <returns>true:切换成功; false:状态机中不存在任何状态,切换失败</returns>public bool Switch2Last(){if (states.Count != 0){//如果当前状态不为空 则根据当前状态找到上一个状态if (CurrentState != null){int index = states.IndexOf(CurrentState);//当前状态的索引值-1后若大等于0 则下一状态的索引为index-1//否则表示当前状态是列表中的第一个 上一状态则回到列表中的最后一个状态index = index - 1 >= 0 ? index - 1 : states.Count - 1;State targetState = states[index];//首先执行当前状态的退出事件 再更新到目标状态CurrentState.OnExit();CurrentState = targetState;}//当前状态为空 则直接进入列表中的最后一个状态else{CurrentState = states[states.Count - 1];}//执行状态进入事件CurrentState.OnEnter();return true;}return false;}/// <summary>/// 切换至空状态(退出当前状态)/// </summary>public void Switch2Null(){if (CurrentState != null){CurrentState.OnExit();CurrentState = null;}}/// <summary>/// 获取状态/// </summary>/// <typeparam name="T">状态类型</typeparam>/// <param name="stateName">状态名称</param>/// <returns>状态</returns>public T GetState<T>(string stateName) where T : State{var target = states.Find(m => m.Name == stateName);return target != null ? target as T : null;}/// <summary>/// 获取状态/// </summary>/// <typeparam name="T">状态类型</typeparam>/// <returns>状态</returns>public T GetState<T>() where T : State{return GetState<T>(typeof(T).Name);}/// <summary>/// 销毁状态机/// </summary>public void Destroy(){//Main.FSM.Destroy(this);}/// <summary>/// 状态机刷新事件/// </summary>internal void OnUpdate(){//若当前状态不为空 执行状态停留事件CurrentState?.OnStay();//检测所有状态切换条件for (int i = 0; i < conditions.Count; i++){var condition = conditions[i];//条件满足if (condition.predicate.Invoke()){//源状态名称为空 表示从任意状态切换至目标状态if (string.IsNullOrEmpty(condition.sourceStateName)){Switch(condition.targetStateName);}//源状态名称不为空 表示从指定状态切换至目标状态else{//首先判断当前的状态是否为指定的状态if (CurrentState.Name == condition.sourceStateName){Switch(condition.targetStateName);}}}}}/// <summary>/// 状态机销毁事件/// </summary>internal void OnDestroy(){//执行状态机内所有状态的状态终止事件for (int i = 0; i < states.Count; i++){states[i].OnTermination();}}/// <summary>/// 构建状态/// </summary>/// <typeparam name="T">状态类型</typeparam>/// <param name="stateName">状态名称</param>/// <returns>状态构建器</returns>public StateBuilder<T> Build<T>(string stateName = null) where T : State, new(){Type type = typeof(T);string name = string.IsNullOrEmpty(stateName) ? type.Name : stateName;if (states.Find(m => m.Name == name) == null){T state = Activator.CreateInstance(type) as T;state.Name = name;state.Machine = this;states.Add(state);return new StateBuilder<T>(state, this);}return null;}/// <summary>/// 设置状态切换条件/// </summary>/// <param name="predicate">切换条件</param>/// <param name="targetStateName">目标状态名称</param>/// <returns>状态机</returns>public StateMachine SwitchWhen(Func<bool> predicate, string targetStateName){conditions.Add(new StateSwitchCondition(predicate, null, targetStateName));return this;}/// <summary>/// 设置状态切换条件/// </summary>/// <param name="predicate">切换条件</param>/// <param name="sourceStateName">源状态名称</param>/// <param name="targetStateName">目标状态名称</param>/// <returns></returns>public StateMachine SwitchWhen(Func<bool> predicate, string sourceStateName, string targetStateName){conditions.Add(new StateSwitchCondition(predicate, sourceStateName, targetStateName));return this;}}
}
通过Add函数去添加状态,除此之外,可以通过Build构建状态实现添加,用于链式编程:
public StateBuilder<T> Build<T>(string stateName = null) where T : State, new()
设置状态切换条件:
public StateMachine SwitchWhen(Func<bool> predicate, string sourceStateName, string targetStateName)
三、后记
如果觉得本篇文章有用别忘了点个关注,关注不迷路,持续分享更多Unity干货文章。
你的点赞就是对博主的支持,有问题记得留言:
博主主页有联系方式。
博主还有跟多宝藏文章等待你的发掘哦:
专栏 | 方向 | 简介 |
---|---|---|
GameFramework框架 | 框架 | Unity之GameFramework框架快速应用、使用说明、源码分析等文章合集。 |
Unity3D开发小游戏 | 小游戏开发教程 | 分享一些使用Unity3D引擎开发的小游戏,分享一些制作小游戏的教程。 |
Unity3D从入门到进阶 | 入门 | 从自学Unity中获取灵感,总结从零开始学习Unity的路线,有C#和Unity的知识。 |
Unity3D之UGUI | UGUI | Unity的UI系统UGUI全解析,从UGUI的基础控件开始讲起,然后将UGUI的原理,UGUI的使用全面教学。 |
Unity3D之读取数据 | 文件读取 | 使用Unity3D读取txt文档、json文档、xml文档、csv文档、Excel文档。 |
Unity3D之数据集合 | 数据集合 | 数组集合:数组、List、字典、堆栈、链表等数据集合知识分享。 |
Unity3D之VR/AR(虚拟仿真)开发 | 虚拟仿真 | 总结博主工作常见的虚拟仿真需求进行案例讲解。 |
Unity3D之插件 | 插件 | 主要分享在Unity开发中用到的一些插件使用方法,插件介绍等 |
Unity3D之日常开发 | 日常记录 | 主要是博主日常开发中用到的,用到的方法技巧,开发思路,代码分享等 |
Unity3D之日常BUG | 日常记录 | 记录在使用Unity3D编辑器开发项目过程中,遇到的BUG和坑,让后来人可以有些参考。 |
相关文章:
【SKFramework框架核心模块】3-6、FSM有限状态机模块
推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享QQ群:398291828小红书小破站 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 一、前言 【Unity3D框架】SKFramework框架完全教程《全…...
Python之爬虫入门(1)
目录 一、简介 二、爬虫的功能 1、爬虫的用处 2、爬虫的应用场景 三、爬虫的实现步骤 四、GET和POST方法 1、GET方法 (1)、简介 (2)、适用场景 2、POST方法 (1)、简介 (2)…...
《MySQL 表结构设计基础》
一、引言 MySQL 表结构设计是数据库开发中的重要环节,合理的设计不仅能提高数据库性能,还能使数据更易于维护和管理。本文将详细介绍 MySQL 表结构设计的基础要点。 在数据库开发中,MySQL 表结构设计的重要性不言而喻。一个良好的表结构设计…...
微信小程序 - 解决报错{“errno“:600001,“errMsg“:“request:fail errcode:-202cronet_error_code:-202error_msg:net::
前言 关于此问题网上的教程都无法解决,如果您的报错信息与我相似,即可解决。 在微信小程序开发中,详细解决小程序请求接口报错:{“errno”:600001,“errMsg”:“request:fail errcode:-202cronet_error_code:-202error_msg:net::ERR_CERT_AUTH ORITY_INVALID”},微…...
k8s 为什么需要Pod?
Pod,是 Kubernetes 项目中最小的 API 对象,更加专业的说,Pod,是 Kubernetes 项目的原子调度单位。 Pod 是 Kubernetes 里的原子调度单位。这就意味着,Kubernetes 项目的调度器,是统一按照 Pod 而非容器的资…...
react 使用状态管理调用列表接口渲染列表(包含条件查询,统一使用查询按钮,重置功能),避免重复多次调用接口的方法
react开发调用api接口一般使用useEffect来监听值的变化,通过值的变化与否来进行接口调用。 比如我们要进行一个查询接口 const [pageParams, setPage] useState({name: ,id: ,});const [dataList, setDataList] useState([]);const getList async () > {const…...
常见限流算法详细解析
常见限流算法详细解析 分布式系统中,由于接口API无法控制上游调用方的行为,因此当瞬时请求量突增时,会导致服务器占用过多资源,发生响应速度降低、超时、乃至宕机,甚至引发雪崩造成整个系统不可用。 限流,…...
第四十一天 ASP应用 HTTP.sys 漏洞 iis6文件解析漏洞和短文件漏洞 access数据库泄露漏洞
前言 随着时代的发展现在呀,这个ASp已经淡出大众的视线了 ,ASP之前的火爆程度无异于现在的PHP 大家的童年 4399 什么的网站都是这个搭建的ASP 简介 | 菜鸟教程 那大家想问为什么你妹的 这个这么火的网站搭建语言被淘汰了呢 其实多半是以为它的不开…...
LLM输出评估标准
LLM输出评估标准 LLM评估方法 响应的完整性和简洁性:确定大模型的响应是否完全解决用户查询,简洁性则评估生成响应的相关性。文本相似性指标:将生成的文本与参考文本进行比较,评估它们的相似度,并给出得分以理解大模…...
ansible学习笔记之02command模块与shell模块
目录 1、概述 2、模块介绍 2.1 command模块 2.2 shell模块 2.3 小结 3、实验 3.1 测试ls命令 3.2 测试环境变量 3.3 测试操作符">" 1、概述 本文介绍ansible的command模块与shell模块,并通过实验比对两个模块的异同。 2、模块介绍 2.1…...
Python 在同一/或不同PPT文档之间复制幻灯片
复制幻灯片可以帮助我们更高效地完成工作,节省大量的制作时间。通过复制现有的幻灯片,可以快速创建新的演示文稿,而无需重新设计板式样式等。此外,复制幻灯片还可以帮助我们保持内容的一致性,使整个PPT演示文稿看起来更…...
4. React 性能优化技巧:如何让你的应用更快
在构建大型应用时,性能优化是一个非常重要的话题。React 提供了许多优化工具,帮助我们提高应用的渲染速度和响应能力。本文将分享一些常见的 React 性能优化技巧。 4.1. 使用 React.memo 缓存组件 当组件的 props 没有变化时,React 默认不会…...
云标准:云计算标准
目录 云计算标准的定义和分类 云计算标准的内容 云计算标准的重要性 云计算标准化组织 5.云计算标准的具体实例 云计算标准是确保云计算技术、服务和应用发展的重要规范,它们对于提高云计算系统的互操作性、可靠性和安全性至关重要。以下是对云计算标准的详细解…...
Redis【2】- SDS源码分析
1 简介&基础用法 Redis 中用得最多的就是字符串,在 C 语言中其实可以直接使用 char* 字符数组来实现字符串,也有很多可以直接使用得函数。但是 Redis 并没有使用 C 语言原生的字符串,而是自己实现了一个 SDS(简单动态字符串&…...
力扣打卡8:最长上升子序列
链接:300. 最长递增子序列 - 力扣(LeetCode) 本题我开始想到的是dp,复杂度为O(n^2),这也是很经典的解法。 看到进阶解法可以O(nlogn),想到可能是要用到二分,但是,我想到的是和map排…...
记录一次老平台改造通知用户刷新页面,纯前端实现
记录一次老平台改造通知用户刷新页面,纯前端实现 方案概述背景现状问题本质 方案设计前提设计实现 其他补充写在最后的话抛出一个问题 方案概述 背景 前端构建完上线,用户还停留还在老页面,用户不知道网页重新部署了,跳转页面的时…...
ubuntu22.04 使用可以用的镜像源获取你要的镜像
默认的是不行的 不管pull啥镜像 仍然会出现这个错误 Error response form daemon:Get "https://registry-1.docker.io/v2": net/http: request canceled while waiting for connection (Client.Timeout exceeded while await) 操作方法是 如果在目录没有/etc/docker…...
Chrome扩展程序开发示例
项目文件夹内文件如下: manifest.json文件内容: {"manifest_version": 3,"name": "我的法宝","description": "我的有魔法的宝贝","version": "1.0","icons": {"…...
Linux 下使用飞鸽传书实现与Windows飞秋的通信
最近把单位的办公电脑换成Linux系统,但是其他同事们都使用飞秋2013进行局域网通信和文件传输,经过一番尝试,发现飞鸽传书For Linux 2014能够实现两者的互相通信。 飞鸽传书ForLINUXLinux版下载_飞鸽传书ForLINUX免费下载_飞鸽传书ForLINUX1.2…...
docker批量创建cloudstack虚拟主机脚本
批量创建cloudstack脚本 #!/bin/bash # 配置变量 container_prefix"cloudworker-" base_ip"192.168.1." start_ip2 #开始ip start_container2 #上同 end_container4 #结束ip 包括 network_name"my_macvlan_network" image_name"dockedahi:…...
SpringBoot项目集成MinIO
最近在学习MinIO,所以想让自己的SpringBoot项目集成MinIO,在网上查阅资料,并进行操作的过程中遇到一些问题,所以想把自己遇到的坑和完成步骤记录下来供自己和各位查阅。 一. MinIO的下载安装以及基本使用 1. 下载地址:https://d…...
【Flutter】常用样式、方法、组件(长期更新中)
一、样式设置 设置颜色透明度:color: Color(0xff4B9E32).withOpacity(0.08) 二、常用方法 数组排序:list.sort(); **升序**:(obj1, obj2) > obj1.compareTo(obj2) **降序**:(obj1, obj2) > obj2.compareTo(obj1)obj1.co…...
dbus接口方法的variant类型传参详解
python实现c++中so库调用及dbus服务开发-CSDN博客 之前写的这篇博文介绍了如何创建一个dbus服务,但是注册的接口方法的入参还是比较简单的,实际上dbus的参数类型有很多种,调用方式也有多种,我们来逐一介绍下。 其实基础数据类型,如字符串、整型、浮点型、布尔型等大多数…...
【时时三省】(NIT计算机考试)Word的使用方法
山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省 一、软件简介 Microsoft Word,简称Word,是微软公司开发的一款文字处理软件,广泛应用于文档编辑、排版、打印等领域。无论是撰写论文、报告、简历…...
spring技术点
引入对象 Autowired 和 Resource的区别 Autowired 和 Resource的区别 valid 参数校验 jarkata进行SpringMVC校验 常规当前进行校验的配置操作,参考文档如下进行操作。 SpringMVC校验注解不生效 List类型参数校验 由于list类型默认不能进行标注校验实现&#x…...
工业—使用Flink处理Kafka中的数据_ChangeRecord1
使用 Flink 消费 Kafka 中 ChangeRecord 主题的数据,当某设备 30 秒状态连续为 “ 预警 ” ,输出预警 信息。当前预警信息输出后,最近30...
实验日志——DETR
DETR训练日志 1. 代码来源 代码源自作者的Github: https://github.com/facebookresearch/detr?tabreadme-ov-file 2. 数据来源 在DETR中只使用了COCO2017数据集,其中训练集有118288张图像,验证集有5001张数据,测试集有40671张数据&#…...
前端常用缓存技术深度剖析
🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…...
汽车IVI中控开发入门及进阶(三十七):基于HFP协议的蓝牙电话
概述: HFP全称Hands-free Profile,是一款让蓝牙设备控制电话的软件,多用于汽车上。此类设备最常见的例子是车载免提装置与蜂窝电话或可穿戴无线耳机一起使用。该配置文件定义了支持免提配置文件的两个设备如何在点对点的基础上相互交互。免提模式的实现通常使耳机或嵌入式免…...
分布式系统架构1:共识算法Paxos
1.背景 今天开始更新分布式的文章,工作几年后还没系统的学习分布式的内容,趁着还有时间学习沉淀的时候多输出些文章 2.为什么需要分布式共识算法 思考:现在你有一份随时变动的数据,需要确保它正确存储在网络的几台不同机器上&a…...
大语言模型应用Text2SQL本地部署实践初探
自从两年前OpenAI公司发布ChatGPT后,大模型(Large Language Model,简称LLM)相关技术在国内外可谓百家争鸣,遍地开花,在传统数据挖掘、机器学习和深度学习的基础上,正式宣告进入快速发展的人工智能(Artificial Intellig…...
C# WPF抽奖程序
C# WPF抽奖程序 using Microsoft.Win32; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.…...
linux运维命令
防火墙相关命令 防火墙规则查看 firewall-cmd --list-all 禁ping firewall-cmd --permanent --add-rich-rulerule protocol valueicmp drop firewall-cmd --reload 执行完以上命令后,通过firewall-cmd --list-all查看规则生效情况 firewall-cmd --list-all 其…...
环境兼容: Vue3+ELement-plus
题目:环境兼容: Vue3ELement-plus 前言 身为小白的我也在负责一个项目咯,开发的是Vue3项目,然后就搜阅多篇文章,整理了这个。内容很多是转载的,拼成的我这个文章。 Element-plus简介 Element-plus 是基于…...
解决 PyTorch 中的 AttributeError: ‘NoneType‘ object has no attribute ‘reshape‘ 错误
这里写目录标题 一、错误分析二、错误原因三、解决方案1. 检查损失函数2. 检查前向传播3. 检查 backward 函数4. 检查梯度传递 四、前向传播与反向传播1. 前向传播2. 反向传播3. 自定义 backward 函数示例反向传播过程:常见的错误:1:损失函数…...
Unity 设计模式-命令模式(Command Pattern)详解
命令模式(Command Pattern)是一种行为型设计模式,它将请求封装成对象,从而使得可以使用不同的请求、队列或日志请求,以及支持可撤销的操作。命令模式通常包含四个主要角色:命令(Command…...
如何解决maven项目使用Ctrl + /添加注释时的顶格问题
一、问题描述 相信后端开发的程序员一定很熟悉IDEA编译器和Maven脚手架,使用IDEA新建一个Maven工程,通过SpringBoot快速构建Spring项目。在Spring项目pom.xml文件中想添加注释,快捷键Ctrl /,但是总是顶格书写。 想保证缩进统一…...
网络安全信息收集(总结)更新
目录 重点: 前言: 又学到了,就是我们什么时候要子域名收集,什么时候收集域名,重点应该放前面 思考: 信息收集分为哪几类,什么是主域名,为什么要收集主域名,为什么要收…...
微服务-seata分布式事务
1.简述 1.1.什么是分布式事务 事务:是应用程序中一系列严密的操作,所有操作必须成功完成,要么全部失败,ACID 特性。本地事务:关系型数据库中,由一组SQL组成的一个执行单元,该单元要么整体成功,要么整体失败ÿ…...
(亲测好用)YOLO格式txt数据集转COCO格式json
1、数据集结构形式 YOLO格式数据集: b文件夹下有images和labels两个文件夹,分别存放图片和标签格式的数据。 两个文件夹下分别有train、val、test三个文件夹,里面存放对应的数据。 COCO数据集格式: COCO格式数据文件夹下有三个…...
LVS的DR模式是否依赖内核的数据包转发
LVS的DR模式是否依赖内核的数据包转发 是的,LVS(Linux Virtual Server) 的 DR(Direct Routing)模式 依赖于 内核的数据包转发。在 DR 模式下,数据包的转发行为是由 Linux 内核进行的,因此正确配…...
沿着数组的指定轴对每行(列)应用一个函数np.apply_along_axis
【小白从小学Python、C、Java】 【考研初试复试毕业设计】 【Python基础AI数据分析】 沿着数组的指定轴 对每行(列)应用一个函数 np.apply_along_axis [太阳]选择题 根据题目代码,执行的结果是? import numpy as np array np.array([[1, 2, 3],…...
BEPUphysicsint定点数3D物理引擎使用
原文:BEPUphysicsint定点数3D物理引擎使用 - 哔哩哔哩 上一节給大家介绍了BEPUphysicsint的一些基本的情况,这节课我们来介绍它的基本使用,本节主要从以下5个方面来介绍: (1) 创建一个物理世界Space,并开启模拟迭代; (2) 添加一个物理物体…...
LinuxUDP编程
由于UDP是无连接、尽力传输的,所以Server端绑定完IP、端口号后,使用recvfrom可以阻塞等待客户端的数据,而且Client端通过sendto发送的数据包直接发送到互联网(也是基于IP、端口号)这种操作是不担保Server端是否收到的&…...
Elasticsearch vs 向量数据库:寻找最佳混合检索方案
图片来自Shutterstock上的Bakhtiar Zein 多年来,以Elasticsearch为代表的基于全文检索的搜索方案,一直是搜索和推荐引擎等信息检索系统的默认选择。但传统的全文搜索只能提供基于关键字匹配的精确结果,例如找到包含特殊名词“Python3.9”的文…...
Android显示系统(07)- OpenGL ES - 纹理Texture
Android显示系统(02)- OpenGL ES - 概述 Android显示系统(03)- OpenGL ES - GLSurfaceView的使用 Android显示系统(04)- OpenGL ES - Shader绘制三角形 Android显示系统(05)- OpenGL…...
C#加速Bitmap存图
如果希望大幅提高图像保存速度,特别是在处理非常大的图像时,可以尝试以下更直接、更高效的方法: 1. 避免使用 Bitmap 类的 Save 方法 Bitmap.Save 方法的速度受限于 GDI 库的操作,尤其是对于非常大的图像,它可能会经历…...
打通Vue3+Flask(python3)+Mysql-实现简单数据交互
一、需要准备的工具 下载python3,Vscode,pycharm(这里用的社区版),phpstudy_pro,Node.js(建议下载长期支持版本,版本不宜过低,比如18,20),Vue.js…...
PT8M2102 触控型 8Bit MCU
1 产品概述 ● PT8M2102 是一款基于 RISC 内核的8位 MTP 单片机,内部集成了电容式触摸感应模块、TIMER,PWM、LVR、LVD、WDT等外设,其主要用作触摸按键开关,广泛适用于触控调光、电子玩具、消费电子、家用电器等领域,具…...
【PyQt5教程 一】Qt Designer 安装及其使用方法说明,附程序源码
目录 一、PyQt5介绍: (1)PyQt简介: (2)PyQt API: (3)支持的环境: (4)安装: (5)配置环境变量…...