00001 /* 00002 * PROPRIETARY INFORMATION. This software is proprietary to 00003 * Side Effects Software Inc., and is not to be reproduced, 00004 * transmitted, or disclosed in any way without written permission. 00005 * 00006 * Produced by: 00007 * Mark Elendt 00008 * Side Effects Software Inc 00009 * 477 Richmond Street West 00010 * Toronto, Ontario 00011 * Canada M5V 3E7 00012 * 416-504-9876 00013 * 00014 * NAME: UT_ProxyPointer.h ( UT Library, C++) 00015 * 00016 * COMMENTS: A proxy pointer is used when you have other objects referencing 00017 * a source object. In many cases, it's possible for the source object to 00018 * be destroyed leaving dangling references to the now deleted source 00019 * object. 00020 * This class allows the source object to obtain a "proxy" pointer that 00021 * the other objects can reference. When the source object is deleted, it 00022 * should clear the proxy pointer so that all referencing objects will get 00023 * a null pointer (instead of a pointer to garbage memory). 00024 * 00025 * Example: 00026 * class A { 00027 * A() { myProxy = UT_ProxyPointer::allocProxy(this); } 00028 * ~A() { UT_ProxyPointer::freeProxy(myProxy); } 00029 * }; 00030 * 00031 * class B { 00032 * B(int proxy) { myPointer=UT_ProxyPointer::reference(proxy); } 00033 * ~B() { UT_ProxyPointer::deReference(myPointer); } 00034 * A *getA() { return (A *)UT_ProxyPointer::lookup(myPointer); } 00035 * }; 00036 * main() 00037 * { 00038 * A *a; 00039 * B *b0, *b1; 00040 * a = new A(); 00041 * b0 = new B(a->myProxy); 00042 * b1 = new B(a->myProxy); 00043 * fprintf(stderr, "0x%08x\n", b0->getA()); delete b0; 00044 * delete a; 00045 * fprintf(stderr, "0x%08x\n", b1->getA()); delete b1; 00046 * } 00047 * 00048 * NOTE: This class mainly provides a defense against poor programming. 00049 * However, it can provide memory efficiency since this allows links to be 00050 * built between objects without maintining double links. The cost here is 00051 * that there are multiple de-references instead of a single de-reference of 00052 * the pointer, meaning that cache performance is impacted. As well, more 00053 * null pointer checking needs to be performed. 00054 */ 00055 00056 #ifndef __UT_ProxyPointer__ 00057 #define __UT_ProxyPointer__ 00058 00059 #include "UT_API.h" 00060 00061 class UT_API UT_ProxyPointer { 00062 public: 00063 // The source object can use this class to allocate a proxy pointer 00064 static int allocProxy(void *ptr); 00065 static void freeProxy(int &id); 00066 00067 // This ID is guaranteed (well pretty much) to be an invalid id. 00068 static inline int nullId() { return -1; } 00069 static inline int isValid(int id) { return id >= 0; } 00070 00071 // When a class needs to reference the proxy, they should make sure to 00072 // reference/de-reference the proxy properly. 00073 static void referenceProxy(int id); 00074 static void deReferenceProxy(int id); 00075 00076 // 00077 // Swizzling the pointer allows you to change the object the proxy points 00078 // to so that all references to the pointer will be updated to the new 00079 // pointer. 00080 static void swizzlePointer(int id, void *ptr); 00081 00082 // This method can be used to get the pointer out of the proxy. If the 00083 // source object has been free'd a null pointer (i.e. 0) will be returned. 00084 static void *lookupProxy(int id); 00085 00086 // For some odd reason, you may want to know if there are other people 00087 // referencing the proxy. This method will return the number of references 00088 // to the proxy (including yourself). 00089 static unsigned getReferenceCount(int id); 00090 }; 00091 00092 #endif
1.5.9