This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

 

  Proxy Object Code
  Submitted by



Proxy objects are extremely useful classes that prevent resource leaks. They also simplify code and can provide portability benefits. A recent Code Of the Day example was excellent other than the fact that it had a global locked memory leak. This is especially bad because locked memory can not be swapped out by window's virtual memory manager. To solve this type of problem, I wrote the simple class below.

The basic idea behind Proxy objects is that they perform the resource grab in the constructor, if possible, and they free the resource in the destructor. Proxy objects are created on the stack as temporary variables. That way one doesn't have to remember to free them explicitly. When the Proxy goes out of scope, the resouce is automatically freed.

Proxy objects are useful for ensuring proper cleanup of any precious resource, such as memory, gdi handles, threads, etc. In addition, they are very useful in graphics - I use proxy objects to set temporary D3D renderstates. When they go out of scope, it puts the renderstate back how it was before. This really cleans up rendering code.

Another advantage of proxy objects is that they provide a nice way to hide O/S specific behavior. You could swap out different Proxy object classes for different operating systems without effecting the game code itself.

Download Associated File: proxyobject.txt (1,489 bytes)

/*

COTD - Proxy Object Code - by D. Sim Dietrich Jr. [simmer@pacbell.net]

Here is an example to handle creating and freeing locked down memory in Win32 :

*/
class GlobalAllocProxy() { private HGLOBAL hMem; private bool bLocked; public GlobalAllocProxy( const int& size ) { hMem = GlobalAlloc( size ); }; public void* Lock() { void* pMem = 0; if ( !mbLocked && ( hMem != 0 ) ) { pMem = GlobalLock( hMem ); mbLocked = ( pMem != 0 ); } return pMem; } public void Unlock() { if ( mbLocked ) { GlobalUnlock( hMem ); mbLocked = false; } } public ~GlobalAllocProxy() { if ( hMem ) { UnLock(); GlobalFree( hMem ); } } }; // Class GlobalAllocProxy Here is an example that shows how to use an abstract base class to support portability for CriticalSections. You could use a typedef or #define to make the type created completely hidden from the main code. // The following code piece was contributed by Bobris: class Mutex { public: Mutex() { InitializeCriticalSection(&mCS); } ~Mutex() { DeleteCriticalSection(&mCS); } void enter() { EnterCriticalSection(&mCS); } void leave() { LeaveCriticalSection(&mCS); } private: CRITICAL_SECTION mCS; };

class Lock { public: Lock(Mutex &aMutex): mMutex(aMutex) { aMutex.enter(); } ~Lock() { mMutex.leave(); } private: Mutex &mMutex; };


The zip file viewer built into the Developer Toolbox made use of the zlib library, as well as the zlibdll source additions.

 

Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
Please read our Terms, Conditions, and Privacy information.