diff options
-rw-r--r-- | src/base/SConscript | 1 | ||||
-rw-r--r-- | src/base/callback.cc | 39 | ||||
-rw-r--r-- | src/base/callback.hh | 76 |
3 files changed, 94 insertions, 22 deletions
diff --git a/src/base/SConscript b/src/base/SConscript index 58c453184..bdc711ed1 100644 --- a/src/base/SConscript +++ b/src/base/SConscript @@ -35,6 +35,7 @@ if env['CP_ANNOTATE']: Source('cp_annotate.cc') Source('atomicio.cc') Source('bigint.cc') +Source('callback.cc') Source('circlebuf.cc') Source('cprintf.cc') Source('crc.cc') diff --git a/src/base/callback.cc b/src/base/callback.cc new file mode 100644 index 000000000..e9f662b19 --- /dev/null +++ b/src/base/callback.cc @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + */ + +#import "base/callback.hh" + +CallbackQueue::~CallbackQueue() +{ + queue::iterator i = callbacks.begin(); + queue::iterator end = callbacks.end(); + for (; i != end; ++i) + (*i)->autoDestruct(); +} diff --git a/src/base/callback.hh b/src/base/callback.hh index a39d7df20..74bb0d2a0 100644 --- a/src/base/callback.hh +++ b/src/base/callback.hh @@ -28,10 +28,11 @@ * Authors: Nathan Binkert */ -#ifndef __CALLBACK_HH__ -#define __CALLBACK_HH__ +#ifndef __BASE_CALLBACK_HH__ +#define __BASE_CALLBACK_HH__ #include <list> +#include <string> /** * Generic callback class. This base class provides a virtual process @@ -39,6 +40,10 @@ */ class Callback { + protected: + friend class CallbackQueue; + virtual void autoDestruct() {} + public: /** * virtualize the destructor to make sure that the correct one @@ -53,6 +58,29 @@ class Callback virtual void process() = 0; }; +/// Helper template class to turn a simple class member function into +/// a callback. +template <class T, void (T::* F)()> +class MakeCallback : public Callback +{ + protected: + T *object; + const bool autoDestroy; + + void autoDestruct() { if (autoDestroy) delete this; } + + public: + MakeCallback(T *o, bool auto_destroy = false) + : object(o), autoDestroy(auto_destroy) + { } + + MakeCallback(T &o, bool auto_destroy = false) + : object(&o), autoDestroy(auto_destroy) + { } + + void process() { (object->*F)(); } +}; + class CallbackQueue { protected: @@ -68,15 +96,33 @@ class CallbackQueue queue callbacks; public: + ~CallbackQueue(); + std::string name() const { return "CallbackQueue"; } + /** * Add a callback to the end of the queue * @param callback the callback to be added to the queue */ - void add(Callback *callback) + void + add(Callback *callback) { callbacks.push_back(callback); } + template <class T, void (T::* F)()> + void + add(T *obj) + { + add(new MakeCallback<T, F>(obj, true)); + } + + template <class T, void (T::* F)()> + void + add(T &obj) + { + add(new MakeCallback<T, F>(&obj, true)); + } + /** * Find out if there are any callbacks in the queue */ @@ -85,7 +131,8 @@ class CallbackQueue /** * process all callbacks */ - void process() + void + process() { queue::iterator i = callbacks.begin(); queue::iterator end = callbacks.end(); @@ -99,26 +146,11 @@ class CallbackQueue /** * clear the callback queue */ - void clear() + void + clear() { callbacks.clear(); } }; -/// Helper template class to turn a simple class member function into -/// a callback. -template <class T, void (T::* F)()> -class MakeCallback : public Callback -{ - private: - T *object; - - public: - MakeCallback(T *o) - : object(o) - { } - - void process() { (object->*F)(); } -}; - -#endif // __CALLBACK_HH__ +#endif // __BASE_CALLBACK_HH__ |