feat: signal and slot principles; and moc principles (what is done)

signal 和 slot 原理;以及 moc 原理(做了什么内容)
This commit is contained in:
xmuli
2021-03-26 16:22:47 +08:00
parent 8bc8b0b039
commit f9e224204d
6 changed files with 141 additions and 4 deletions

View File

@@ -3,4 +3,4 @@ project(DbSigSlot)
set(CMAKE_CXX_STANDARD 14)
add_executable(DbSigSlot main.cpp object.cpp object.h)
add_executable(DbSigSlot main.cpp object.cpp object.h db_object.cpp)

29
DbSigSlot/db_object.cpp Normal file
View File

@@ -0,0 +1,29 @@
#include "object.h"
//db_object: 是由 moc 编译器 将 object.cpp 展开的内容(此处手写表示)
const char sig_names[] = "sig1()";
const char slot_names[] = "slot1()";
MetaObject Object::meta = {sig_names, slot_names};
void Object::sig1()
{
MetaObject::active(this, 0);
}
void Object::slot1()
{
cout << "-----------> this is slot1()";
}
// 槽的索引==> 槽函数
void Object::metacall(int idx)
{
switch (idx) {
case 0:
slot1();
break;
default:
break;
}
}

View File

@@ -1,8 +1,19 @@
#include <iostream>
#include "object.h"
using namespace std;
// 目的:自行构造 moc 编译器,手动将 object.h --> db_bject.cpp (宏 和 moc 编译器处理的部分)
// 时间2021-003-26
// 作者:偕臧 ifmet.cn
// 下载https://github.com/xmuli/QtExamples
// 参考https://blog.csdn.net/perfectguyipeng/article/details/78082360
int main(int argc, char *argv[])
{
Object *obj1 = new Object();
Object *obj2 = new Object();
Object::db_connet(obj1, "sig1()", obj2, "slot1()");
obj1->testSignal();
return 0;
}

View File

@@ -1,6 +1,56 @@
#include "object.h"
#include <cstring>
static int findSignalIndex(const char *str, const char *subStr)
{
if (!str || !subStr || strlen(str) < strlen(subStr))
return -1;
int ret = strcmp(str, subStr);
if (ret == 0)
return ret;
else
return -1;
}
void Object::db_connet(Object *sender, const char *sig, Object *receiver, const char *slot)
{
int sig_idx = findSignalIndex(sender->meta.sig_names, sig);
int slot_idx = findSignalIndex(receiver->meta.slot_names, slot);
if (sig_idx == -1 || slot_idx == -1) {
cout<<"signal or slot not found!";
return;
} else {
Connection c = {receiver, slot_idx};
sender->connectionsMap.insert(pair<int, Connection>(sig_idx, c)); // connectionsMap 私有成员
}
}
void Object::testSignal()
{
db_emit sig1();
}
Object::Object()
{
}
Object::~Object()
{
}
// 通过 sender 的信号 idx ==> 槽函数
void MetaObject::active(Object *sender, int idx)
{
pair<ConnectionMapIt, ConnectionMapIt> ret;
ret = sender->connectionsMap.equal_range(idx); // 寻找[idx, )
for (ConnectionMapIt it = ret.first; it != ret.second; ++it) {
Connection c = (*it).second;
c.recviver->metacall(idx);
}
}

View File

@@ -1,11 +1,56 @@
#ifndef OBJECT_H
#define OBJECT_H
#include <iostream>
#include <map>
using namespace std;
#define db_signals protected
#define db_slots
#define db_emit
class Object;
struct MetaObject // 元对象
{
const char *sig_names;
const char *slot_names;
static void active(Object *sender, int idx);
};
struct Connection
{
Object *recviver;
int method;
};
typedef multimap<int, Connection> ConnectionMap;
typedef multimap<int, Connection>::iterator ConnectionMapIt;
class Object
{
static MetaObject meta;
void metacall(int idx);
public:
static void db_connet(Object *sender, const char *sig, Object *receiver, const char *slot);
void testSignal();
public:
Object();
virtual ~Object();
db_signals:
void sig1();
// void sig2();
public db_slots:
void slot1();
// void slot2();
friend class MetaObject;
private:
ConnectionMap connectionsMap;
};
#endif // OBJECT_H
#endif // OBJECT_H