home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 August: Tool Chest / Dev.CD Aug 00 TC Disk 1.toast / pc / sample code / games / isp sample / source / memoryhandler.c < prev    next >
Encoding:
Text File  |  2000-06-23  |  7.5 KB  |  389 lines

  1. /*
  2.     File:        MemoryHandler.c
  3.  
  4.     Contains:    xxx put contents here xxx
  5.  
  6.     Version:    xxx put version here xxx
  7.  
  8.     Copyright:    © 1999 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     File Ownership:
  11.  
  12.         DRI:                xxx put dri here xxx
  13.  
  14.         Other Contact:        xxx put other contact here xxx
  15.  
  16.         Technology:            xxx put technology here xxx
  17.  
  18.     Writers:
  19.  
  20.         (BWS)    Brent Schorsch
  21.  
  22.     Change History (most recent first):
  23.  
  24.        <SP1>      7/1/99    BWS        first checked in
  25. */
  26.  
  27. /*
  28.     These memory routines are kinda handy and solve a lot of problems on the Mac when dealing
  29.     with memory.  For instance, people often call DisposeHandle() when they mean to call
  30.     ReleaseResource() and it screws up their resource chain.  DisposeHandleZ() checks to see
  31.     if the handle is locked or not, and whether it's a resource or not and takes the appropriate
  32.     action.
  33.     
  34.     All functions ending in 'Z' take the ADDRESS of the Ptr/Handle and set it to nil when it
  35.     disposes of the memory.  This is handy because you can then do things like this:
  36.     
  37.         foo = NewPtr();
  38.         DisposePtrZ(&foo);
  39.             ...
  40.             ...
  41.             
  42.         if (foo)
  43.             ...
  44.     
  45.     Probably the most useful of all this stuff are the tagged Ptr and tagged Handle functions.
  46.     Basically what they do is add 12 bytes to the beginning of every block of memory that you
  47.     allocate.  The first four bytes are the value kBlockTag.  The second is an OSType that
  48.     you provide.  The 3rd group of four bytes is a refcon that you provide.  This is really
  49.     usefull when working with ZoneRanger or other memory watching tool because when you view
  50.     a block of memory you can see your type and refcon and get a clue as to what the memory
  51.     is.  It's really great when you have a memory leak and can't tell what's not getting
  52.     deallocated.  Another use is for tracking resources.  Pass in the resource type as the
  53.     OSType field and the resource number in the refcon.  Then in ZoneRanger you can see
  54.     exactly which resource and number a handle is.
  55.     
  56.     Another use is for reference counting list of similar objects.  If you allocate 200 foos
  57.     then set the OSType to 'foo ' and make the refcon the index of which foo it is.  This is
  58.     helpful for finding off-by-one loop errors when deallocating lists and arrays.
  59.     
  60.     One other thing that has come in really handy is to set the OSType to some identifier saying
  61.     which source file the block was allocated in and setting the refcon to the line number in
  62.     that source file.  That way in ZoneRanger you can tell exactly where that mystery block
  63.     came from.
  64. */
  65.  
  66. //•    ————————————————————————————————————————    Includes
  67.  
  68. #include <Dialogs.h>
  69. #include <Resources.h>
  70. #include <Windows.h>
  71.  
  72. #include <string.h>
  73.  
  74. #include "MemoryHandler.h"
  75.  
  76. //•    ————————————————————————————————————————    Private Definitions
  77.  
  78. #define kBlockTag                    "TBLK"
  79.  
  80. //•    ————————————————————————————————————————    Private Types
  81. //•    ————————————————————————————————————————    Private Variables
  82.  
  83. static UInt32    gAllocatedRam = 0U;
  84.  
  85. //•    ————————————————————————————————————————    Private Functions
  86. //•    ————————————————————————————————————————    Public Variables
  87.  
  88. //•    ————————————————————    IsResourceHandle
  89.  
  90. Boolean
  91. IsResourceHandle(Handle theHandle)
  92. {
  93. SInt8    memState;
  94.  
  95.     memState = HGetState(theHandle);
  96.     
  97.     //•    Check the resource bit in the handle info
  98.     if (memState & 0x20)
  99.         return (true);
  100.         
  101.     return (false);
  102. }
  103. //•    ————————————————————    IsLockedHandle
  104.  
  105. Boolean
  106. IsLockedHandle(Handle theHandle)
  107. {
  108. SInt8    memState;
  109.  
  110.     //•    Check the lock bit in the handle info
  111.     memState = HGetState(theHandle);
  112.     
  113.     if (memState & 0x80)
  114.         return (true);
  115.         
  116.     return (false);
  117. }
  118.  
  119. //•    ————————————————————    DisposeControlZ
  120.  
  121. void
  122. DisposeControlZ(ControlHandle *theControl)
  123. {
  124.     if (! (**theControl))
  125.         return;
  126.  
  127.     if (IsLockedHandle((Handle) *theControl))
  128.         HUnlock((Handle) *theControl);
  129.  
  130.     DisposeControl(*theControl);
  131.     *theControl = nil;
  132. }
  133.  
  134. //•    ————————————————————    DisposeWindowZ
  135.  
  136. void
  137. DisposeWindowZ(WindowPtr *theWindow)
  138. {
  139.     if (nil == theWindow)
  140.         return;
  141.         
  142.     if (nil == *theWindow)
  143.         return;
  144.  
  145.     DisposeWindow(*theWindow);
  146.     *theWindow = nil;
  147. }
  148.  
  149. //•    ————————————————————    DisposeDialogZ
  150.  
  151. void
  152. DisposeDialogZ(DialogPtr *theWindow)
  153. {
  154.     if (! *theWindow)
  155.         return;
  156.  
  157.     DisposeDialog(*theWindow);
  158.     *theWindow = nil;
  159. }
  160.  
  161. //•    ————————————————————    DisposeGWorldZ
  162.  
  163. void
  164. DisposeGWorldZ(GWorldPtr *theGWorld)
  165. {
  166.     if (! *theGWorld)
  167.         return;
  168.  
  169.     if (IsLockedHandle((Handle) GetGWorldPixMap(*theGWorld)))
  170.         UnlockPixels(GetGWorldPixMap(*theGWorld));
  171.         
  172.     DisposeGWorld(*theGWorld);
  173.     *theGWorld = nil;
  174. }
  175.  
  176. //•    ————————————————————    DisposePaletteZ
  177.  
  178. void
  179. DisposePaletteZ(PaletteHandle *thePal)
  180. {
  181.     if (! *thePal)
  182.         return;
  183.  
  184.     if (IsResourceHandle((Handle) *thePal))
  185.         ReleaseResource((Handle) *thePal);
  186.     else
  187.         DisposePalette(*thePal);
  188.         
  189.     *thePal = nil;
  190. }
  191.  
  192. //•    ————————————————————    KillPictureZ
  193.  
  194. void
  195. KillPictureZ(PicHandle *thePicture)
  196. {
  197.     if (! (**thePicture))
  198.         return;
  199.  
  200.     if (IsLockedHandle((Handle) *thePicture))
  201.         HUnlock((Handle) *thePicture);
  202.  
  203.     if (IsResourceHandle((Handle) *thePicture))
  204.         ReleaseResource((Handle) *thePicture);
  205.     else
  206.         KillPicture(*thePicture);
  207.         
  208.     *thePicture = nil;
  209. }
  210.  
  211. //•    ————————————————————    DisposePtrZ
  212.  
  213. void
  214. DisposePtrZ(Ptr *thePtr)
  215. {
  216.     if (! *thePtr)
  217.         return;
  218.  
  219.     DisposePtr(*thePtr);
  220.     *thePtr = nil;
  221. }
  222.  
  223. //•    ————————————————————    DisposeHandleZ
  224.  
  225. void
  226. DisposeHandleZ(Handle *theHandle)
  227. {
  228.     if (! (**theHandle))
  229.         return;
  230.  
  231.     if (IsLockedHandle(*theHandle))
  232.         HUnlock(*theHandle);
  233.         
  234.     if (IsResourceHandle(*theHandle))
  235.         ReleaseResource(*theHandle);
  236.     else
  237.         DisposeHandle(*theHandle);
  238.         
  239.     *theHandle = nil;
  240. }
  241.  
  242. //•    ————————————————————    TEDisposeZ
  243.  
  244. void
  245. TEDisposeZ(TEHandle *theHandle)
  246. {
  247.     if (! (**theHandle))
  248.         return;
  249.  
  250.     if (IsLockedHandle((Handle) *theHandle))
  251.         HUnlock((Handle) *theHandle);
  252.         
  253.     if (IsResourceHandle((Handle) *theHandle))
  254.         ReleaseResource((Handle) *theHandle);
  255.     else
  256.         TEDispose(*theHandle);
  257. }
  258.  
  259. //•    ————————————————————    LDisposeZ
  260.  
  261. void
  262. LDisposeZ(ListHandle *theHandle)
  263. {
  264.     if (! (**theHandle))
  265.         return;
  266.  
  267.     if (IsLockedHandle((Handle) *theHandle))
  268.         HUnlock((Handle) *theHandle);
  269.         
  270.     if (IsResourceHandle((Handle) *theHandle))
  271.         ReleaseResource((Handle) *theHandle);
  272.     else
  273.         LDispose(*theHandle);
  274. }
  275.  
  276. //•    ————————————————————    PurgeAndCompactMem
  277.  
  278. void
  279. PurgeAndCompactMem()
  280. {
  281. Size    growSize;
  282.  
  283.     MaxMem(&growSize);
  284. }
  285.  
  286. //•    ————————————————————    NewTaggedPtr
  287.  
  288. Ptr
  289. NewTaggedPtr(Size size, OSType tag, UInt32 refCon)
  290. {
  291. Ptr    thePtr;
  292.  
  293.     size += 12;
  294.  
  295.     thePtr = NewPtr(size);
  296.     if (! thePtr)
  297.         return (nil);
  298.  
  299.     BlockMoveData(kBlockTag, thePtr, 4);
  300.     BlockMoveData(&tag, thePtr + 4, 4);
  301.     BlockMoveData(&refCon, thePtr + 8, 4);
  302.  
  303.     gAllocatedRam += size;
  304.  
  305.     return (thePtr + 12);
  306. }
  307.  
  308. //•    ————————————————————    NewTaggedPtrClear
  309.  
  310. Ptr
  311. NewTaggedPtrClear(Size size, OSType tag, UInt32 refCon)
  312. {
  313. Ptr    thePtr;
  314.  
  315.     size += 12;
  316.  
  317.     thePtr = NewPtrClear(size);
  318.     if (! thePtr)
  319.         return (nil);
  320.  
  321.     BlockMoveData(kBlockTag, thePtr, 4);
  322.     BlockMoveData(&tag, thePtr + 4, 4);
  323.     BlockMoveData(&refCon, thePtr + 8, 4);
  324.  
  325.     gAllocatedRam += size;
  326.  
  327.     return (thePtr + 12);
  328. }
  329.  
  330. //•    ————————————————————    DisposeTaggedPtr
  331.  
  332. void
  333. DisposeTaggedPtr(Ptr thePtr)
  334. {
  335. Ptr        ptr2;
  336. Size    size;
  337.  
  338.     if (! thePtr)
  339.         return;
  340.  
  341.     ptr2 = thePtr - 12;
  342.     size = GetPtrSize(ptr2);
  343.     
  344.     //•    Confirm that this is one of our tagged blocks first
  345.     if (strncmp(kBlockTag, ptr2, 4) == 0)
  346.     {
  347.         DisposePtr(ptr2);
  348.         gAllocatedRam -= size;
  349.     }
  350.     else
  351.     {
  352.         DisposePtr(thePtr);
  353.     }
  354. }
  355.  
  356. //•    ————————————————————    DisposeTaggedPtrZ
  357.  
  358. void
  359. DisposeTaggedPtrZ(Ptr *thePtr)
  360. {
  361. Ptr        ptr2;
  362. Size    size;
  363.  
  364.     if (! *thePtr)
  365.         return;
  366.  
  367.     ptr2 = (*thePtr) - 12;
  368.     size = GetPtrSize(ptr2);
  369.     
  370.     if (strncmp(kBlockTag, ptr2, 4) == 0)
  371.     {
  372.         DisposePtr(ptr2);
  373.         gAllocatedRam -= size;
  374.     }
  375.     else
  376.     {
  377.         DisposePtr(*thePtr);
  378.     }
  379.         
  380.     *thePtr = nil;
  381. }
  382.  
  383. //•    ————————————————————    GetAllocatedRam
  384.  
  385. UInt32
  386. GetAllocatedRam(void)
  387. {
  388.     return (gAllocatedRam);
  389. }