xref: /trunk/main/canvas/inc/canvas/vclwrapper.hxx (revision 91c99ff4)
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