callback.hh revision 7067:8832fe9b5a57
1/*
2 * Copyright (c) 2003-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Nathan Binkert
29 */
30
31#ifndef __BASE_CALLBACK_HH__
32#define __BASE_CALLBACK_HH__
33
34#include <list>
35#include <string>
36
37/**
38 * Generic callback class.  This base class provides a virtual process
39 * function that gets called when the callback queue is processed.
40 */
41class Callback
42{
43  protected:
44    friend class CallbackQueue;
45    virtual void autoDestruct() {}
46
47  public:
48    /**
49     * virtualize the destructor to make sure that the correct one
50     * gets called.
51     */
52    virtual ~Callback() {}
53
54    /**
55     * virtual process function that is invoked when the callback
56     * queue is executed.
57     */
58    virtual void process() = 0;
59};
60
61/// Helper template class to turn a simple class member function into
62/// a callback.
63template <class T, void (T::* F)()>
64class MakeCallback : public Callback
65{
66  protected:
67    T *object;
68    const bool autoDestroy;
69
70    void autoDestruct() { if (autoDestroy) delete this; }
71
72  public:
73    MakeCallback(T *o, bool auto_destroy = false)
74        : object(o), autoDestroy(auto_destroy)
75    { }
76
77    MakeCallback(T &o, bool auto_destroy = false)
78        : object(&o), autoDestroy(auto_destroy)
79    { }
80
81    void process() { (object->*F)(); }
82};
83
84class CallbackQueue
85{
86  protected:
87    /**
88     * Simple typedef for the data structure that stores all of the
89     * callbacks.
90     */
91    typedef std::list<Callback *> queue;
92
93    /**
94     * List of all callbacks.  To be called in fifo order.
95     */
96    queue callbacks;
97
98  public:
99    ~CallbackQueue();
100    std::string name() const { return "CallbackQueue"; }
101
102    /**
103     * Add a callback to the end of the queue
104     * @param callback the callback to be added to the queue
105     */
106    void
107    add(Callback *callback)
108    {
109        callbacks.push_back(callback);
110    }
111
112    template <class T, void (T::* F)()>
113    void
114    add(T *obj)
115    {
116        add(new MakeCallback<T, F>(obj, true));
117    }
118
119    template <class T, void (T::* F)()>
120    void
121    add(T &obj)
122    {
123        add(new MakeCallback<T, F>(&obj, true));
124    }
125
126    /**
127     * Find out if there are any callbacks in the queue
128     */
129    bool empty() const { return callbacks.empty(); }
130
131    /**
132     * process all callbacks
133     */
134    void
135    process()
136    {
137        queue::iterator i = callbacks.begin();
138        queue::iterator end = callbacks.end();
139
140        while (i != end) {
141            (*i)->process();
142            ++i;
143        }
144    }
145
146    /**
147     * clear the callback queue
148     */
149    void
150    clear()
151    {
152        callbacks.clear();
153    }
154};
155
156#endif // __BASE_CALLBACK_HH__
157