cstool/framedataholder.h Source File (Crystal Space 2.0 Public API Reference)

| ## Public API Reference

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

cstool/framedataholder.h
Go to the documentation of this file.

    00001 /*
    00002     Copyright (C) 2004 by Jorrit Tyberghein
    00003               (C) 2004 by Frank Richter
    00004
    00005     This library is free software; you can redistribute it and/or
    00006     modify it under the terms of the GNU Library General Public
    00007     License as published by the Free Software Foundation; either
    00008     version 2 of the License, or (at your option) any later version.
    00009
    00010     This library is distributed in the hope that it will be useful,
    00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
    00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00013     Library General Public License for more details.
    00014
    00015     You should have received a copy of the GNU Library General Public
    00016     License along with this library; if not, write to the Free
    00017     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    00018 */
    00019
    00020 #ifndef __CS_CSTOOL_FRAMEDATAHOLDER_H__
    00021 #define __CS_CSTOOL_FRAMEDATAHOLDER_H__
    00022
    00028 #include "csgeom/math.h"
    00029 #include "csutil/array.h"
    00030
    00037 template <class T>
    00038 class csFrameDataHolder
    00039 {
    00041   struct FrameData
    00042   {
    00044     uint lastFrame;
    00046     T data;
    00047   };
    00049   csArray<FrameData> data;
    00051   size_t lastData;
    00053   uint nextShrink;
    00055   uint lastFrame;
    00057   uint clearReq;
    00058
    00060   void NewFrame()
    00061   {
    00062     if (clearReq != (uint)~0)
    00063     {
    00064       data.DeleteAll();
    00065       clearReq = (uint)~0;
    00066     }
    00067     // Try to shrink the cache to a size that reflects what's needed
    00068     if (lastFrame > nextShrink)
    00069     {
    00070       /* lastData is reset every frame, so it gives a good indicator
    00071        * on how much has been used the last frame */
    00072       data.Truncate (csMin(lastData+1, data.GetSize ()));
    00073       data.ShrinkBestFit ();
    00074       nextShrink = (uint)~0;
    00075     }
    00076     else if (lastData+1 < data.GetSize())
    00077     {
    00078       // Last frame we used less cache than available.
    00079       // "Schedule" a shrink in the future.
    00080       nextShrink = lastFrame + 5;
    00081     }
    00082     lastData = 0;
    00083   }
    00084 public:
    00085   csFrameDataHolder () : lastData(0), nextShrink((uint)~0),
    00086         lastFrame((uint)~0), clearReq((uint)~0)
    00087   { }
    00088   ~csFrameDataHolder () { }
    00089
    00097   T& GetUnusedData (bool& created, uint frameNumber)
    00098   {
    00099     if (lastFrame != frameNumber)
    00100     {
    00101       NewFrame();
    00102       lastFrame = frameNumber;
    00103     }
    00104     created = false;
    00105     if ((data.GetSize() == 0) || (data[lastData].lastFrame == frameNumber))
    00106     {
    00107       size_t startPoint = lastData;
    00108       //check the list
    00109       if (data.GetSize() > 0)
    00110       {
    00111         do
    00112         {
    00113           if (data[lastData].lastFrame != frameNumber)
    00114             break;
    00115           lastData++;
    00116           if (lastData >= data.GetSize()) lastData = 0;
    00117         }
    00118         while (lastData != startPoint);
    00119       }
    00120       if (lastData == startPoint)
    00121       {
    00122         data.SetSize ((lastData = data.GetSize ()) + 1);
    00123         created = true;
    00124       }
    00125     }
    00126
    00127     FrameData& frameData = data[lastData];
    00128     frameData.lastFrame = frameNumber;
    00129     return frameData.data;
    00130   }
    00131
    00141   void Clear (bool instaClear = false)
    00142   {
    00143     if (instaClear)
    00144       data.DeleteAll();
    00145     else
    00146       // Don't clear just yet, rather, clear when we enter the next frame.
    00147       clearReq = lastFrame;
    00148   }
    00149 };
    00150
    00151 #endif // __CS_CSTOOL_FRAMEDATAHOLDER_H__