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 GenericCallback_h 27 #define GenericCallback_h 28 29 #include "WKAPICast.h" 30 31 #include "WebError.h" 32 #include <wtf/HashMap.h> 33 #include <wtf/PassRefPtr.h> 34 #include <wtf/RefCounted.h> 35 36 namespace WebKit { 37 38 class CallbackBase : public RefCounted<CallbackBase> { 39 public: 40 virtual ~CallbackBase() 41 { 42 } 43 44 uint64_t callbackID() const { return m_callbackID; } 45 46 protected: 47 CallbackBase(void* context) 48 : m_context(context) 49 , m_callbackID(generateCallbackID()) 50 { 51 } 52 53 void* context() const { return m_context; } 54 55 private: 56 static uint64_t generateCallbackID() 57 { 58 static uint64_t uniqueCallbackID = 1; 59 return uniqueCallbackID++; 60 } 61 62 void* m_context; 63 uint64_t m_callbackID; 64 }; 65 66 class VoidCallback : public CallbackBase { 67 public: 68 typedef void (*CallbackFunction)(WKErrorRef, void*); 69 70 static PassRefPtr<VoidCallback> create(void* context, CallbackFunction callback) 71 { 72 return adoptRef(new VoidCallback(context, callback)); 73 } 74 75 virtual ~VoidCallback() 76 { 77 ASSERT(!m_callback); 78 } 79 80 void performCallback() 81 { 82 ASSERT(m_callback); 83 84 m_callback(0, context()); 85 86 m_callback = 0; 87 } 88 89 void invalidate() 90 { 91 ASSERT(m_callback); 92 93 RefPtr<WebError> error = WebError::create(); 94 m_callback(toAPI(error.get()), context()); 95 96 m_callback = 0; 97 } 98 99 private: 100 VoidCallback(void* context, CallbackFunction callback) 101 : CallbackBase(context) 102 , m_callback(callback) 103 { 104 } 105 106 CallbackFunction m_callback; 107 }; 108 109 template<typename APIReturnValueType, typename InternalReturnValueType = typename APITypeInfo<APIReturnValueType>::ImplType> 110 class GenericCallback : public CallbackBase { 111 public: 112 typedef void (*CallbackFunction)(APIReturnValueType, WKErrorRef, void*); 113 114 static PassRefPtr<GenericCallback> create(void* context, CallbackFunction callback) 115 { 116 return adoptRef(new GenericCallback(context, callback)); 117 } 118 119 virtual ~GenericCallback() 120 { 121 ASSERT(!m_callback); 122 } 123 124 void performCallbackWithReturnValue(InternalReturnValueType returnValue) 125 { 126 ASSERT(m_callback); 127 128 m_callback(toAPI(returnValue), 0, context()); 129 130 m_callback = 0; 131 } 132 133 void invalidate() 134 { 135 ASSERT(m_callback); 136 137 RefPtr<WebError> error = WebError::create(); 138 m_callback(0, toAPI(error.get()), context()); 139 140 m_callback = 0; 141 } 142 143 private: 144 GenericCallback(void* context, CallbackFunction callback) 145 : CallbackBase(context) 146 , m_callback(callback) 147 { 148 } 149 150 CallbackFunction m_callback; 151 }; 152 153 // FIXME: Make a version of CallbackBase with two arguments, and define ComputedPagesCallback as a specialization. 154 class ComputedPagesCallback : public CallbackBase { 155 public: 156 typedef void (*CallbackFunction)(const Vector<WebCore::IntRect>&, double, WKErrorRef, void*); 157 158 static PassRefPtr<ComputedPagesCallback> create(void* context, CallbackFunction callback) 159 { 160 return adoptRef(new ComputedPagesCallback(context, callback)); 161 } 162 163 virtual ~ComputedPagesCallback() 164 { 165 ASSERT(!m_callback); 166 } 167 168 void performCallbackWithReturnValue(const Vector<WebCore::IntRect>& returnValue1, double returnValue2) 169 { 170 ASSERT(m_callback); 171 172 m_callback(returnValue1, returnValue2, 0, context()); 173 174 m_callback = 0; 175 } 176 177 void invalidate() 178 { 179 ASSERT(m_callback); 180 181 RefPtr<WebError> error = WebError::create(); 182 m_callback(Vector<WebCore::IntRect>(), 0, toAPI(error.get()), context()); 183 184 m_callback = 0; 185 } 186 187 private: 188 189 ComputedPagesCallback(void* context, CallbackFunction callback) 190 : CallbackBase(context) 191 , m_callback(callback) 192 { 193 } 194 195 CallbackFunction m_callback; 196 }; 197 198 template<typename T> 199 void invalidateCallbackMap(HashMap<uint64_t, T>& map) 200 { 201 Vector<T> callbacksVector; 202 copyValuesToVector(map, callbacksVector); 203 for (size_t i = 0, size = callbacksVector.size(); i < size; ++i) 204 callbacksVector[i]->invalidate(); 205 map.clear(); 206 } 207 208 } // namespace WebKit 209 210 #endif // GenericCallback_h 211