利用队列收集单双击和长按按键
利用队列收集单双击和长按按键
引言
当我们仅仅通过在while循环里面进行判断按键类型的标志位, 然后进行操作的时候, 我们的最小例程很小, 所以能够实时的检测到按键,从而触发实验现象.
![]()
假如我们此时进入了一个事件处理函数呢 ? 并且这个这个函数的操作是不可被打断的, 如果此时我们重复按下多次按键, 标志位只能存放一个数值, 等事件处理完, 我们再处理的时候, 只能处理最后一次按下的按键类型.
![]()
最常见的就是, 我们使用遥控器, 我们连着按下了多个下箭头, 因为电视太卡, 导致只向下一次, 会极大影响操作体验.
所以我们的需求就是, 虽然你现在可能有重要事情要做, 但是, 你可以把我的按键需求存下来, 等不忙的时候, 再来处理. 因为处理器的处理是很快的, 所以我们也不会耽搁太多的时间。
按键收集模型分析
对于按键的收集, 我们分成三种类型,单击,双击和长按, 并且我们是按顺序按下的, 按顺序处理的, 所以这很符合队列的模型, 我们把他们排成一排, 放进数组, 然后到处理的时候, 再按顺序, 逐个处理, 按键需求和用户需求保持一致即可.
按键收集时机
对于按键收集, 假如现在我们有重要的事情去做, 不能立即去处理按键的功能, 但是我们可以中断的去收集按键类型, 因为中断是不会耽搁时间的. 只是花费CPU去记录一下数据. 所以我们在定时器函数内, 判断按键类型的时候, 把按键类型 button_mode 收集到队列里面。

按键收集队列
我们采用数组存储, 定义一个队头,定义一个队尾,加入按键的时候,我们放在队尾, 处理按键的时候, 我们拿取队头按键处理。
初始化时候
队首,队尾都指向数组初始的时候
加入一个按键的时候
此按键, 加入到队尾(位序0), 然后队尾后移, 因为队尾始终要承载按键, 所以后移, 为后续腾出位置
加入两个按键的时候
把按键2,加入队尾, 位序为1处, 然后队尾后移到位序2
所以, 在收集按键的时候, 我们定义一个数组, 队尾一直后移, 因为我们相当于一个循环队列, 所以队尾后移到最大位序的时候, 可以再次回到开头, 继续添加(这里有一个前提就是, 我们一次性处理的数据, 不能超过数组的最大位序, 保证出队和入队的正常运转即可)。
void collect_button(void)
{//采集按键信息button_order[button_send] = button_mode;if(button_send >= 5) // 说明5的位置已经被填了,下个该0了(++后,所指位置为空){button_send = 0;}else{button_send++;}
}
按键队列处理
有加入,就有取出。所以当我们取出按键的时候, 把队头按键取出, 处理此按键, 然后队头后移.
直到队头和队尾的数组位序重合, 那么我们就可以宣布,按键处理完毕了
取出按键
按键处理完毕的时候
当队头对应的按键处理完的时候, 我们队头后移, 为下次抽取按键做准备, 但是当队头和队尾 , 重合的时候, 就代表我们没有按键需要处理了.(队尾实时指向的位置, 是为下一次加入队列的按键做准备的, 所以是空的)
代码实现
我们一边处理着按键, 一边判断着队首和队尾是否重合, 一旦重合就代表着我们按键处理完了.
当 button_deal 队首 和 button_send 队尾 不重合时, 就一直取出按键
每次处理完一个按键后, 队尾位序后移, 同时要记得我们是数组,所以容量总会有不够用的时候, 所以我们要回到开头, 继续添加, 逻辑上是连在一起的(只需要保证同时处理的按键总和小于数组总容量即可)
void oled_chose(void)
{//下面是原子时间,不可被定时器新加命令button_atom = 1;//if(button_deal != button_send)//如果有按键指令while(button_deal != button_send ) //直到处理完指令{button_down = 1; //代表已经有指令了//(短按 1, 双按 2, 长按 3)if(button_order[button_deal] == 1){if(now_mode[0] == 1){now_mode[1] ^= 1;}elseif(now_mode[0] == 2)//歌曲选择{if(now_mode[1] == 3){now_mode[1] = 0;}else{now_mode[1]++;}}elseif(now_mode[0] == 3)//歌曲播放页面{//开关歌曲now_mode[2] ^= 1;}}elseif(button_order[button_deal] == 2) //(双击){switch(now_mode[0]){case 1:break; //没想好干啥case 2:now_mode[0] = 3;//进入音乐播放界面now_mode[2] = 1;//播放按钮打开break;case 3:now_mode[0] = 2;//返回音乐菜单now_mode[2] = 0;//播放按钮关闭break;default:break;}} else if(button_order[button_deal] == 3)//长按{if(now_mode[0] == 1){now_mode[0] = 2;//切换为音乐模式now_mode[1] = 0;//音乐界面默认第一个now_mode[2] = 0;//播放按钮也关闭}else{now_mode[0] = 1;//切换为智能模式now_mode[1] = 0;//界面默认第一个now_mode[2] = 0;//播放按钮也关闭}}//然后跳到下一位,接着判断是否重合if(button_deal >= 5) //队尾始终为空,向目标前进{button_deal = 0;}else{button_deal++;}}//可以接受新命令button_atom = 0;
}
注意, 我们这里队首处理完按键,并没有清除其数据, 而是位序往后走, 去覆盖了,队尾移动到此处, 相当于默认此处数据可覆盖, 所以就默认清除了. 要注意,同时我们也可以进行清除, 处理完队头后, 对数组此处赋值一个特定的数值, 方便后续我们调试.
相关文章:

利用队列收集单双击和长按按键
利用队列收集单双击和长按按键 引言 当我们仅仅通过在while循环里面进行判断按键类型的标志位, 然后进行操作的时候, 我们的最小例程很小, 所以能够实时的检测到按键,从而触发实验现象. 假如我们此时进入了一个事件处理函数呢 ? 并且这个这个函数的操作是不可被打断的, 如果此…...

AI工作流:低代码时代的革新者,重塑手机问答类应用生态
在这个数字化迅猛发展的时代,低代码技术正以惊人的速度改变着我们的生活方式。作为低代码人群的先锋,AI工作流技术正在以前所未有的方式,赋予非技术人群实现梦想的能力 🔥能用AI-低代码传送门:https://www.nyai.chat …...

配置MySQL主从,配置MySQL主主 +keeplive高可用
在大数据-Hadoop体系中 配置MySQL主主keeplive高可用 注意:这个是我两年前的word文档,可以当作参考文档有个思路参考一下,但是里面可能有些地方有误 另外 :关于一些企业级实战技术可以参考这篇mysql 物理备份 MySQL 全量备份 增量备份 差异…...

第5节:Elasticsearch核心概念
我的后端学习笔记大纲 我的ElasticSearch学习大纲 1.Lucene和Elasticsearch的关系: 1.Lucene:最先进、功能最强大的搜索库,直接基于lucene开发,非常复杂,api复杂2.Elasticsearch:基于lucene,封装了许多luc…...

存储实验:华为异构存储在线接管与在线数据迁移(Smart Virtualization Smart Migration 特性)
目录 目的实验环境实验步骤参考文档1. 主机安装存储多路径2. v2存储创建Lun,映射给主机;主机分区格式化,写数据3. 将v2存储映射该成映射到v3存储上(v3存储和v2之间链路搭建,测通,远端设备)(Smar…...

职业院校云计算实训室建设方案全景剖析
在信息化社会的今天,云计算作为一项关键技术,正在迅速改变着教育和培训的方式。本文旨在探讨如何通过"职业院校云计算实训室建设方案",为学生提供一个现代化、高效的学习和研究环境,以适应云计算技术的发展和市场需求。…...
VS Code安装与vue项目新建
1、下载安装node.js、VS Code node.js官网下载 Visual Studio Code官网下载 # 查看node.js是否安装成功 node -v npm -v # 定义镜像路径 npm config set registry https://registry.npmmirror.com # 查看是否配置成功 npm config get# 安装webpack npm install webpack -g #…...
如何在Java中将数据库查询结果转换为枚举类型
前言 在开发过程中,我们经常需要将从数据库获取的字符串或数字转换为更具语义的枚举类型。这不仅可以提高代码的可读性,还可以确保类型安全。这时候我们从数据库查出来的值如何通过枚举转换返回? 1. 构建枚举类型 首先,我们需要…...

秋招突击——8、20——知识补充——Java容器
文章目录 引言正文总览ArrayListLinkedListQueue & Stack & ArrayDequePriorityQueueHashSet & HashMapLinkedHashSet & LinkedHashMapTreeSet & TreeMap 面…...
IOS 06 OC调用Swift第三方框架
前面文章05讲的是在OC项目中,调用Swift代码,而在真实开发过程中,在OC项目中调用Swift第三方框架场景用的是非常多的,所以我们也了解在OC项目如何使用Swift写的三方框架。 实现流程: 1、OCUseSwiftTest;在…...

SAP和致远OA系统集成案例
一、项目介绍 重庆某控股(集团)有限公司是一家集合汽柴油动力及终端、摩托车、储能电源、汽车零部件、金融服务等产业的多元化集团公司,业务遍布全球80多个国家及地区,2021年营业收入达80亿元。 为推动集团信息化、数字化转型…...

19 OptionMenu 组件
OptionMenu 组件使用指南 Tkinter 的 OptionMenu 组件是一个下拉选择框,允许用户从一组预定义的选项中选择一个。它通常用于提供用户一个有限的选项集合来选择。以下是对 OptionMenu 组件的详细说明和一个使用案例。 OptionMenu 组件属性 variable: 与 OptionMen…...

【C语言】字符函数与字符串函数(上)
字符函数与字符串函数(上) 文章目录 字符函数与字符串函数(上)1.字符分类函数2.字符转换函数3.strlen的使用和模拟实现3.1使用示例:3.2模拟实现 4.strcpy的使用和模拟实现4.1使用示例:4.2模拟实现 5.strcat的使用和模拟…...

机器学习系列—深入探索弗里德曼检验:非参数统计分析的利器
🌟🌟 欢迎来到我的技术小筑,一个专为技术探索者打造的交流空间。在这里,我们不仅分享代码的智慧,还探讨技术的深度与广度。无论您是资深开发者还是技术新手,这里都有一片属于您的天空。让我们在知识的海洋中…...
【ubutnu18.04】k8s 部署4: worker节点配置1.31.0和containerd 1.7.20
上一篇:【ubutnu24.04】k8s部署3:重新安装1.31.0并init成功 worker 节点之一是ubuntu18.04主要参考 How Install Kubernetes on Ubuntu 24.04 (Step-by-Step Guide) 重点参考 ubuntu24.04 作为master反复配置kubelet root@PerfSvr:/home/zhangbin/perfwork/k8sadmin# sudo kub…...
android kotlin集成WorkManager实现定时获取数据
在Android中使用Kotlin集成WorkManager来实现定时获取数据是一个很常见的需求。WorkManager可以帮助你在设备处于闲置或应用被关闭时执行后台任务,特别适用于需要在特定时间间隔内重复执行的任务。以下是实现步骤: 1. 添加依赖项 首先,在你…...

BvSP_ Broad-view Soft Prompting for Few-Shot Aspect Sentiment Quad Prediction
BvSP: Broad-view Soft Prompting for Few-Shot Aspect Sentiment Quad Prediction 英文题目BvSP: Broad-view Soft Prompting for Few-Shot Aspect Sentiment Quad Prediction中文题目BvSP:面向少样本方面情感四元预测的广视角软提示论文地址aclanthology.org/202…...

React+Vis.js(05):vis.js的节点的点击事件
文章目录 需求实现思路抽屉实现完整代码需求 双击节点,弹出右侧的“抽屉”,显示节点的详细信息 实现思路 vis.network提供了一个doubleClick事件,代码如下: network.on(doubleClick, function (properties) {// console.log(nodes);let id = properties...
今日(2024 年 8 月 19 日)科技新闻
科大讯飞推出星火极速超拟人交互:8 月 19 日,科大讯飞宣布星火语音大模型更新,正式推出星火极速超拟人交互,并将其能力落地在讯飞星火 APP “小星畅聊” 功能中。该交互响应速度更快,能感知用户情绪变化并共情回应&…...
Python 虚拟环境
为什么要创建虚拟环境 创建 Python 虚拟环境的主要目的是为了解决依赖管理的问题,特别是在开发多个项目或部署应用程序时,虚拟环境具有以下几个优势: 依赖隔离: 不同的项目可能需要不同版本的 Python 解释器和库。通过创建虚拟环…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...

定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...