1/*
2 * Copyright (C) 2010 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. 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 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef WorkItem_h
27#define WorkItem_h
28
29#include <wtf/PassOwnPtr.h>
30
31class WorkItem {
32public:
33    template<typename C>
34    static PassOwnPtr<WorkItem> create(C*, void (C::*)());
35
36    template<typename C, typename T0>
37    static PassOwnPtr<WorkItem> create(C*, void (C::*)(T0), T0);
38
39    template<typename C, typename T0, typename T1>
40    static PassOwnPtr<WorkItem> create(C*, void (C::*)(T0, T1), T0, T1);
41
42    static PassOwnPtr<WorkItem> create(void (*)());
43
44    virtual ~WorkItem() { }
45    virtual void execute() = 0;
46
47protected:
48    WorkItem() { }
49
50private:
51    WorkItem(const WorkItem&);
52    WorkItem& operator=(const WorkItem&);
53};
54
55template <typename C>
56class MemberFunctionWorkItem0 : private WorkItem {
57    // We only allow WorkItem to create this.
58    friend class WorkItem;
59
60    typedef void (C::*FunctionType)();
61
62    MemberFunctionWorkItem0(C* ptr, FunctionType function)
63        : m_ptr(ptr)
64        , m_function(function)
65    {
66        m_ptr->ref();
67    }
68
69    ~MemberFunctionWorkItem0()
70    {
71        m_ptr->deref();
72    }
73
74    virtual void execute()
75    {
76        (m_ptr->*m_function)();
77    }
78
79    C* m_ptr;
80    FunctionType m_function;
81};
82
83template<typename C, typename T0>
84class MemberFunctionWorkItem1 : private WorkItem {
85    // We only allow WorkItem to create this.
86    friend class WorkItem;
87
88    typedef void (C::*FunctionType)(T0);
89
90    MemberFunctionWorkItem1(C* ptr, FunctionType function, T0 t0)
91        : m_ptr(ptr)
92        , m_function(function)
93        , m_t0(t0)
94    {
95        m_ptr->ref();
96    }
97
98    ~MemberFunctionWorkItem1()
99    {
100        m_ptr->deref();
101    }
102
103    virtual void execute()
104    {
105        (m_ptr->*m_function)(m_t0);
106    }
107
108    C* m_ptr;
109    FunctionType m_function;
110    T0 m_t0;
111};
112
113template<typename C, typename T0, typename T1>
114class MemberFunctionWorkItem2 : private WorkItem {
115    // We only allow WorkItem to create this.
116    friend class WorkItem;
117
118    typedef void (C::*FunctionType)(T0, T1);
119
120    MemberFunctionWorkItem2(C* ptr, FunctionType function, T0 t0, T1 t1)
121        : m_ptr(ptr)
122        , m_function(function)
123        , m_t0(t0)
124        , m_t1(t1)
125    {
126        m_ptr->ref();
127    }
128
129    ~MemberFunctionWorkItem2()
130    {
131        m_ptr->deref();
132    }
133
134    virtual void execute()
135    {
136        (m_ptr->*m_function)(m_t0, m_t1);
137    }
138
139    C* m_ptr;
140    FunctionType m_function;
141    T0 m_t0;
142    T1 m_t1;
143};
144
145template<typename C>
146PassOwnPtr<WorkItem> WorkItem::create(C* ptr, void (C::*function)())
147{
148    return adoptPtr(static_cast<WorkItem*>(new MemberFunctionWorkItem0<C>(ptr, function)));
149}
150
151template<typename C, typename T0>
152PassOwnPtr<WorkItem> WorkItem::create(C* ptr, void (C::*function)(T0), T0 t0)
153{
154    return adoptPtr(static_cast<WorkItem*>(new MemberFunctionWorkItem1<C, T0>(ptr, function, t0)));
155}
156
157template<typename C, typename T0, typename T1>
158PassOwnPtr<WorkItem> WorkItem::create(C* ptr, void (C::*function)(T0, T1), T0 t0, T1 t1)
159{
160    return adoptPtr(static_cast<WorkItem*>(new MemberFunctionWorkItem2<C, T0, T1>(ptr, function, t0, t1)));
161}
162
163class FunctionWorkItem0 : private WorkItem {
164    // We only allow WorkItem to create this.
165    friend class WorkItem;
166
167    typedef void (*FunctionType)();
168
169    FunctionWorkItem0(FunctionType function)
170        : m_function(function)
171    {
172    }
173
174    virtual void execute()
175    {
176        (*m_function)();
177    }
178
179    FunctionType m_function;
180};
181
182inline PassOwnPtr<WorkItem> WorkItem::create(void (*function)())
183{
184    return adoptPtr(static_cast<WorkItem*>(new FunctionWorkItem0(function)));
185}
186
187#endif // WorkItem_h
188