1 |
#!/usr/bin/perl |
2 |
# $Id: gencallbacks.pl,v 1.1 2007-07-19 08:24:50 pippijn Exp $ |
3 |
|
4 |
use strict; |
5 |
use warnings; |
6 |
use utf8; |
7 |
|
8 |
my $namespace = "callback"; |
9 |
my $events = $ARGV[0] || 0; |
10 |
|
11 |
$events > 1 |
12 |
or die "Usage: $0 NUMBER\nwhere NUMBER > 1."; |
13 |
|
14 |
my $gen = ""; |
15 |
|
16 |
for my $num (2 .. $events) { |
17 |
my @argt; |
18 |
my @argn; |
19 |
my $arg_type_list_named; |
20 |
|
21 |
for (1 .. $num) { |
22 |
my $a = "arg${_}_type"; |
23 |
my $aname = "a$_"; |
24 |
push @argt, $a; |
25 |
push @argn, $aname; |
26 |
$arg_type_list_named .= "$a $aname, "; |
27 |
} |
28 |
|
29 |
$arg_type_list_named =~ s/, *$//; |
30 |
|
31 |
my $arg_params_names = join ", ", @argn; |
32 |
my $arg_tmpl_decl = "class " . join ", class ", @argt; |
33 |
my $arg_type_list = join ", ", @argt; |
34 |
|
35 |
$gen .= <<EOF; |
36 |
////////////////////// events for $num arguments ////////////////////// |
37 |
// auto-generated by $0 |
38 |
// |
39 |
// tmpl decl = $arg_tmpl_decl |
40 |
// args = $arg_type_list |
41 |
// named args = $arg_type_list_named |
42 |
|
43 |
EOF |
44 |
|
45 |
######################################################################## |
46 |
# connection_base |
47 |
$gen .= <<EOF; |
48 |
template <${arg_tmpl_decl}> |
49 |
class connection_base${num} |
50 |
{ |
51 |
public: |
52 |
typedef connection_base${num}<${arg_type_list}> this_type; |
53 |
|
54 |
virtual ~connection_base${num} (){} |
55 |
|
56 |
virtual listening_base* getdest () const = 0; |
57 |
virtual void invoke (${arg_type_list}) const = 0; |
58 |
virtual this_type *clone () const { return 0; } |
59 |
virtual this_type *duplicate (listening_base* pnewdest) const { return 0; } |
60 |
#if 0 |
61 |
virtual this_type *clone () const = 0; // { return 0; } |
62 |
virtual this_type *duplicate (listening_base* pnewdest) const = 0; // { return 0; } |
63 |
#endif |
64 |
}; |
65 |
|
66 |
EOF |
67 |
|
68 |
|
69 |
######################################################################## |
70 |
# connection |
71 |
$gen .= <<EOF; |
72 |
template<class dest_type, ${arg_tmpl_decl}> |
73 |
class connection${num} : public connection_base${num}<${arg_type_list}> |
74 |
{ |
75 |
public: |
76 |
typedef connection_base${num}<${arg_type_list} > base_type; |
77 |
typedef connection${num}< dest_type, ${arg_type_list} > this_type; |
78 |
typedef void (dest_type::*listener_func) (${arg_type_list}); |
79 |
|
80 |
connection${num} () : m_pobject (0), m_pmemfun (0) { } |
81 |
|
82 |
virtual ~connection${num} () { } |
83 |
|
84 |
connection${num} (dest_type *pobject, listener_func pfunc) : m_pobject (pobject), m_pmemfun (pfunc) { } |
85 |
|
86 |
virtual base_type *clone () const |
87 |
{ |
88 |
return new this_type (*this); |
89 |
} |
90 |
|
91 |
virtual base_type *duplicate (listening_base *pnewdest) const |
92 |
{ |
93 |
return new this_type (dynamic_cast<dest_type *> (pnewdest), m_pmemfun); |
94 |
} |
95 |
|
96 |
virtual listening_base* getdest () const |
97 |
{ |
98 |
return m_pobject; |
99 |
} |
100 |
|
101 |
virtual void invoke (${arg_type_list_named}) const |
102 |
{ |
103 |
(m_pobject->*m_pmemfun) (${arg_params_names}); |
104 |
} |
105 |
|
106 |
private: |
107 |
dest_type* m_pobject; |
108 |
listener_func m_pmemfun; |
109 |
}; |
110 |
|
111 |
EOF |
112 |
|
113 |
|
114 |
######################################################################## |
115 |
# event |
116 |
$gen .= <<EOF; |
117 |
template<${arg_tmpl_decl} > |
118 |
class event${num} : public event_base |
119 |
{ |
120 |
public: |
121 |
typedef has_listeners listening_base; |
122 |
typedef std::list<connection_base${num}<${arg_type_list}> *> |
123 |
connection_list; |
124 |
|
125 |
event${num} () { } |
126 |
|
127 |
event${num} (const event${num}<${arg_type_list}> &s) : event_base (s) |
128 |
{ |
129 |
if (&s == this) |
130 |
return; |
131 |
|
132 |
this->copy_connections (s.connections (), this->connections ()); |
133 |
} |
134 |
|
135 |
|
136 |
template<class desttype> |
137 |
void attach (desttype* plistener, void (desttype::*pmemfun) (${arg_type_list})) |
138 |
{ |
139 |
connection_base${num}<${arg_type_list}> *conn = new connection${num}<desttype, ${arg_type_list}> (plistener, pmemfun); |
140 |
this->connections ().push_back (conn); |
141 |
plistener->add_invoker (this); |
142 |
} |
143 |
|
144 |
void invoke (${arg_type_list_named}) const |
145 |
{ |
146 |
typename connection_list::const_iterator it; |
147 |
typename connection_list::const_iterator it_end = this->connections ().end (); |
148 |
|
149 |
for (it = this->connections ().begin (); it != it_end; ++it) |
150 |
(*it)->invoke (${arg_params_names}); |
151 |
} |
152 |
|
153 |
void operator () (${arg_type_list_named}) const |
154 |
{ |
155 |
this->invoke (${arg_params_names}); |
156 |
} |
157 |
|
158 |
event${num} &operator= (const event${num} &s) |
159 |
{ |
160 |
this->copy_connections (s.connections (), this->connections ()); |
161 |
return *this; |
162 |
} |
163 |
|
164 |
~event${num} () |
165 |
{ |
166 |
disconnect_all (); |
167 |
} |
168 |
|
169 |
void disconnect_all () |
170 |
{ |
171 |
this->free_connections (connections ()); |
172 |
} |
173 |
|
174 |
bool listener_duplicate (const listening_base *oldtarget, listening_base *newtarget) |
175 |
{ |
176 |
return this->duplicate_connection (oldtarget, newtarget, connections ()); |
177 |
} |
178 |
|
179 |
protected: |
180 |
bool listener_detach (listening_base *plistener) |
181 |
{ |
182 |
return this->detach (plistener, this->connections ()); |
183 |
} |
184 |
|
185 |
connection_list & connections () |
186 |
{ |
187 |
return this->m_connected_listeners; |
188 |
} |
189 |
|
190 |
const connection_list &connections () const |
191 |
{ |
192 |
return this->m_connected_listeners; |
193 |
} |
194 |
|
195 |
private: |
196 |
connection_list m_connected_listeners; |
197 |
}; |
198 |
EOF |
199 |
|
200 |
} |
201 |
|
202 |
print $gen; |