12SN/A/* 21762SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Nathan Binkert 292SN/A */ 302SN/A 317067Snate@binkert.org#ifndef __BASE_CALLBACK_HH__ 327067Snate@binkert.org#define __BASE_CALLBACK_HH__ 332SN/A 342SN/A#include <list> 357067Snate@binkert.org#include <string> 362SN/A 37147SN/A/** 381158SN/A * Generic callback class. This base class provides a virtual process 39147SN/A * function that gets called when the callback queue is processed. 40147SN/A */ 41147SN/Aclass Callback 42147SN/A{ 437067Snate@binkert.org protected: 447067Snate@binkert.org friend class CallbackQueue; 457067Snate@binkert.org virtual void autoDestruct() {} 467067Snate@binkert.org 472SN/A public: 48147SN/A /** 49147SN/A * virtualize the destructor to make sure that the correct one 50147SN/A * gets called. 51147SN/A */ 522SN/A virtual ~Callback() {} 53147SN/A 54147SN/A /** 55147SN/A * virtual process function that is invoked when the callback 56147SN/A * queue is executed. 57147SN/A */ 582SN/A virtual void process() = 0; 592SN/A}; 602SN/A 617067Snate@binkert.org/// Helper template class to turn a simple class member function into 627067Snate@binkert.org/// a callback. 637067Snate@binkert.orgtemplate <class T, void (T::* F)()> 647067Snate@binkert.orgclass MakeCallback : public Callback 657067Snate@binkert.org{ 667067Snate@binkert.org protected: 677067Snate@binkert.org T *object; 687067Snate@binkert.org const bool autoDestroy; 697067Snate@binkert.org 707067Snate@binkert.org void autoDestruct() { if (autoDestroy) delete this; } 717067Snate@binkert.org 727067Snate@binkert.org public: 737067Snate@binkert.org MakeCallback(T *o, bool auto_destroy = false) 747067Snate@binkert.org : object(o), autoDestroy(auto_destroy) 757067Snate@binkert.org { } 767067Snate@binkert.org 777067Snate@binkert.org MakeCallback(T &o, bool auto_destroy = false) 787067Snate@binkert.org : object(&o), autoDestroy(auto_destroy) 797067Snate@binkert.org { } 807067Snate@binkert.org 817067Snate@binkert.org void process() { (object->*F)(); } 827067Snate@binkert.org}; 837067Snate@binkert.org 842SN/Aclass CallbackQueue 852SN/A{ 862SN/A protected: 87147SN/A /** 88147SN/A * Simple typedef for the data structure that stores all of the 89147SN/A * callbacks. 90147SN/A */ 91147SN/A typedef std::list<Callback *> queue; 92147SN/A 93147SN/A /** 94147SN/A * List of all callbacks. To be called in fifo order. 95147SN/A */ 96147SN/A queue callbacks; 972SN/A 982SN/A public: 997067Snate@binkert.org ~CallbackQueue(); 1007067Snate@binkert.org std::string name() const { return "CallbackQueue"; } 1017067Snate@binkert.org 102147SN/A /** 103147SN/A * Add a callback to the end of the queue 104147SN/A * @param callback the callback to be added to the queue 105147SN/A */ 1067067Snate@binkert.org void 1077067Snate@binkert.org add(Callback *callback) 108147SN/A { 109147SN/A callbacks.push_back(callback); 110147SN/A } 111147SN/A 1127067Snate@binkert.org template <class T, void (T::* F)()> 1137067Snate@binkert.org void 1147067Snate@binkert.org add(T *obj) 1157067Snate@binkert.org { 1167067Snate@binkert.org add(new MakeCallback<T, F>(obj, true)); 1177067Snate@binkert.org } 1187067Snate@binkert.org 1197067Snate@binkert.org template <class T, void (T::* F)()> 1207067Snate@binkert.org void 1217067Snate@binkert.org add(T &obj) 1227067Snate@binkert.org { 1237067Snate@binkert.org add(new MakeCallback<T, F>(&obj, true)); 1247067Snate@binkert.org } 1257067Snate@binkert.org 126147SN/A /** 127147SN/A * Find out if there are any callbacks in the queue 128147SN/A */ 1292SN/A bool empty() const { return callbacks.empty(); } 130147SN/A 131147SN/A /** 132147SN/A * process all callbacks 133147SN/A */ 1347067Snate@binkert.org void 1357067Snate@binkert.org process() 136147SN/A { 137147SN/A queue::iterator i = callbacks.begin(); 138147SN/A queue::iterator end = callbacks.end(); 139147SN/A 140147SN/A while (i != end) { 141147SN/A (*i)->process(); 142147SN/A ++i; 143147SN/A } 1442SN/A } 145147SN/A 146147SN/A /** 147147SN/A * clear the callback queue 148147SN/A */ 1497067Snate@binkert.org void 1507067Snate@binkert.org clear() 151147SN/A { 152147SN/A callbacks.clear(); 153147SN/A } 1542SN/A}; 1552SN/A 1567067Snate@binkert.org#endif // __BASE_CALLBACK_HH__ 157