00001 /* 00002 * This source file is part of libRocket, the HTML/CSS Interface Middleware 00003 * 00004 * For the latest information, see http://www.librocket.com 00005 * 00006 * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd 00007 * 00008 * Permission is hereby granted, free of charge, to any person obtaining a copy 00009 * of this software and associated documentation files (the "Software"), to deal 00010 * in the Software without restriction, including without limitation the rights 00011 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00012 * copies of the Software, and to permit persons to whom the Software is 00013 * furnished to do so, subject to the following conditions: 00014 * 00015 * The above copyright notice and this permission notice shall be included in 00016 * all copies or substantial portions of the Software. 00017 * 00018 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00019 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00020 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00021 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00022 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00023 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00024 * THE SOFTWARE. 00025 * 00026 */ 00027 00028 #if !defined(BOOST_PP_IS_ITERATING) 00029 # error PyWrapperIter - do not include this file! 00030 #endif 00031 00032 #define N BOOST_PP_ITERATION() 00033 00045 #define WRAPPER_PARAM(x, n, d) , d 00046 00047 template < typename T BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS_Z(1, N, typename A) > 00048 class Wrapper< T BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS_Z(1, N, A) BOOST_PP_REPEAT_1( BOOST_PP_SUB(BOOST_PP_INC(WRAPPER_MAX_ARGS), N), WRAPPER_PARAM, WrapperNone) > : public T 00049 { 00050 public: 00051 Wrapper(PyObject* self BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, a)) : T(BOOST_PP_ENUM_PARAMS_Z(1, N, a)) 00052 { 00053 // Set self to NULL, so we can trap the reference deactivated and not pass it down 00054 this->self = NULL; 00055 00056 // We have to remove the C++ reference count that all C++ objects start with here, 00057 // otherwise if an object is created in python and destroyed by python, the C++ ref count will 00058 // remain 1. The PyWrapperInstancer will increase the refcount again, to ensure a correct refcount 00059 // if the object was created by C++ 00060 T::RemoveReference(); 00061 00062 // If the C++ reference count is not 0 at this point, it means additional references have been added 00063 // during the classes constructor. We have to propogate these references into python. 00064 for (int i = 0; i < this->T::GetReferenceCount(); i++) 00065 Py_INCREF(self); 00066 00067 // Store self 00068 this->self = self; 00069 } 00070 00071 Wrapper(PyObject* self, const T& other) : T(other) 00072 { 00073 this->self = self; 00074 } 00075 00076 virtual ~Wrapper() 00077 { 00078 // We should only be deleted when python says the refcnt is 0, if we 00079 // are being deleted prematurely, something is wrong! 00080 ROCKET_ASSERTMSG(self->ob_refcnt == 0, "Python object being cleared up prematurely, reference count not 0."); 00081 ROCKET_ASSERT(this->T::GetReferenceCount() == 0); 00082 } 00083 00085 virtual void AddReference() 00086 { 00087 Py_INCREF(self); 00088 00089 T::AddReference(); 00090 } 00091 00093 virtual void RemoveReference() 00094 { 00095 T::RemoveReference(); 00096 00097 Py_DECREF(self); 00098 } 00099 00100 virtual int GetReferenceCount() 00101 { 00102 // C++ reference counts are always reflected in the python ref count 00103 return self->ob_refcnt; 00104 } 00105 00106 virtual void OnReferenceDeactivate() 00107 { 00108 // If self is NULL, don't pass the call down, as this is the initial 00109 // T::RemoveReference from the constructor 00110 if (self) 00111 T::OnReferenceDeactivate(); 00112 } 00113 00114 // Script object access 00115 virtual void* GetScriptObject() const { return self; } 00116 00117 protected: 00118 PyObject* self; 00119 }; 00120 00121 #undef WRAPPER_PARAM 00122