23 Star 89 Fork 49

类似Qt / 信号槽 v11

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
gObject.h 7.15 KB
一键复制 编辑 原始数据 按行查看 历史
类似Qt 提交于 2020-06-22 11:32 . new syntax
/*
* Copyright (C) 2020 明心 <imleizhang@qq.com>
* All rights reserved.
*
* This program is an open-source software; and it is distributed in the hope
* that it will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE.
* This program is not a free software; so you can not redistribute it(include
* binary form and source code form) without my authorization. And if you
* need use it for any commercial purpose, you should first get commercial
* authorization from me, otherwise there will be your's legal&credit risks.
*
*/
#ifndef GOBJECT_H
#define GOBJECT_H
#include <string>
#include <cxxabi.h>
#include <list>
#include <stdio.h>
using namespace std;
class GObjectPrivate;
class GObject;
#define slots
enum E_SLOT_TYPE
{
C_SLOT_TYPE,
CPP_SLOT_TYPE,
};
template<typename F>
class GSlotAPI;
template<typename Ret, typename ...Args>
class GSlotAPI<Ret(Args...)>
{
public:
E_SLOT_TYPE type() const
{
return m_type;
}
public:
explicit GSlotAPI(void* slot, GObject* receiver=NULL, E_SLOT_TYPE t=C_SLOT_TYPE )
:m_receiver(receiver),
m_slot(slot),
m_type(t)
{
}
virtual ~GSlotAPI() {}
virtual void operator() ( Args&... args ) = 0;
private:
GSlotAPI &operator= ( const GSlotAPI & ) = delete;
public:
bool operator==(const GSlotAPI& other)
{
return other.m_type == m_type
&& other.m_slot == m_slot
&& other.m_receiver == m_receiver ;
}
public:
GObject* m_receiver;
protected:
void* m_slot;
private:
E_SLOT_TYPE m_type;
};
template<typename Receiver, typename F>
class GSlotCpp;
template<typename Receiver, typename Ret, typename ...Args>
class GSlotCpp<Receiver, Ret(Args...)> : public GSlotAPI<Ret(Args...)>
{
public:
typedef void ( Receiver::*SlotFuncType ) ( Args... );
GSlotCpp ( Receiver* r, SlotFuncType slot )
: GSlotAPI<Ret(Args...)>( (void*)slot, (GObject*)r, CPP_SLOT_TYPE),
m_class_slot(slot)
{
}
virtual ~GSlotCpp() {}
public:
void operator() ( Args&... args )
{
( ( (Receiver*)GSlotAPI<Ret(Args...)>::m_receiver)->*m_class_slot ) ( args... );
}
private:
SlotFuncType m_class_slot;
};
/**
* @class GSignal
* @brief GSignal 类用来定义信号,所述信号的函数类型为Ret (*)(Args...)。\n
* 比如:GSignal<void(int)> intSig;//定义一个函数类型为void intSig(int);
* 比如:GSignal<void(int, float)> ifSig;//定义一个函数类型为void ifSig(int, float);
*
*/
template<typename F>
class GSignal;
template<typename Ret, typename... Args>
class GSignal<Ret(Args...)>
{
public:
typedef list<GSlotAPI<Ret(Args...)>* > SlotLstType;
public:
/**
* @brief 发射信号
*
* @param args 参数列表
* @return void
*/
void emit ( Args... args )
{
for ( auto it : _slotLst )
{
( *it ) ( args... );
}
}
/**
* @brief 发射信号
*
* @param args 参数列表
* @return void
*/
void operator() ( Args... args )
{
for ( auto it : _slotLst )
{
( *it ) ( args... );
}
}
public:
SlotLstType _slotLst;
};
class GSlot
{
public:
E_SLOT_TYPE type() const
{
return m_type;
}
public:
explicit GSlot(void* slot, GObject* receiver=NULL, E_SLOT_TYPE t=C_SLOT_TYPE )
:m_receiver(receiver),
m_slot(slot),
m_type(t)
{
}
virtual ~GSlot() {}
virtual void operator() ( const GSlot& );
private:
GSlot &operator= ( const GSlot & ) = delete;
public:
bool operator==(const GSlot& other)
{
return other.m_type == m_type
&& other.m_slot == m_slot
&& other.m_receiver == m_receiver ;
}
public:
GObject* m_receiver;
protected:
void* m_slot;
private:
E_SLOT_TYPE m_type;
};
#define SIGNAL_TYPE list<GSlot*>
#define SIGNAL_POINTER list<GSlot*>*
#define SIGNAL_TYPE_ITERATOR list<GSlot*>::iterator
#define signals public
#define SET_CLASS_NAME(any_type) \
public: \
virtual const char *className() const \
{ \
static string s_name; \
char* name = abi::__cxa_demangle(typeid(any_type).name(), NULL, NULL, NULL); \
s_name = name; \
free(name); \
return s_name.c_str(); \
}
class GObject
{
SET_CLASS_NAME(GObject)
signals:
GSignal<void(void)> sigDestroyed;
private:
GObjectPrivate *m_priv;
public:
explicit GObject ( GObject *parent=NULL, const char *name=NULL );
GObject ( const GObject & src );
GObject & operator= ( const GObject & src );
virtual ~GObject();
/**
* @brief 将信号和槽建立连接。\n
* Receiver代表接收者的类型
* Args是槽函数/信号的参数列表。
*
* @param sender 指向发射者的指针
* @param signal 指向信号的引用。
* @param receiver 指向接收者的指针
* @param slot 指向槽函数的指针
*
* @return 0代表成功;非0代表失败
*/
template<class Receiver, typename ...Args>
static int connect ( GObject* sender, GSignal<void(Args...)>& signal, Receiver* receiver, void ( Receiver::*SlotFunc ) ( Args... ) );
/**
* @brief 将信号和槽断开连接。\n
* Receiver代表接收者的类型
* Args是槽函数/信号的参数列表。
*
* @param sender 指向发射者的指针
* @param signal 指向信号的引用。
* @param receiver 指向接收者的指针
* @param slot 指向槽函数的指针
*
* @return 0代表成功;非0代表失败
*/
template<class Receiver, typename ...Args>
static int disconnect ( GObject* sender, GSignal<void(Args...)>& signal, Receiver* receiver, void ( Receiver::*SlotFunc ) ( Args... ) );
const char *name() const;
GObject *parent() const;
private:
static int privConnect(GObject* sender, SIGNAL_POINTER signal, GObject* receiver, void* slot);
static int privDisconnect(GObject* sender, SIGNAL_POINTER signal, GObject* receiver, void* slot);
void saveSenderPair(GObject* sender, SIGNAL_POINTER signal);
void deleteSenderPair(GObject* sender, SIGNAL_POINTER signal);
void destructAsReceiver();
void destructAsSender();
void saveReceiver ( GObject* receiver );
void deleteReceiver ( GObject* receiver );
};
template<class Receiver, typename ...Args>
int GObject::connect ( GObject* sender, GSignal<void(Args...)>& signal, Receiver* receiver, void ( Receiver::*SlotFunc ) ( Args... ) )
{
GSlotCpp<Receiver, void(Args...)> *vslot = new GSlotCpp<Receiver, void(Args...)>(receiver, SlotFunc);
int ret = privConnect(sender, reinterpret_cast<SIGNAL_POINTER>(&(signal._slotLst)), (GObject*)receiver, (void*)vslot);
if(0 != ret)
{
delete vslot;
}
return ret;
}
template<class Receiver, typename ...Args>
int GObject::disconnect ( GObject* sender, GSignal<void(Args...)>& signal, Receiver* receiver, void ( Receiver::*SlotFunc ) ( Args... ) )
{
int ret = privDisconnect(sender, reinterpret_cast<SIGNAL_POINTER>(&(signal._slotLst)), (GObject*)receiver, (void*)SlotFunc);
return ret;
}
#endif // GOBJECT_H
C++
1
https://gitee.com/giveda/gobject_cpp11.git
git@gitee.com:giveda/gobject_cpp11.git
giveda
gobject_cpp11
信号槽 v11
master

搜索帮助