// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*- // Copyright (c) 2001-2007 International Computer Science Institute // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software") // to deal in the Software without restriction, subject to the conditions // listed in the XORP LICENSE file. These conditions include: you must // preserve this copyright notice, and you cannot mention the copyright // holders in advertising related to the Software without their permission. // The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This // notice is a summary of the XORP LICENSE file; the license in that file is // legally binding. #ident "$XORP: xorp/libxorp/test_callback.cc,v 1.9 2007/02/16 22:46:24 pavlin Exp $" // // Callback test program // #include #include #include "xorp.h" #include "callback.hh" typedef XorpCallback1::RefPtr TestCallback; class Widget { public: Widget() {} ~Widget() {} void notify(int event) { printf("Widget event %d\n", event); } void funky_notify(int event, TestCallback cb) { printf("Funky, "); cb->dispatch(event); } private: }; class SafeWidget : public CallbackSafeObject { public: SafeWidget(int* counter) : _counter(counter) {} void notify(int event) { printf("SafeWidget event %d\n", event); *_counter = *_counter + 1; } private: int* _counter; }; int main() { Widget w; TestCallback cbm; // The callback should be empty if (!cbm.is_empty()) { printf("ERROR: callback is not empty\n"); return -1; } // Set the callback cbm = callback(&w, &Widget::notify); // Test that the callback is not empty if (cbm.is_empty()) { printf("ERROR: callback is empty\n"); return -1; } // Call the callback cbm->dispatch(3); // call w.notify(3); cbm = callback(&w, &Widget::funky_notify, callback(&w, &Widget::funky_notify, callback(&w, &Widget::notify) ) ); cbm->dispatch(4); cbm = callback(&w, &Widget::notify); for (int i = 0; i < 8; i++) { cbm = callback(&w, &Widget::funky_notify, cbm); } cbm->dispatch(5); // Show safe callback - only dispatches if object referred to in // callback() method exists. ie object deletion prevents further // dispatches upon object int counter = 0; const int stop_point = 5; SafeWidget* sw = new SafeWidget(&counter); cbm = callback(sw, &SafeWidget::notify); for (int i = 0; i < 10; ++i) { if (i == stop_point) delete sw; cbm->dispatch(i); } if (counter != stop_point) { printf("ERROR: safe callback executed after object deletion\n"); return -1; } // Test destructor of callback correctly interacts with // CallbackSafeObject correctly. { int counter2 = 0; SafeWidget* sw = new SafeWidget(&counter2); { TestCallback cbset[10]; for (int i = 0; i < 10; i++) { cbset[i] = callback(sw, &SafeWidget::notify); } cbset[0] = 0; } delete sw; } return (0); }