-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexample.cpp
More file actions
158 lines (124 loc) · 6.84 KB
/
example.cpp
File metadata and controls
158 lines (124 loc) · 6.84 KB
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
/**
* @file example.cpp
* @brief Example coding demonstrating the usage of EasyDelegate.
* @date 7/11/2015
* @author <a href="https://dx.no-ip.org">Robert MacGregor</a>
*
* @copyright This software is licensed under the MIT license. Please refer to LICENSE.txt for more
* information.
*/
#define EASYDELEGATE_FORCE_INLINE
#include <set> // std::set
#include <unordered_set> // std::unordered_set
#include <iostream> // std::cout, std::endl
#include <easydelegate/easydelegate.hpp>
using namespace std;
unsigned int myStaticIntMethod(const char* str, const float& flt, const double& dbl)
{
cout << "myStaticIntMethod: " << str << "," << flt << "," << dbl << endl;
return 5;
}
void myStaticVoidMethod(const float& flt, const char* str, const double& dbl)
{
cout << "myStaticVoidMethod: " << flt << "," << str << "," << dbl << endl;
}
class MyCustomClass
{
public:
unsigned int myMemberMethod(const char* str, const float& flt, const double &dbl)
{
cout << "MyCustomClass::myMemberMethod: " << str << "," << flt << "," << dbl << endl;
return 2;
}
};
int main(int argc, char *argv[])
{
// You can typedef the actual delegate type to some type that's specific to your project
typedef EasyDelegate::DelegateSet<unsigned int, const char*, const float&, const double&> MyEventType;
typedef EasyDelegate::DelegateSet<void, const float&, const char*, const double&> VoidEventType;
MyEventType myDelegateSet;
MyCustomClass *myCustomClassInstance = new MyCustomClass();
// Register both our static function and our member function
myDelegateSet.push_back(new MyEventType::StaticDelegateType(myStaticIntMethod));
myDelegateSet.push_back(new MyEventType::MemberDelegateType<MyCustomClass>(&MyCustomClass::myMemberMethod, myCustomClassInstance));
myDelegateSet.push_back(new MyEventType::FunctionDelegateType([](const char* str, const float& flt, const double& dbl)->unsigned int
{
cout << "A lambda call: " << str << ", " << flt << ", " << dbl << endl;
return 25;
}));
// This form works too.
myDelegateSet += new MyEventType::StaticDelegateType(myStaticIntMethod);
// Call the set via .invoke(), ignoring return values
cout << "------------- CALLING VIA .invoke() ---------------" << endl;
myDelegateSet.invoke("Foo", 3.14, 3.14159);
// Call the set via .invoke(), collecting returns into an std::set
cout << "------------- CALLING VIA .invoke(), Getting Returns ---------------" << endl;
MyEventType::ReturnSetType myReturnValues;
myDelegateSet.invoke(myReturnValues, "Foo", 3.14, 3.14159);
for (auto it = myReturnValues.begin(); it != myReturnValues.end(); it++)
cout << *it << endl;
// Iterate on our own, calling invoke() for each delegate
cout << "------- CUSTOM ITERATION --------" << endl;
for (auto it = myDelegateSet.begin(); it != myDelegateSet.end(); it++)
cout << (*it)->invoke("Foo", 3.14, 3.14159) << endl;
// Remove a static listener function by address
cout << "-------------- REMOVING STATIC LISTENERS -----------------" << endl;
myDelegateSet.removeDelegateByMethod(myStaticIntMethod);
myDelegateSet.invoke("Foo", 3.14, 3.14159);
// Remove a member listener function by address
cout << "-------------- REMOVING MEMBER LISTENERS -----------------" << endl;
myDelegateSet.push_back(new MyEventType::StaticDelegateType(myStaticIntMethod));
myDelegateSet.removeDelegateByMethod(&MyCustomClass::myMemberMethod);
myDelegateSet.invoke("Foo", 3.14, 3.14159);
// Remove a member listener function by this pointer
cout << "-------------- REMOVING MEMBER LISTENERS VIA THIS -----------------" << endl;
myDelegateSet.push_back(new MyEventType::MemberDelegateType<MyCustomClass>(&MyCustomClass::myMemberMethod, myCustomClassInstance));
myDelegateSet.removeDelegateByThisPointer(myCustomClassInstance);
myDelegateSet.invoke("Foo", 3.14, 3.14159);
// Remove a delegate by it's address
cout << "-------------- REMOVING DELEGATE VIA ADDRESS -----------------" << endl;
MyEventType::MemberDelegateType<MyCustomClass> *delegateToRemove = new MyEventType::MemberDelegateType<MyCustomClass>(&MyCustomClass::myMemberMethod, myCustomClassInstance);
myDelegateSet.push_back(delegateToRemove);
myDelegateSet.removeDelegate(delegateToRemove, false);
myDelegateSet.invoke("Foo", 3.14, 3.14159);
// delegateToRemove Still Exists
cout << "---------- Removed Delegate is still usable ------------" << endl;
delegateToRemove->invoke("Foo", 3.14, 3.14159);
// Create a cached delegate with the removed member delegate above
#ifndef EASYDELEGATE_NO_DEFERRED_CALLING
cout << "---------- DEFERRED CALLERS ---------------" << endl;
typedef EasyDelegate::DeferredMemberCaller<MyCustomClass, unsigned int, const char*, const float&, const double&> MyCachedIntMemberDelegateType;
typedef EasyDelegate::DeferredStaticCaller<void, const float&, const char*, const double&> MyCachedVoidStaticDelegateType;
// Allocate our delegate types
MyCachedIntMemberDelegateType* cachedMemberDelegate = new MyCachedIntMemberDelegateType(&MyCustomClass::myMemberMethod, myCustomClassInstance, "Cached", 3.14, 3.14159);
MyCachedVoidStaticDelegateType* cachedStaticDelegate = new MyCachedVoidStaticDelegateType(myStaticVoidMethod, 8.15f, "Cached", 3.14f);
// Now store these in a set
vector<EasyDelegate::IDeferredCaller *> delegates;
delegates.push_back(cachedMemberDelegate);
delegates.push_back(cachedStaticDelegate);
// Iterate
for (auto it = delegates.begin(); it != delegates.end(); ++it)
{
cout << "Invoking Delegate " << endl;
(*it)->genericDispatch();
}
#endif
// Comparisons
MyEventType::StaticDelegateType staticDelegateReference(myStaticIntMethod);
VoidEventType::StaticDelegateType staticVoidDelegateReference(myStaticVoidMethod);
MyEventType::MemberDelegateType<MyCustomClass> memberDelegateReference(&MyCustomClass::myMemberMethod, myCustomClassInstance);
cout << (staticDelegateReference.hasSameMethodAs(&staticDelegateReference)) << endl;
cout << (staticDelegateReference.hasSameMethodAs(&memberDelegateReference)) << endl;
cout << (memberDelegateReference.hasSameMethodAs(&memberDelegateReference)) << endl;
cout << (memberDelegateReference.hasSameMethodAs(&staticDelegateReference)) << endl;
// Unlike comparisons
cout << (staticDelegateReference.hasSameMethodAs(&staticVoidDelegateReference)) << endl;
cout << (memberDelegateReference.hasSameMethodAs(&staticVoidDelegateReference)) << endl;
// Cleanup
#ifndef EASYDELEGATE_NO_DEFERRED_CALLING
delete cachedMemberDelegate;
delete cachedStaticDelegate;
#endif
delete myCustomClassInstance;
return 0;
}