sysperfana/heapanalyser/Libraries/UI/HeapCtrlLib/Utilities/HeapCellMetaData.cs
changeset 8 15296fd0af4a
equal deleted inserted replaced
7:8e12a575a9b5 8:15296fd0af4a
       
     1 /*
       
     2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 *
       
     5 * Redistribution and use in source and binary forms, with or without
       
     6 * modification, are permitted provided that the following conditions are met:
       
     7 *
       
     8 * - Redistributions of source code must retain the above copyright notice,
       
     9 *   this list of conditions and the following disclaimer.
       
    10 * - Redistributions in binary form must reproduce the above copyright notice,
       
    11 *   this list of conditions and the following disclaimer in the documentation
       
    12 *   and/or other materials provided with the distribution.
       
    13 * - Neither the name of Nokia Corporation nor the names of its contributors
       
    14 *   may be used to endorse or promote products derived from this software
       
    15 *   without specific prior written permission.
       
    16 *
       
    17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
       
    18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
       
    19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
       
    20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
       
    21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
       
    22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
       
    23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
       
    24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
       
    25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
       
    26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
       
    27 * POSSIBILITY OF SUCH DAMAGE.
       
    28 * 
       
    29 * Initial Contributors:
       
    30 * Nokia Corporation - initial contribution.
       
    31 *
       
    32 * Contributors:
       
    33 *
       
    34 * Description: 
       
    35 *
       
    36 */
       
    37 
       
    38 using System;
       
    39 using System.Drawing;
       
    40 using HeapLib.Cells;
       
    41 using SymbianUtils.RawItems;
       
    42 
       
    43 namespace HeapCtrlLib.Utilities
       
    44 {
       
    45     public class HeapCellMetaData
       
    46     {
       
    47         #region Constructors & destructor
       
    48         public HeapCellMetaData( HeapRenderingNavigator aNavigator )
       
    49         {
       
    50             aNavigator.iNavBegin += new HeapCtrlLib.Utilities.HeapRenderingNavigator.NavBegin( Navigator_NavBegin );
       
    51             aNavigator.iNavEnd += new HeapCtrlLib.Utilities.HeapRenderingNavigator.NavEnd( Navigator_NavEnd );
       
    52             aNavigator.iNavHeapCellBegin += new HeapCtrlLib.Utilities.HeapRenderingNavigator.NavHeapCellBegin( Navigator_NavHeapCellBegin );
       
    53             aNavigator.iNavHeapCellEnd += new HeapCtrlLib.Utilities.HeapRenderingNavigator.NavHeapCellEnd( Navigator_NavHeapCellEnd );
       
    54             aNavigator.iNavNewColumn += new HeapCtrlLib.Utilities.HeapRenderingNavigator.NavNewColumn( Navigator_NavNewColumn );
       
    55             aNavigator.iNavNewRowBody += new HeapCtrlLib.Utilities.HeapRenderingNavigator.NavNewRowBody( Navigator_NavNewRowBody );
       
    56         }
       
    57         #endregion
       
    58 
       
    59         #region Properties
       
    60         public Point BoxCoordinates
       
    61         {
       
    62             get { return iBoxCoordinates; }
       
    63             set { iBoxCoordinates = value; }
       
    64         }
       
    65 
       
    66         public int RemainingBoxes
       
    67         {
       
    68             get { return iRemainingBoxes; }
       
    69             set { iRemainingBoxes = value; }
       
    70         }
       
    71 
       
    72         public int RemainingBoxesAfterThisRow
       
    73         {
       
    74             get { return iRemainingBoxesAfterThisRow; }
       
    75             set { iRemainingBoxesAfterThisRow = value; }
       
    76         }
       
    77 
       
    78         public int RemainingRows
       
    79         {
       
    80             get { return iRemainingRows; }
       
    81             set { iRemainingRows = value; }
       
    82         }
       
    83 
       
    84         public long RemainingBytes
       
    85         {
       
    86             get { return iRemainingBytes; }
       
    87             set { iRemainingBytes = value; }
       
    88         }
       
    89 
       
    90         public int CellBoxIndex
       
    91         {
       
    92             get { return iCellBoxIndex; }
       
    93             set { iCellBoxIndex = value; }
       
    94         }
       
    95 
       
    96         public int CellRowIndex
       
    97         {
       
    98             get { return iCellRowIndex; }
       
    99             set { iCellRowIndex = value; }
       
   100         }
       
   101 
       
   102         public int CellBoxCount
       
   103         {
       
   104             get { return iCellBoxCount; }
       
   105             set { iCellBoxCount = value; }
       
   106         }
       
   107 
       
   108         public RawItem RawItem
       
   109         {
       
   110             get { return iRawItem; }
       
   111         }
       
   112 
       
   113         public HeapCell.TRegion Region
       
   114         {
       
   115             get
       
   116             {
       
   117                 System.Diagnostics.Debug.Assert( iCell != null, "Not rendering a heap cell" );
       
   118                 System.Diagnostics.Debug.Assert( iAddress > 0, "Invalid current address" );
       
   119                 //
       
   120                 HeapCell.TRegion region = iCell.RegionForAddress( iAddress );
       
   121                 return region;
       
   122             }
       
   123         }
       
   124 
       
   125         public HeapCellBorderInfo Borders
       
   126         {
       
   127             get { return iBorders; }
       
   128             set { iBorders = value; }
       
   129         }
       
   130 
       
   131         // Set by the content renderer, read by the border renderer
       
   132         public Color CellBoxColor
       
   133         {
       
   134             get { return iCellBoxColor; }
       
   135             set { iCellBoxColor = value; }
       
   136         }
       
   137         #endregion
       
   138 
       
   139         #region Internal methods
       
   140         private void CalculateBorders( HeapCell aCell, long aAddress, Size aDimensions )
       
   141         {
       
   142             long remainingBoxes = ( aCell.EndAddress - aAddress ) / SymbianUtils.RawItems.RawItem.KSizeOfOneRawItemInBytes;
       
   143 
       
   144             // Start with no borders
       
   145             Borders.Reset();
       
   146 
       
   147             // How many boxes are left to render on this row
       
   148             int remainingBoxesForThisLine = ( aDimensions.Width - BoxCoordinates.X );
       
   149 
       
   150             // Its the first line if we are drawing the first row, or if we're drawing the
       
   151             // second row and there weren't any boxes from this heap cell directly above us
       
   152             // in the grid.
       
   153             bool firstLine = ( CellRowIndex == 0 );
       
   154             if  ( CellRowIndex == 1 )
       
   155             {
       
   156                 int numberOfBoxesDrawnOnPreviousLine = ( CellBoxIndex - BoxCoordinates.X );
       
   157                 int xPosOfFirstBox = aDimensions.Width - numberOfBoxesDrawnOnPreviousLine;
       
   158                 firstLine = ( BoxCoordinates.X < xPosOfFirstBox );
       
   159             }
       
   160             Borders.SetBorder( THeapCellBorderType.ETop, firstLine );
       
   161 
       
   162             // Its the last line if we are drawing the last row, or then if we're drawing
       
   163             // the last-but-one row and there weren't any boxes from this heap cell directly
       
   164             // below us in the grid.
       
   165             bool lastLine = ( RemainingBoxes <= remainingBoxesForThisLine );
       
   166             if  ( RemainingRows > 0 && BoxCoordinates.Y == aDimensions.Height - 1 )
       
   167             {
       
   168                 lastLine = true;
       
   169             }
       
   170             else if ( RemainingRows == 1 )
       
   171             {
       
   172                 // Now we need to work out how many boxes of the next row will be
       
   173                 // required to finish rendering it fully.
       
   174                 lastLine = ( BoxCoordinates.X >= RemainingBoxesAfterThisRow );
       
   175             }
       
   176             Borders.SetBorder( THeapCellBorderType.EBottom, lastLine );
       
   177 
       
   178             // Its the first box if it is the absolute first box we have rendered for a given
       
   179             // cell, or then it is the first box in a new row.
       
   180             bool firstBox = ( CellBoxIndex == 0 ) || ( BoxCoordinates.X == 0 );
       
   181             Borders.SetBorder( THeapCellBorderType.ELeft, firstBox );
       
   182 
       
   183             // Its the last box if it is the absolute last box we have rendered for a given
       
   184             // cell, or then it is the last box in a new row.
       
   185             bool lastBox = ( CellBoxIndex == CellBoxCount - 1 ) || ( remainingBoxes == 0 ) || ( BoxCoordinates.X == aDimensions.Width - 1 );
       
   186             Borders.SetBorder( THeapCellBorderType.ERight, lastBox );
       
   187         }
       
   188         #endregion
       
   189 
       
   190         #region Navigator call backs
       
   191         private void Navigator_NavBegin()
       
   192         {
       
   193         }
       
   194 
       
   195         private void Navigator_NavEnd()
       
   196         {
       
   197             iCell = null;
       
   198         }
       
   199 
       
   200         private void Navigator_NavHeapCellBegin( HeapCell aCell, uint aAddress, Point aPosition, Size aDimensions, Size aBoxSize, Size aPadding )
       
   201         {
       
   202             // Starting a new cell
       
   203             iCell = aCell;
       
   204             iAddress = aAddress;
       
   205 
       
   206             // This contains the absolute number of boxes required to render a given
       
   207             // heap cell.
       
   208             CellBoxCount = (int) ( aCell.Length / SymbianUtils.RawItems.RawItem.KSizeOfOneRawItemInBytes );
       
   209             BoxCoordinates = new Point();
       
   210             RemainingBoxes = 0;
       
   211             RemainingBoxesAfterThisRow = 0;
       
   212             RemainingRows = 0;
       
   213             RemainingBytes = 0;
       
   214             CellRowIndex = 0;
       
   215             Borders.Reset();
       
   216  
       
   217             // Reset current raw item - we won't have a new one until we hit the payload section
       
   218             iRawItem = null;
       
   219 
       
   220             // This starts at -1 since the first act of
       
   221             // preparing the meta data is to increment the index by one.
       
   222             CellBoxIndex = -1;
       
   223         }
       
   224 
       
   225         private void Navigator_NavHeapCellEnd( HeapCell aCell, HeapCellMetaData aMetaData, uint aAddress, Point aPosition, Size aDimensions, Size aBoxSize, Size aPadding )
       
   226         {
       
   227             // Finished with the cell...
       
   228             iCell = null;
       
   229         }
       
   230 
       
   231         private void Navigator_NavNewColumn( HeapCell aCell, HeapCellMetaData aMetaData, uint aAddress, Point aPixelPos, Point aBoxPos, Size aDimensions, Size aBoxSize, Size aPadding )
       
   232         {
       
   233             System.Diagnostics.Debug.Assert( iCell != null && iCell.Address == aCell.Address );
       
   234 
       
   235             // Indicate that we're processing a new box
       
   236             ++CellBoxIndex;
       
   237             iAddress = aAddress;
       
   238 
       
   239             // Set our box coordinates
       
   240             iBoxCoordinates = aBoxPos;
       
   241 
       
   242             // Get current raw item if we're in the payload section
       
   243             iRawItem = null;
       
   244             try
       
   245             {
       
   246                 HeapCell.TRegion region = Region;
       
   247                 if ( region == HeapCell.TRegion.EPayload )
       
   248                 {
       
   249                     iRawItem = iCell[ aAddress ];
       
   250                 }
       
   251             }
       
   252             catch( ArgumentException )
       
   253             {
       
   254             }
       
   255 
       
   256 
       
   257             // Some up front calculations that we'll need below...
       
   258             RemainingBytes = aCell.Remainder( aAddress );
       
   259             int remainingBoxesForThisLine = ( aDimensions.Width - BoxCoordinates.X );
       
   260             RemainingBoxes = (int) ( RemainingBytes / SymbianUtils.RawItems.RawItem.KSizeOfOneRawItemInBytes );
       
   261             RemainingBoxesAfterThisRow = Math.Max( 0, RemainingBoxes - remainingBoxesForThisLine );
       
   262 
       
   263             // If we can render all the remaining boxes in the not-yet-drawn
       
   264             // boxes from this row, we don't need anymore rows.
       
   265             RemainingRows = 0;
       
   266             if  ( RemainingBoxesAfterThisRow > 0 )
       
   267             {
       
   268                 // Otherwise, we need to identify how many more rows we will need
       
   269                 // in order to complete the remaining boxes that are left over
       
   270                 // after this row's boxes.
       
   271                 RemainingRows = ( RemainingBoxesAfterThisRow / aDimensions.Width ) + 1;
       
   272             }
       
   273 
       
   274             // Work out the borders that should be enabled for the cell
       
   275             CalculateBorders( aCell, aAddress, aDimensions );
       
   276         }
       
   277 
       
   278         private void Navigator_NavNewRowBody( HeapCellMetaData aMetaData, uint aAddress, Point aPosition, Size aDimensions, Size aBoxSize, Size aPadding )
       
   279         {
       
   280             ++CellRowIndex;
       
   281         }
       
   282         #endregion
       
   283 
       
   284         #region Data members
       
   285         private Point iBoxCoordinates = new Point( 0, 0 );
       
   286         private int iRemainingBoxes = 0;
       
   287         private int iRemainingBoxesAfterThisRow = 0;
       
   288         private int iRemainingRows = 0;
       
   289         private long iRemainingBytes = 0;
       
   290         private int iCellBoxIndex = 0;
       
   291         private int iCellRowIndex = 0;
       
   292         private int iCellBoxCount = 0;
       
   293         private uint iAddress = 0;
       
   294         private HeapCell iCell = null;
       
   295         private RawItem iRawItem = null;
       
   296         private HeapCellBorderInfo iBorders = new HeapCellBorderInfo();
       
   297         private Color iCellBoxColor = Color.HotPink;
       
   298         #endregion
       
   299     }
       
   300 }