1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #ifndef INCLUDED_CANVAS_VCLWRAPPER_HXX 25 #define INCLUDED_CANVAS_VCLWRAPPER_HXX 26 27 #include <osl/mutex.hxx> 28 #include <vos/mutex.hxx> 29 #include <vcl/svapp.hxx> 30 31 32 namespace canvas 33 { 34 namespace vcltools 35 { 36 /** This helper template wraps VCL objects, and protects 37 object deletion with the Solar mutex. All other operations 38 are unprotected, this must be handled by client code. 39 40 The reason for this template is the fact that VCL objects 41 hold by value in uno::Reference-handled classes are 42 deleted without having the chance to get inbetween and 43 lock the solar mutex. 44 45 This template handles that problem transparently, the only 46 inconvenience is the fact that object member access now 47 has to be performed via operator->, since . is not 48 overloadable. 49 50 Otherwise, the template preserves the value semantics of 51 the wrapped object, that is, copy operations are performed 52 not by copying pointers, but by copying the underlying 53 object. This includes constness, i.e. on a const 54 VCLObject, only const methods of the wrapped object can be 55 called. Simply imagine this to be a value object of type 56 "template argument", with the only peculiarity that 57 member/method access is performed by operator-> instead of 58 the non-existing "operator.". 59 */ 60 template< class _Wrappee > class VCLObject 61 { 62 public: 63 typedef _Wrappee Wrappee; 64 VCLObject()65 VCLObject() : 66 mpWrappee( new Wrappee() ) 67 { 68 } 69 70 // no explicit here. VCLObjects should be freely 71 // constructible with Wrappees, and AFAIK there is no other 72 // implicit conversion path that could cause harm here VCLObject(Wrappee * pWrappee)73 VCLObject( Wrappee* pWrappee ) : 74 mpWrappee( pWrappee ) 75 { 76 } 77 78 // This object has value semantics, thus, forward copy 79 // to wrappee VCLObject(const VCLObject & rOrig)80 VCLObject( const VCLObject& rOrig ) 81 { 82 if( rOrig.mpWrappee ) 83 mpWrappee = new Wrappee( *rOrig.mpWrappee ); 84 else 85 mpWrappee = NULL; 86 } 87 88 // This object has value semantics, thus, forward copy 89 // to wrappee VCLObject(const Wrappee & rOrig)90 VCLObject( const Wrappee& rOrig ) : 91 mpWrappee( new Wrappee( rOrig ) ) 92 { 93 } 94 95 // This object has value semantics, thus, forward 96 // assignment to wrappee operator =(const VCLObject & rhs)97 VCLObject& operator=( const VCLObject& rhs ) 98 { 99 if( mpWrappee ) 100 { 101 if( rhs.mpWrappee ) 102 *mpWrappee = *rhs.mpWrappee; 103 } 104 else 105 { 106 if( rhs.mpWrappee ) 107 mpWrappee = new Wrappee( *rhs.mpWrappee ); 108 } 109 110 return *this; 111 } 112 ~VCLObject()113 ~VCLObject() 114 { 115 // This here is the whole purpose of the template: 116 // protecting object deletion with the solar mutex 117 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 118 119 if( mpWrappee ) 120 delete mpWrappee; 121 } 122 operator ->()123 Wrappee* operator->() { return mpWrappee; } operator ->() const124 const Wrappee* operator->() const { return mpWrappee; } 125 operator *()126 Wrappee& operator*() { return *mpWrappee; } operator *() const127 const Wrappee& operator*() const { return *mpWrappee; } 128 get()129 Wrappee& get() { return *mpWrappee; } get() const130 const Wrappee& get() const { return *mpWrappee; } 131 swap(VCLObject & rOther)132 void swap( VCLObject& rOther ) 133 { 134 ::std::swap( mpWrappee, rOther.mpWrappee ); 135 } 136 137 private: 138 139 Wrappee* mpWrappee; 140 }; 141 142 } 143 } 144 145 #endif /* INCLUDED_CANVAS_VCLWRAPPER_HXX */ 146