#include <iostream>
#include <list>
#include <string>
using std::list;
using std::string;
using std::cout;
using std::endl;
#define callback_macro(facade, call) \
\
for(list<transactor_callbacks*>::iterator it=this->callbacks.begin(); it!=this->callbacks.end(); ++it) { \
facade* cb = dynamic_cast<facade*>(*it); \
cb->call; \
}
class transactor_callbacks {
public:
virtual ~transactor_callbacks(){}
};
class driver;
class driver_callbacks: virtual public transactor_callbacks {
public:
virtual void driver_pre_transactor (driver* xactor, bool* drop) {}
virtual void driver_post_transactor (driver* xactor) {}
};
class driver {
public:
virtual bool prepend_callback(transactor_callbacks* cb) {
for(list<transactor_callbacks*>::iterator it=callbacks.begin(); it!=callbacks.end(); ++it) {
if(cb == *it) {
return 1;
}
}
callbacks.push_front(cb);
return 0;
}
virtual bool append_callback(transactor_callbacks* cb) {
for(list<transactor_callbacks*>::iterator it=callbacks.begin(); it!=callbacks.end(); ++it) {
if(cb == *it) {
return 1;
}
}
callbacks.push_back(cb);
return 0;
}
virtual bool unregister_callback(transactor_callbacks* cb) {
for(list<transactor_callbacks*>::iterator it=callbacks.begin(); it!=callbacks.end(); ++it) {
if(cb == *it) {
callbacks.erase(it);
return 0;
}
}
return 1;
}
void run() {
callback_macro(driver_callbacks, driver_pre_transactor(this, &drop));
callback_macro(driver_callbacks, driver_post_transactor(this));
}
list<transactor_callbacks*> callbacks;
bool drop;
};
class driver_pre_transactor1: public driver_callbacks {
public:
driver_pre_transactor1(string name="cb1"):driver_callbacks() {
this->name = name;
}
virtual void driver_pre_transactor (driver* xactor, bool* drop) {
cout << name << ": before transactor" << endl;
}
private:
string name;
};
class driver_post_transactor2: public driver_callbacks {
public:
driver_post_transactor2(string name="cb2"):driver_callbacks() {
this->name = name;
}
virtual void driver_post_transactor (driver* xactor) {
cout << name << ": after transactor" << endl;
}
private:
string name;
};
int main(int argc, char** argv) {
driver* drv = new driver();
driver_pre_transactor1* drv_pre_tx1 = new driver_pre_transactor1("pre_tx1");
driver_pre_transactor1* drv_pre_tx2 = new driver_pre_transactor1("pre_tx2");
driver_post_transactor2* drv_post_tx1 = new driver_post_transactor2("post_tx1");
drv->append_callback(drv_pre_tx1);
drv->append_callback(drv_pre_tx2);
drv->append_callback(drv_post_tx1);
drv->run();
drv->unregister_callback(drv_pre_tx2);
drv->run();
return 0;
}
#include <list>
#include <string>
using std::list;
using std::string;
using std::cout;
using std::endl;
#define callback_macro(facade, call) \
\
for(list<transactor_callbacks*>::iterator it=this->callbacks.begin(); it!=this->callbacks.end(); ++it) { \
facade* cb = dynamic_cast<facade*>(*it); \
cb->call; \
}
class transactor_callbacks {
public:
virtual ~transactor_callbacks(){}
};
class driver;
class driver_callbacks: virtual public transactor_callbacks {
public:
virtual void driver_pre_transactor (driver* xactor, bool* drop) {}
virtual void driver_post_transactor (driver* xactor) {}
};
class driver {
public:
virtual bool prepend_callback(transactor_callbacks* cb) {
for(list<transactor_callbacks*>::iterator it=callbacks.begin(); it!=callbacks.end(); ++it) {
if(cb == *it) {
return 1;
}
}
callbacks.push_front(cb);
return 0;
}
virtual bool append_callback(transactor_callbacks* cb) {
for(list<transactor_callbacks*>::iterator it=callbacks.begin(); it!=callbacks.end(); ++it) {
if(cb == *it) {
return 1;
}
}
callbacks.push_back(cb);
return 0;
}
virtual bool unregister_callback(transactor_callbacks* cb) {
for(list<transactor_callbacks*>::iterator it=callbacks.begin(); it!=callbacks.end(); ++it) {
if(cb == *it) {
callbacks.erase(it);
return 0;
}
}
return 1;
}
void run() {
callback_macro(driver_callbacks, driver_pre_transactor(this, &drop));
callback_macro(driver_callbacks, driver_post_transactor(this));
}
list<transactor_callbacks*> callbacks;
bool drop;
};
class driver_pre_transactor1: public driver_callbacks {
public:
driver_pre_transactor1(string name="cb1"):driver_callbacks() {
this->name = name;
}
virtual void driver_pre_transactor (driver* xactor, bool* drop) {
cout << name << ": before transactor" << endl;
}
private:
string name;
};
class driver_post_transactor2: public driver_callbacks {
public:
driver_post_transactor2(string name="cb2"):driver_callbacks() {
this->name = name;
}
virtual void driver_post_transactor (driver* xactor) {
cout << name << ": after transactor" << endl;
}
private:
string name;
};
int main(int argc, char** argv) {
driver* drv = new driver();
driver_pre_transactor1* drv_pre_tx1 = new driver_pre_transactor1("pre_tx1");
driver_pre_transactor1* drv_pre_tx2 = new driver_pre_transactor1("pre_tx2");
driver_post_transactor2* drv_post_tx1 = new driver_post_transactor2("post_tx1");
drv->append_callback(drv_pre_tx1);
drv->append_callback(drv_pre_tx2);
drv->append_callback(drv_post_tx1);
drv->run();
drv->unregister_callback(drv_pre_tx2);
drv->run();
return 0;
}
Makefile
PROJECT = main
EXE = $(PROJECT).exe
OBJ = $(patsubst %.exe,%.o,$(EXE))
.PHONY: clean all
all: clean $(EXE)
clean:
rm -rf *.o *.exe
$(EXE): $(OBJ)
g++ $^ -o $@
EXE = $(PROJECT).exe
OBJ = $(patsubst %.exe,%.o,$(EXE))
.PHONY: clean all
all: clean $(EXE)
clean:
rm -rf *.o *.exe
$(EXE): $(OBJ)
g++ $^ -o $@
No comments:
Post a Comment