1 /* 2 * Copyright (C) 2013 Google 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 are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #ifndef ResourceOwner_h 32 #define ResourceOwner_h 33 34 #include "core/fetch/ResourcePtr.h" 35 36 namespace blink { 37 38 39 template<class R, class C = typename R::ClientType> 40 class ResourceOwner : public C { 41 public: 42 typedef R ResourceType; 43 44 virtual ~ResourceOwner(); 45 ResourceType* resource() const { return m_resource.get(); } 46 47 protected: 48 ResourceOwner(); 49 ResourceOwner(const ResourceOwner& other) { setResource(other.resource()); } 50 explicit ResourceOwner(const ResourcePtr<ResourceType>&); 51 52 void setResource(const ResourcePtr<ResourceType>&); 53 void clearResource(); 54 55 ResourceOwner& operator=(const ResourceOwner& other); 56 57 private: 58 ResourcePtr<ResourceType> m_resource; 59 }; 60 61 template<class R, class C> 62 inline ResourceOwner<R, C>::ResourceOwner() 63 { 64 } 65 66 template<class R, class C> 67 inline ResourceOwner<R, C>::~ResourceOwner() 68 { 69 clearResource(); 70 } 71 72 template<class R, class C> 73 inline ResourceOwner<R, C>::ResourceOwner(const ResourcePtr<R>& resource) 74 : m_resource(resource) 75 { 76 if (m_resource) 77 m_resource->addClient(this); 78 } 79 80 template<class R, class C> 81 inline void ResourceOwner<R, C>::setResource(const ResourcePtr<R>& newResource) 82 { 83 if (newResource == m_resource) 84 return; 85 86 // Some ResourceClient implementations reenter this so 87 // we need to prevent double removal. 88 if (ResourcePtr<ResourceType> oldResource = m_resource) { 89 m_resource.clear(); 90 oldResource->removeClient(this); 91 } 92 93 if (newResource) { 94 m_resource = newResource; 95 m_resource->addClient(this); 96 } 97 } 98 99 template<class R, class C> 100 inline void ResourceOwner<R, C>::clearResource() 101 { 102 setResource(0); 103 } 104 105 template<class R, class C> 106 inline ResourceOwner<R, C>& ResourceOwner<R, C>::operator=(const ResourceOwner<R, C>& other) 107 { 108 if (this == &other) 109 return *this; 110 setResource(other.resource()); 111 return *this; 112 } 113 114 } // namespace blink 115 116 #endif 117