C++ 仿QT信号槽二

news2024/12/28 3:34:45

// 实现原理
// 每个signal映射到bitset位,全集
// 每个slot做为signal的bitset子集
// signal全集触发,标志位有效
// flip将触发事件队列前置
// slot检测智能指针全集触发的标志位,主动运行子集绑定的函数
// 下一帧对bitset全集进行触发清空,防止slot一直检测到signal触发

#include <any>
#include <iostream>

#include "blinker.h"

void testMatch() {
    blinker::SignalTrie<1024> trie;
    trie.Put("ab.cd.ef", 1);
    trie.Put("ab.cd.kk", 2);
    trie.Put("ab.xy.zz", 3);
    trie.Put("tt.xx", 4);
    trie.Put("ab.cd", 5);

    auto m1 = trie.Match("ab.cd.ef");
    //REQUIRE(m1.count() == 1);
    //REQUIRE(m1[1]);

    auto m2 = trie.Match("ab.cd.kk");
    //REQUIRE(m2.count() == 1);
    //REQUIRE(m2[2]);

    auto m3 = trie.Match("ab.xy.zz");
    //REQUIRE(m3.count() == 1);
    //REQUIRE(m3[3]);

    auto m4 = trie.Match("ab.not.found");
    //REQUIRE(m4.count() == 0);

    auto m5 = trie.Match("ab.*");
    //REQUIRE(m5.count() == 4);
    //REQUIRE(m5[1]);
    //REQUIRE(m5[2]);
    //REQUIRE(m5[3]);
    //REQUIRE(m5[5]);

    auto m6 = trie.Match("*");
    //REQUIRE(m6.count() == 5);
    //REQUIRE(m6[1]);
    //REQUIRE(m6[2]);
    //REQUIRE(m6[3]);
    //REQUIRE(m6[4]);
    //REQUIRE(m6[5]);

    auto m7 = trie.Match("ab.cd.*");
    //REQUIRE(m7.count() == 2);
    //REQUIRE(m7[1]);
    //REQUIRE(m7[2]);

    auto m8 = trie.Match("tt.xx.");
    //REQUIRE(m8.count() == 0);

    auto m9 = trie.Match("tt.xx.*");
    //REQUIRE(m9.count() == 0);

    auto m10 = trie.Match("ab.cd");
    //REQUIRE(m10.count() == 1);
    //REQUIRE(m10[5]);
}

void testValue() {
    struct Data {
        int value = 1;
        Data(int value) : value(value) {}
    };

    blinker::Board board;

    auto signal1 = board.NewSignal("ab.cd");
    auto signal2 = board.NewSignal("ab.ef");
    auto signal3 = board.NewSignal("xy.zk");

    auto conn1 = board.Connect("ab.*");
    auto conn2 = board.Connect("ab.cd");
    auto conn3 = board.Connect("ab.ef");
    auto conn4 = board.Connect("xy.zk");
    auto conn5 = board.Connect("*");

    bool conn1CallbackCalled = false;
    bool conn2CallbackCalled = false;
    bool conn3CallbackCalled = false;
    bool conn4CallbackCalled = false;
    bool conn5CallbackCalled = false;

    auto tick = [&]() {
        signal1->Emit(std::make_shared<Data>(1));
        signal2->Emit(std::make_shared<Data>(2));
        signal3->Emit(std::make_shared<Data>(3));

        // signal1 and signal2
        conn1->Poll([&](const blinker::SignalId id, std::any data) {
            conn1CallbackCalled = true;
            auto p = std::any_cast<std::shared_ptr<Data>>(data);
            if (id == signal1->Id())
                std::cout << "value: " << p->value << std::endl;
            else if (id == signal2->Id())
                std::cout << "value: " << p->value << std::endl;
            else
                std::cout << "value error!" << std::endl;
            });

        // signal1
        conn2->Poll([&](const blinker::SignalId id, std::any data) {
            conn2CallbackCalled = true;
            auto p = std::any_cast<std::shared_ptr<Data>>(data);
            if (id == signal1->Id())
                std::cout << "value: " << p->value << std::endl;
            else
                std::cout << "value error!" << std::endl;
            });

        // signal2
        conn3->Poll([&](const blinker::SignalId id, std::any data) {
            conn3CallbackCalled = true;
            auto p = std::any_cast<std::shared_ptr<Data>>(data);
            if (id == signal2->Id())
                std::cout << "value: " << p->value << std::endl;
            else
                std::cout << "value error!" << std::endl;
            });

        // signal3
        conn4->Poll([&](const blinker::SignalId id, std::any data) {
            conn4CallbackCalled = true;
            auto p = std::any_cast<std::shared_ptr<Data>>(data);
            if (id == signal3->Id())
                std::cout << "value: " << p->value << std::endl;
            else                
                std::cout << "value error!" << std::endl;
            });

        // all signals
        conn5->Poll([&](const blinker::SignalId id, std::any data) {
            conn5CallbackCalled = true;
            auto p = std::any_cast<std::shared_ptr<Data>>(data);
            if (id == signal1->Id())
                std::cout << "value: " << p->value << std::endl;
            else if (id == signal2->Id())
                std::cout << "value: " << p->value << std::endl;
            else if (id == signal3->Id())
                std::cout << "value: " << p->value << std::endl;
            else
                std::cout << "value error!" << std::endl;
            });

        board.Flip();
        };

    tick();
    // still not called.
    tick();
    // called after flip
}

int testLoops() {
    // Creates a board.
    blinker::Board board;

    // Creates signals.
    auto taskStarted = board.NewSignal("task.started");
    auto taskEnded = board.NewSignal("task.ended");
    auto actionStarted = board.NewSignal("action.started");

    // Creates connection to match some signals.
    auto connection = board.Connect("task.*");

    // Callback to be called on signal fire.
    auto callback = [&](const blinker::SignalId id, std::any data) {
        if (id == taskStarted->Id())
            std::cout << "signal taskStarted:";
        else if (id == taskEnded->Id())
            std::cout << "signal taskEnded:";
        else if (id == actionStarted->Id())
            std::cout << "signal actionStarted-:";
        std::cout << std::any_cast<int>(data) << std::endl;
        };

    // Assuming your main tick function here.
    for (int i = 0; i < 10; i++) {
        // Emit some signals (to backend).
        taskStarted->Emit(i);
        taskEnded->Emit(i);
        actionStarted->Emit(i);

        // Poll from frontend.
        connection->Poll(callback);

        // Flip double buffers.
        board.Flip();
    }

    return 0;
}

void test() {
    testMatch();
    testValue();
    testLoops();
}

输出

value: 1
value: 2
value: 1
value: 2
value: 3
value: 1
value: 2
value: 3
signal taskStarted:0
signal taskEnded:0
signal taskStarted:1
signal taskEnded:1
signal taskStarted:2
signal taskEnded:2
signal taskStarted:3
signal taskEnded:3
signal taskStarted:4
signal taskEnded:4
signal taskStarted:5
signal taskEnded:5
signal taskStarted:6
signal taskEnded:6
signal taskStarted:7
signal taskEnded:7
signal taskStarted:8
signal taskEnded:8

参考

GitHub - hit9/blinker.h: A lightweight signal/event library for C++, similar to Python's blinker, but designed to work with ticking loops.


创作不易,小小的支持一下吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1898470.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

玩转内网穿透详细教程,收藏这一篇就够了

小朋友&#xff0c;你是否有过以下这些烦恼&#xff1f; 当你在外地&#xff0c;苦于无法拿到存储在家里的资料&#xff1b; 当你在玩游戏的时候&#xff0c;苦于无法和朋友直接联机&#xff1b; 当你在家里&#xff0c;苦于无法通过自己的电脑连上公司电脑远程办公&#xf…

论文导读 | 综述:大模型与推荐系统

最近&#xff0c;预训练语言模型&#xff08;PLM&#xff09;在自然语言处理领域取得了巨大成功&#xff0c;并逐渐引入推荐系统领域。本篇推文介绍了最近的两篇预训练语言模型和推荐系统结合的综述&#xff1a; [1] Pre-train, Prompt, and Recommendation: A Comprehensive …

Django学习第五天

启动项目命令 python manage.py runserver 图像验证码生成随机字母或者数字 import random from PIL import Image, ImageDraw, ImageFont, ImageFilterdef check_code(width120, height40, char_length5, font_fileZixunHappyBold.ttf, font_size28):code []img Image.new…

《后端程序猿 · Caffeine 本地缓存》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻一周&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…

4、SSD主控

简述 主控是个片上系统&#xff0c;由硬件和固件组成一个功能完整的系统&#xff1b;上文所述的FTL就属于主控的固件范畴。主控闪存构成了整个SSD&#xff0c;在闪存确定的情况下&#xff0c;主控就反映了各家SSD的差异。实时上各家SSD的差异也主要反应在主控上&#xff0c;毕…

TCP和IP数据包结构

一、问题引入 一般我们在谈上网速度的时候&#xff0c;专业上用带宽来描述&#xff0c;其实无论说网速或者带宽都是不准确的&#xff0c;呵呵。比如&#xff1a;1兆&#xff0c;512K……有些在学校的学生&#xff0c;也许会有疑问&#xff0c;明明我的业务是1M&#xff0c;为…

打开浏览器控制台,点击应用,浏览器崩溃

调试的时候&#xff0c;打开控制台&#xff0c;点击 “应用” 立马浏览器奔溃&#xff0c;但是点击别的没问题 调查发现是因为manifest.json这个文件引起的 manifest.json 最主要的原因是因为没有设置这个sizes字段 Google浏览器更新大概到126之后的版本会有问题&#xff0c;之…

vuepress使用简介及个人博客搭建

目录 一、介绍二、环境准备三、安装运行vuepress四、目录结构五、配置文件六、导航栏配置七、导航栏logo八、浏览器图标九、侧边栏配置十、添加 Git 仓库和编辑链接十一、部署到GitHub十二、搭建成功 一、介绍 VuePress 是 Vuejs 官方提供的一个是Vue驱动的静态网站生成器&…

10.09面试题目记录

艾融软件 - 线上面试题 排序算法的时间复杂度 O(n^2&#xff09;&#xff1a;冒泡&#xff0c;选择&#xff0c;插入 O(logn&#xff09;&#xff1a;折半插入排序 O(nlogn)&#xff1a;希尔&#xff0c;归并&#xff0c;快速&#xff0c;堆 O(nk)&#xff1a;桶&#xff0c;…

12款超良心好用APP推荐,每一款都值得下载!

AI视频生成&#xff1a;小说文案智能分镜智能识别角色和场景批量Ai绘图自动配音添加音乐一键合成视频https://aitools.jurilu.com/分享是奉献的果实&#xff0c;分享是快乐的前提。每天给小伙伴们分享自己认可的软件&#xff0c;也是莫大的幸福&#xff0c;今天获得12款好用的软…

【qt】如何获取本机的IP地址?

需要用到这个类QHostInfo和pro里面添加network模块 用这个类的静态函数forName()来获取该主机名的信息 返回的就是这个类 这个QHostInfo类就包括主机的IP地址信息 用静态函数addresses()来获取 返回的是一个QHostAddress的容器 QList<QHostAddress>addrList hostIn…

基于React和TypeScript的开源白板项目(Github项目分享)

在学习前端开发的过程中&#xff0c;有时候我们需要一些有趣的项目来提升我们的技能。今天我要给大家介绍的是一个非常酷的项目——NinjaSketch&#xff0c;这是一个用React和TypeScript构建的简易白板工具。这个项目使用了Rough.js来实现手绘风格的效果。尽管这个应用不是响应…

知识图谱和 LLM:多跳问答

检索增强生成&#xff08;RAG&#xff09;应用程序通过将外部来源的数据集成到 LLM 中&#xff0c;擅长回答简单的问题。但他们很难回答涉及将相关信息之间的点连接起来的多部分问题。这是因为 RAG 应用程序需要一个数据库&#xff0c;该数据库旨在存储数据&#xff0c;以便轻松…

html+js+css在线倒计时

代码在图片后面 点赞加关注 谢谢大佬照顾&#x1f61c; 图例 时间到前 时间到后 源代码 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width,…

Docker:三、安装nginx与tomcat

&#x1f341;安装常见服务 &#x1f332;安装nginx &#x1f9ca;1、搜索镜像 Ⅰ.hub docker上查询&#xff1a;https://hub.docker.com/_/nginx Ⅱ. 命令查询&#xff1a;docker search nginx &#x1f9ca;2、下载镜像 命令&#xff1a;docker pull nginx &#x1f9c…

google 邮件信息收集

主要介绍通过google和fofax对目标进行邮件信息收集 chrome插件 email-whatsapp-extractor link-klipper-extract-all bulk-url-opener-extension email-whatsapp-extractor 使用正则表达式&#xff0c;获取访问页面内所有的email邮箱和whatsapp号码&#xff0c;以表格的形式导…

vulnhub--IMF

环境 攻击机&#xff1a;192.168.96.4 靶机&#xff1a;ip未知 主机探测 确定靶机ip为32的主机 端口扫描 访问80端口 外围打点 在contact.php页面源码中找到了flag1 之后没啥突破 但查看网络后发现contact.php页面请求的三个js文件的文件名很有特点&#xff0c;猜测是base64编码…

奥比中光astra_pro相机使用记录

一、信息获取 1、官网 用于了解产品信息 http://www.orbbec.com.cn/sys/37.html 2、开发者社区 咨询问题下载开发部https://developer.orbbec.com.cn/ 二 、windowvs19 1、相机型号 orbbec_astro_pro 根据对应的型号找到需要的包工具 踩坑1&#xff0c;因为这个相机型号…

C++ UTF-8编解码

icu 编解码数据&#xff1a; extern const UConverterSharedData _MBCSData, _Latin1Data, _UTF8Data, _UTF16BEData, _UTF16LEData, _UTF32BEData, _UTF32LEData, _ISO2022Data, _LMBCSData1,_LMBCSData2, _LMBCSData3, _LMBCSData4, _LMBCSData5, _LMBCSDat…

数字信号处理及MATLAB仿真(2)——离散系统

上回书说到如何来编写一些简单的离散时间序列&#xff0c;今天咱们就来谈谈一些关于常系数差分方程的操作吧。 说到这里咱们对于常系数差分方程可能最关心的就是怎么去求解了。 其中最关键的部分就是filter函数&#xff0c;可以用来计算系统在输入信号为x的输出信号y。大家学过…