#!/usr/bin/perl # $Id: gencallbacks.pl,v 1.1 2007/07/19 08:24:50 pippijn Exp $ use strict; use warnings; use utf8; my $namespace = "callback"; my $events = $ARGV[0] || 0; $events > 1 or die "Usage: $0 NUMBER\nwhere NUMBER > 1."; my $gen = ""; for my $num (2 .. $events) { my @argt; my @argn; my $arg_type_list_named; for (1 .. $num) { my $a = "arg${_}_type"; my $aname = "a$_"; push @argt, $a; push @argn, $aname; $arg_type_list_named .= "$a $aname, "; } $arg_type_list_named =~ s/, *$//; my $arg_params_names = join ", ", @argn; my $arg_tmpl_decl = "class " . join ", class ", @argt; my $arg_type_list = join ", ", @argt; $gen .= < class connection_base${num} { public: typedef connection_base${num}<${arg_type_list}> this_type; virtual ~connection_base${num} (){} virtual listening_base* getdest () const = 0; virtual void invoke (${arg_type_list}) const = 0; virtual this_type *clone () const { return 0; } virtual this_type *duplicate (listening_base* pnewdest) const { return 0; } #if 0 virtual this_type *clone () const = 0; // { return 0; } virtual this_type *duplicate (listening_base* pnewdest) const = 0; // { return 0; } #endif }; EOF ######################################################################## # connection $gen .= < class connection${num} : public connection_base${num}<${arg_type_list}> { public: typedef connection_base${num}<${arg_type_list} > base_type; typedef connection${num}< dest_type, ${arg_type_list} > this_type; typedef void (dest_type::*listener_func) (${arg_type_list}); connection${num} () : m_pobject (0), m_pmemfun (0) { } virtual ~connection${num} () { } connection${num} (dest_type *pobject, listener_func pfunc) : m_pobject (pobject), m_pmemfun (pfunc) { } virtual base_type *clone () const { return new this_type (*this); } virtual base_type *duplicate (listening_base *pnewdest) const { return new this_type (dynamic_cast (pnewdest), m_pmemfun); } virtual listening_base* getdest () const { return m_pobject; } virtual void invoke (${arg_type_list_named}) const { (m_pobject->*m_pmemfun) (${arg_params_names}); } private: dest_type* m_pobject; listener_func m_pmemfun; }; EOF ######################################################################## # event $gen .= < class event${num} : public event_base { public: typedef has_listeners listening_base; typedef std::list *> connection_list; event${num} () { } event${num} (const event${num}<${arg_type_list}> &s) : event_base (s) { if (&s == this) return; this->copy_connections (s.connections (), this->connections ()); } template void attach (desttype* plistener, void (desttype::*pmemfun) (${arg_type_list})) { connection_base${num}<${arg_type_list}> *conn = new connection${num} (plistener, pmemfun); this->connections ().push_back (conn); plistener->add_invoker (this); } void invoke (${arg_type_list_named}) const { typename connection_list::const_iterator it; typename connection_list::const_iterator it_end = this->connections ().end (); for (it = this->connections ().begin (); it != it_end; ++it) (*it)->invoke (${arg_params_names}); } void operator () (${arg_type_list_named}) const { this->invoke (${arg_params_names}); } event${num} &operator= (const event${num} &s) { this->copy_connections (s.connections (), this->connections ()); return *this; } ~event${num} () { disconnect_all (); } void disconnect_all () { this->free_connections (connections ()); } bool listener_duplicate (const listening_base *oldtarget, listening_base *newtarget) { return this->duplicate_connection (oldtarget, newtarget, connections ()); } protected: bool listener_detach (listening_base *plistener) { return this->detach (plistener, this->connections ()); } connection_list & connections () { return this->m_connected_listeners; } const connection_list &connections () const { return this->m_connected_listeners; } private: connection_list m_connected_listeners; }; EOF } print $gen;