sig/slot

Posted 自由度

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sig/slot相关的知识,希望对你有一定的参考价值。

2014-06-28 星期六 18:44:51 技术分享

开源的有

libsigc++,

简单代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#include <algorithm>
#include <iostream>
#include <vector>
#include <stdio.h>
 
/*
Slot        一个对象和其对应的pfunc
Signal  媒介,保存Slot Node
emitter "知晓"(一般是聚合)Signal并发起Signal
*/
using namespace std;
 
template<typename T1>
class SlotBase
{
public:
    virtual void Exec(T1 param1) = 0;
};
 
template<typename T, typename T1>
class SlotImpl : public SlotBase<T1>
{
public:
    SlotImpl(T* pObj, void (T::*func)(T1))
    {
        m_pObj = pObj;
        m_Func = func;
    }
 
    void Exec( T1 param1)
    {
        (m_pObj->*m_Func)(param1);
    }
 
private:
    T* m_pObj;
    void (T::*m_Func)(T1);
};
 
 
//node
template<typename T1>
class Slot
{
public:
    template<typename T>
    Slot(T* pObj, void (T::*func)(T1))
    {
        m_pSlotBase = new SlotImpl<T,T1>(pObj, func);
    }
 
    ~Slot()
    {
        delete m_pSlotBase;
    }
 
    void Exec(T1 param1)
    {
        m_pSlotBase->Exec(param1);
    }
 
private:
    SlotBase<T1>* m_pSlotBase;
};
 
 
//veteor <node> m_node
template<typename T1>
class Signal
{
public:
    template<typename T>
    void Bind(T* pObj, void (T::*func)(T1))
    {
        m_pSlotSet.push_back( new Slot<T1>(pObj,func) );
    }
 
    ~Signal()
    {
        for(int i=0;i<(int)m_pSlotSet.size();i++)
        {
            delete m_pSlotSet[i];
        }
    }
 
    //Functor
    void operator()(T1 param1)
    {
        for(int i=0;i<(int)m_pSlotSet.size();i++)
        {
            m_pSlotSet[i]->Exec(param1);
        }
    }
 
private:
    vector< Slot<T1>* > m_pSlotSet;
};
 
#define Connect( sender, signal, receiver, method) ( (sender)->signal.Bind(receiver, method) )
 
class CRecv0
{
public:
    void FuncRecv0(int param)
    {
        printf("CRecv0::FuncRecv0(%d)\n", param);
    }
};
 
class CRecv1
{
public:
    void FuncRecv1(int param)
    {
        printf("CRecv1::FuncRecv1(%d)\n", param);
    }
};
 
//emitter
class CEmit
{
public:
    CEmit()
    {
        m_Value = 0;
    }
    void EmitValue(int value)
    {
        if(m_Value != value)
        {
            m_Value = value;
            SigValue(m_Value);
        }
    }
     
public:
    Signal<int> SigValue;
 
private:
    int m_Value;
};
 
int main()
{
    CRecv0* pRecv0 = new CRecv0;
    CRecv1* pRecv1 = new CRecv1;
    CEmit*  pEmit  = new CEmit;
 
    Connect(pEmit, SigValue, pRecv0, &CRecv0::FuncRecv0);
    Connect(pEmit, SigValue, pRecv1, &CRecv1::FuncRecv1);
 
    pEmit->EmitValue(10);
    pEmit->EmitValue(5);
    pEmit->EmitValue(2);
 
    delete pEmit;
    delete pRecv0;
    delete pRecv1;
    return 0;
}


另一个libjingel中的signal/slot,分析见http://my.oschina.net/tianxialangui/blog/67005

demo如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
#include "sigslot_libjingle.h"
using namespace sigslot;
 
#if 1
struct dog
{
    signal1<std::string &> bark;
    void beaten()
    {
        std::string w = "wangwangwang";
        bark(w); // 娑堟伅浜х敓
    }
};
 
struct human : public has_slots<>
{
    void action0(std::string &w)
    {
       std::cout << "action0:" << w.c_str() << std::endl;
    }
      
    void action1(std::string &w)
    {
       std::cout << "action1:" << w.c_str() << std::endl;
    }
};
 
int main()
{
    dog d;
    human man;
    d.bark.connect(&man, &human::action0);
    //d.beaten();
   
    d.bark.connect(&man, &human::action1);
 
    std::string w0 = "www0";
    d.bark(w0);
 
    std::string w1 = "www1";
    //emit all
    //d.bark.emit(w);
    d.bark(w1);
     
    d.bark.disconnect(&man);
    return 0;
}
#endif

这个的耦合度基本为零。














以上是关于sig/slot的主要内容,如果未能解决你的问题,请参考以下文章

Gtalk源码剖析之:sigslot介绍

Gtalk源码剖析之:sigslot介绍

微信小程序代码片段

VSCode自定义代码片段——CSS选择器

谷歌浏览器调试jsp 引入代码片段,如何调试代码片段中的js

片段和活动之间的核心区别是啥?哪些代码可以写成片段?