]> git.saurik.com Git - wxWidgets.git/blobdiff - contrib/src/fl/gcupdatesmgr.cpp
fix evaluation order bug (patch 1158099)
[wxWidgets.git] / contrib / src / fl / gcupdatesmgr.cpp
index dfe73d3811f56e99cf3b90541dd3ac85f29fe4f9..577ccfd1c33dd762caa02320888e54ddc5d29dda 100644 (file)
@@ -1,12 +1,12 @@
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
-// Name:        No names yet.
-// Purpose:     Contrib. demo
+// Name:        gcupdatesmgr.cpp
+// Purpose:     cbGCUpdatesMgr class, optimizing refresh using GarbageCollector
 // Author:      Aleksandras Gluchovas
 // Modified by:
 // Created:     19/10/98
 // RCS-ID:      $Id$
 // Copyright:   (c) Aleksandras Gluchovas 
 // Author:      Aleksandras Gluchovas
 // Modified by:
 // Created:     19/10/98
 // RCS-ID:      $Id$
 // Copyright:   (c) Aleksandras Gluchovas 
-// Licence:    wxWindows license
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 #ifdef __GNUG__
 /////////////////////////////////////////////////////////////////////////////
 
 #ifdef __GNUG__
 
 static inline bool rect_hits_rect( const wxRect& r1, const wxRect& r2 )
 {
 
 static inline bool rect_hits_rect( const wxRect& r1, const wxRect& r2 )
 {
-       if ( ( r2.x >= r1.x && r2.x <= r1.x + r1.width ) ||
-                ( r1.x >= r2.x && r1.x <= r2.x + r2.width ) )
+    if ( ( r2.x >= r1.x && r2.x <= r1.x + r1.width ) ||
+         ( r1.x >= r2.x && r1.x <= r2.x + r2.width ) )
 
 
-               if ( ( r2.y >= r1.y && r2.y <= r1.y + r1.height ) ||
-                        ( r1.y >= r2.y && r1.y <= r2.y + r2.height ) )
-                        
-                       return 1;
+        if ( ( r2.y >= r1.y && r2.y <= r1.y + r1.height ) ||
+             ( r1.y >= r2.y && r1.y <= r2.y + r2.height ) )
+             
+            return 1;
 
 
-       return 0;
+    return 0;
 }
 
 // helper structure
 
 struct cbRectInfo
 {
 }
 
 // helper structure
 
 struct cbRectInfo
 {
-       cbBarInfo*  mpBar;
-       cbDockPane* mpPane;
-       wxRect*     mpCurBounds;
-       wxRect*     mpPrevBounds;
+    cbBarInfo*  mpBar;
+    cbDockPane* mpPane;
+    wxRect*     mpCurBounds;
+    wxRect*     mpPrevBounds;
 };
 
 static inline cbRectInfo& node_to_rect_info( wxNode* pNode )
 {
 };
 
 static inline cbRectInfo& node_to_rect_info( wxNode* pNode )
 {
-       return *( (cbRectInfo*) (pNode->Data()) );
+    return *( (cbRectInfo*) (pNode->GetData()) );
 }
 
 /***** Implementation for class cbSimpleUpdatesMgr *****/
 }
 
 /***** Implementation for class cbSimpleUpdatesMgr *****/
@@ -61,350 +61,350 @@ static inline cbRectInfo& node_to_rect_info( wxNode* pNode )
 IMPLEMENT_DYNAMIC_CLASS( cbGCUpdatesMgr, cbSimpleUpdatesMgr )
 
 cbGCUpdatesMgr::cbGCUpdatesMgr( wxFrameLayout* pPanel )
 IMPLEMENT_DYNAMIC_CLASS( cbGCUpdatesMgr, cbSimpleUpdatesMgr )
 
 cbGCUpdatesMgr::cbGCUpdatesMgr( wxFrameLayout* pPanel )
-       : cbSimpleUpdatesMgr( pPanel )
+    : cbSimpleUpdatesMgr( pPanel )
 {}
 
 void cbGCUpdatesMgr::AddItem( wxList&     itemList,
 {}
 
 void cbGCUpdatesMgr::AddItem( wxList&     itemList,
-                                                     cbBarInfo*  pBar, 
-                                                         cbDockPane* pPane,
-                                                         wxRect&     curBounds,
-                                                         wxRect&     prevBounds )
+                              cbBarInfo*  pBar, 
+                              cbDockPane* pPane,
+                              wxRect&     curBounds,
+                              wxRect&     prevBounds )
 {
 {
-       cbRectInfo* pInfo = new cbRectInfo();
+    cbRectInfo* pInfo = new cbRectInfo();
 
 
-       pInfo->mpBar     = pBar;
-       pInfo->mpPane       = pPane;
-       pInfo->mpCurBounds  = &curBounds;
-       pInfo->mpPrevBounds = &prevBounds;
+    pInfo->mpBar     = pBar;
+    pInfo->mpPane       = pPane;
+    pInfo->mpCurBounds  = &curBounds;
+    pInfo->mpPrevBounds = &prevBounds;
 
 
-       itemList.Append( (wxObject*) pInfo );
+    itemList.Append( (wxObject*) pInfo );
 }
 
 void cbGCUpdatesMgr::OnStartChanges()
 {
 }
 
 void cbGCUpdatesMgr::OnStartChanges()
 {
-       // memorize states of ALL items in the layout -
-       // this is quite excessive, but OK for the decent 
-       // implementation of updates manager
+    // memorize states of ALL items in the layout -
+    // this is quite excessive, but OK for the decent 
+    // implementation of updates manager
 
 
-       mpLayout->GetPrevClientRect() = mpLayout->GetClientRect();
+    mpLayout->GetPrevClientRect() = mpLayout->GetClientRect();
 
 
-       cbDockPane** panes = mpLayout->GetPanesArray();
+    cbDockPane** panes = mpLayout->GetPanesArray();
 
 
-       for( int n = 0; n != MAX_PANES; ++n )
-       {
-               cbDockPane& pane = *(panes[n]);
+    for( int n = 0; n != MAX_PANES; ++n )
+    {
+        cbDockPane& pane = *(panes[n]);
 
 
-               // store pane state
-               pane.mUMgrData.StoreItemState( pane.mBoundsInParent );
-               pane.mUMgrData.SetDirty( FALSE );
+        // store pane state
+        pane.mUMgrData.StoreItemState( pane.mBoundsInParent );
+        pane.mUMgrData.SetDirty( false );
 
 
-               cbRowInfo* pRow = pane.GetFirstRow();
+        cbRowInfo* pRow = pane.GetFirstRow();
 
 
-               while ( pRow )
-               {
-                       cbBarInfo* pBar = pRow->GetFirstBar();
+        while ( pRow )
+        {
+            cbBarInfo* pBar = pRow->GetFirstBar();
 
 
-                       // store row state
-                       pRow->mUMgrData.StoreItemState( pRow->mBoundsInParent );
-                       pRow->mUMgrData.SetDirty( FALSE );
+            // store row state
+            pRow->mUMgrData.StoreItemState( pRow->mBoundsInParent );
+            pRow->mUMgrData.SetDirty( false );
 
 
-                       while( pBar )
-                       {
-                               // store bar state
-                               pBar->mUMgrData.StoreItemState( pBar->mBoundsInParent );
-                               pBar->mUMgrData.SetDirty( FALSE );
+            while( pBar )
+            {
+                // store bar state
+                pBar->mUMgrData.StoreItemState( pBar->mBoundsInParent );
+                pBar->mUMgrData.SetDirty( false );
 
 
-                               pBar = pBar->mpNext;
-                       }
+                pBar = pBar->mpNext;
+            }
 
 
-                       pRow = pRow->mpNext;
-               }
-       }
+            pRow = pRow->mpNext;
+        }
+    }
 }
 
 void cbGCUpdatesMgr::UpdateNow()
 {
 }
 
 void cbGCUpdatesMgr::UpdateNow()
 {
-       cbDockPane** panes = mpLayout->GetPanesArray();
+    cbDockPane** panes = mpLayout->GetPanesArray();
 
 
-       wxRect& r1 = mpLayout->GetClientRect();
-       wxRect& r2 = mpLayout->GetPrevClientRect();
+    wxRect& r1 = mpLayout->GetClientRect();
+    wxRect& r2 = mpLayout->GetPrevClientRect();
 
 
-       // detect changes in client window's area
+    // detect changes in client window's area
 
 
-       bool clientWindowChanged = ( r1.x      != r2.x     ||
-                                        r1.y      != r2.y     ||
-                                                                r1.width  != r2.width ||
-                                                                r1.height != r2.height );
+    bool clientWindowChanged = ( r1.x      != r2.x     ||
+                                 r1.y      != r2.y     ||
+                                 r1.width  != r2.width ||
+                                 r1.height != r2.height );
 
 
-       // step #1 - detect changes in each row of each pane,
-       //           and repaint decorations around changed windows
+    // step #1 - detect changes in each row of each pane,
+    //           and repaint decorations around changed windows
 
 
-       wxList mBarsToResize;
+    wxList mBarsToResize;
 
 
-       int n;
-       for ( n = 0; n != MAX_PANES; ++n )
-       {
-               cbDockPane& pane = *(panes[n]);
+    int n;
+    for ( n = 0; n != MAX_PANES; ++n )
+    {
+        cbDockPane& pane = *(panes[n]);
 
 
-               bool paneChanged = WasChanged( pane.mUMgrData, pane.mBoundsInParent );
+        bool paneChanged = WasChanged( pane.mUMgrData, pane.mBoundsInParent );
 
 
-               if ( paneChanged )
-               {
-                       wxClientDC dc( &mpLayout->GetParentFrame() );
-                       pane.PaintPaneBackground( dc );
-               }
+        if ( paneChanged )
+        {
+            wxClientDC dc( &mpLayout->GetParentFrame() );
+            pane.PaintPaneBackground( dc );
+        }
 
 
-               wxRect realBounds;
+        wxRect realBounds;
 
 
-               cbRowInfo* pRow = pane.GetFirstRow();
+        cbRowInfo* pRow = pane.GetFirstRow();
 
 
-               while ( pRow )
-               {
-                       wxDC* pDc = 0;
+        while ( pRow )
+        {
+            wxDC* pDc = 0;
 
 
-                       cbBarInfo* pBar = pRow->GetFirstBar();
+            cbBarInfo* pBar = pRow->GetFirstBar();
 
 
-                       bool rowChanged = FALSE;
-//                     bool rowBkPainted  = FALSE;
+            bool rowChanged = false;
+//            bool rowBkPainted  = false;
 
 
-                       // FIXME:: the below should not be fixed
-                       cbBarInfo* barsToRepaint[128];
-                       // number of bars, that were changed in the current row
-                       int nBars = 0; 
+            // FIXME:: the below should not be fixed
+            cbBarInfo* barsToRepaint[128];
+            // number of bars, that were changed in the current row
+            int nBars = 0; 
 
 
-                       wxRect r1 = pRow->mUMgrData.mPrevBounds;
-                       wxRect r2 = pRow->mBoundsInParent;
+            //wxRect r1 = pRow->mUMgrData.mPrevBounds;
+            //wxRect r2 = pRow->mBoundsInParent;
 
 
-                       if ( WasChanged( pRow->mUMgrData, pRow->mBoundsInParent ) )
-                       
-                               rowChanged = TRUE;
-                       else
-                               while( pBar )
-                               {
-                                       if ( WasChanged( pBar->mUMgrData, pBar->mBoundsInParent ) )
-                                       
-                                               barsToRepaint[nBars++] = pBar;
+            if ( WasChanged( pRow->mUMgrData, pRow->mBoundsInParent ) )
+            
+                rowChanged = true;
+            else
+                while( pBar )
+                {
+                    if ( WasChanged( pBar->mUMgrData, pBar->mBoundsInParent ) )
+                    
+                        barsToRepaint[nBars++] = pBar;
 
 
-                                       pBar = pBar->mpNext;
-                               }
+                    pBar = pBar->mpNext;
+                }
 
 
-                       if ( nBars || rowChanged )
-                       {
-                               realBounds = pRow->mBoundsInParent;
+            if ( nBars || rowChanged )
+            {
+                realBounds = pRow->mBoundsInParent;
 
 
-                               // include 1-pixel thick shades around the row
-                               realBounds.x -= 1;
-                               realBounds.y -= 1;
-                               realBounds.width  += 2;
-                               realBounds.height += 2;
+                // include 1-pixel thick shades around the row
+                realBounds.x -= 1;
+                realBounds.y -= 1;
+                realBounds.width  += 2;
+                realBounds.height += 2;
 
 
-                               pDc = pane.StartDrawInArea( realBounds );
-                       }
+                pDc = pane.StartDrawInArea( realBounds );
+            }
 
 
-                       if ( rowChanged )
-                       {
-                               // postphone the resizement and refreshing the changed
-                               // bar windows
+            if ( rowChanged )
+            {
+                // postphone the resizement and refreshing the changed
+                // bar windows
 
 
-                               cbBarInfo* pCurBar = pRow->GetFirstBar();
+                cbBarInfo* pCurBar = pRow->GetFirstBar();
 
 
-                               while ( pCurBar )
-                               {
-                                       if ( WasChanged( pCurBar->mUMgrData, 
-                                                                        pCurBar->mBoundsInParent ) )
+                while ( pCurBar )
+                {
+                    if ( WasChanged( pCurBar->mUMgrData, 
+                                     pCurBar->mBoundsInParent ) )
 
 
-                                               AddItem( mBarsToResize, pCurBar, &pane, 
-                                                                pCurBar->mBoundsInParent,
-                                                                pCurBar->mUMgrData.mPrevBounds );
+                        AddItem( mBarsToResize, pCurBar, &pane, 
+                                 pCurBar->mBoundsInParent,
+                                 pCurBar->mUMgrData.mPrevBounds );
 
 
-                                       pCurBar = pCurBar->mpNext;
-                               }
+                    pCurBar = pCurBar->mpNext;
+                }
 
 
-                               // draw only their decorations now
+                // draw only their decorations now
 
 
-                               pane.PaintRow( pRow, *pDc );
-                       }
-                       else
-                       if ( nBars != 0 )
-                       {
-                               for ( int i = 0; i != nBars; ++i )
+                pane.PaintRow( pRow, *pDc );
+            }
+            else
+            if ( nBars != 0 )
+            {
+                for ( int i = 0; i != nBars; ++i )
 
 
-                                       // postphone the resizement and refreshing the changed
-                                       // bar windows
+                    // postphone the resizement and refreshing the changed
+                    // bar windows
 
 
-                                       AddItem( mBarsToResize, 
-                                                        barsToRepaint[i], 
-                                                        &pane, 
-                                                    barsToRepaint[i]->mBoundsInParent,
-                                                        barsToRepaint[i]->mUMgrData.mPrevBounds );
+                    AddItem( mBarsToResize, 
+                             barsToRepaint[i], 
+                             &pane, 
+                             barsToRepaint[i]->mBoundsInParent,
+                             barsToRepaint[i]->mUMgrData.mPrevBounds );
 
 
-                               // redraw decorations of entire row, regardless of how much
-                               // of the bars were changed
+                // redraw decorations of entire row, regardless of how much
+                // of the bars were changed
 
 
-                               pane.PaintRow( pRow, *pDc );
-                       }
+                pane.PaintRow( pRow, *pDc );
+            }
 
 
-                       if ( pDc )
-               
-                               pane.FinishDrawInArea( realBounds );
+            if ( pDc )
+        
+                pane.FinishDrawInArea( realBounds );
 
 
-                       pRow = pRow->mpNext;
+            pRow = pRow->mpNext;
 
 
-               } // end of while
+        } // end of while
 
 
-               if ( paneChanged )
-               {
-                       wxClientDC dc( &mpLayout->GetParentFrame() );
-                       pane.PaintPaneDecorations( dc );
-               }
+        if ( paneChanged )
+        {
+            wxClientDC dc( &mpLayout->GetParentFrame() );
+            pane.PaintPaneDecorations( dc );
+        }
 
 
-       } // end of for
+    } // end of for
 
 
-       if ( clientWindowChanged && !mpLayout->mClientWndRefreshPending )
-       {
-               // ptr to client-window object is "marked" as NULL
+    if ( clientWindowChanged && !mpLayout->mClientWndRefreshPending )
+    {
+        // ptr to client-window object is "marked" as NULL
 
 
-               AddItem( mBarsToResize, NULL, NULL, 
-                            mpLayout->GetClientRect(),
-                                mpLayout->GetPrevClientRect() );
-       }
+        AddItem( mBarsToResize, NULL, NULL, 
+                 mpLayout->GetClientRect(),
+                 mpLayout->GetPrevClientRect() );
+    }
 
 
-       // step #2 - do ordered refreshing and resizing of bar window objects now
+    // step #2 - do ordered refreshing and resizing of bar window objects now
 
 
-       DoRepositionItems( mBarsToResize );
+    DoRepositionItems( mBarsToResize );
 }
 
 void cbGCUpdatesMgr::DoRepositionItems( wxList& items )
 {
 }
 
 void cbGCUpdatesMgr::DoRepositionItems( wxList& items )
 {
-       wxNode* pNode1 = items.First();
+    wxNode* pNode1 = items.GetFirst();
 
 
-       while( pNode1 )
-       {
-               cbRectInfo& info = node_to_rect_info( pNode1 );
+    while( pNode1 )
+    {
+        cbRectInfo& info = node_to_rect_info( pNode1 );
 
 
-               wxNode* pNode2 = items.First();
+        wxNode* pNode2 = items.GetFirst();
 
 
-               // and node itself
+        // and node itself
 
 
-               mGC.AddObject( &info );
+        mGC.AddObject( &info );
 
 
-               while( pNode2 )
-               {
-                       if ( pNode2 != pNode1 ) // node should not depend on itself
-                       {
-                               // add references to objects, on which this object
-                               // depends. Dependecy here indicates intersection of current
-                               // bounds of this object with the initial bounds of the
-                               // other object
+        while( pNode2 )
+        {
+            if ( pNode2 != pNode1 ) // node should not depend on itself
+            {
+                // Add references to objects on which this object
+                // depends. Dependency here indicates intersection of current
+                // bounds of this object with the initial bounds of the
+                // other object.
 
 
-                               cbRectInfo& otherInfo = node_to_rect_info( pNode2 );
+                cbRectInfo& otherInfo = node_to_rect_info( pNode2 );
 
 
-                               if ( rect_hits_rect( *info.mpCurBounds, *otherInfo.mpPrevBounds ) )
-                               
-                                                                       // the node    depends on node
-                                       mGC.AddDependency( &info,      &otherInfo      );
-                       }
+                if ( rect_hits_rect( *info.mpCurBounds, *otherInfo.mpPrevBounds ) )
+                
+                                    // the node    depends on node
+                    mGC.AddDependency( &info,      &otherInfo      );
+            }
 
 
-                       pNode2 = pNode2->Next();
-               }
+            pNode2 = pNode2->GetNext();
+        }
 
 
-               pNode1 = pNode1->Next();
-       }
+        pNode1 = pNode1->GetNext();
+    }
 
 
-       mGC.ArrangeCollection(); // order nodes according "least-dependency" rule,
-                                    // and find out cycled chains
+    mGC.ArrangeCollection(); // order nodes according "least-dependency" rule,
+                             // and find out cycled chains
 
 
-       // regular item nodes need to be resized, but not repainted (since
-       // they stand in linear (not cyclic) dependency with other
-       // regular nodes)
+    // Regular item nodes need to be resized, but not repainted (since
+    // they stand in linear (not cyclic) dependency with other
+    // regular nodes).
 
 
-       wxNode* pNode = mGC.GetRegularObjects().First();
+    wxNode* pNode = mGC.GetRegularObjects().GetFirst();
 
 
-       while ( pNode )
-       {
-               cbRectInfo& info = *((cbRectInfo*)gc_node_to_obj(pNode));
+    while ( pNode )
+    {
+        cbRectInfo& info = *((cbRectInfo*)gc_node_to_obj(pNode));
 
 
-               if ( info.mpBar == NULL ) 
-                       
-                       mpLayout->PositionClientWindow();
-               else
-                       info.mpPane->SizeBar( info.mpBar );
+        if ( info.mpBar == NULL ) 
+            
+            mpLayout->PositionClientWindow();
+        else
+            info.mpPane->SizeBar( info.mpBar );
 
 
-               pNode = pNode->Next();
-       }
+        pNode = pNode->GetNext();
+    }
 
 
-       // cycled item nodes, need to be both resized and repainted
+    // cycled item nodes, need to be both resized and repainted
 
 
-       pNode = mGC.GetCycledObjects().First();
+    pNode = mGC.GetCycledObjects().GetFirst();
 
 
-       while ( pNode )
-       {
-               cbRectInfo& info = *((cbRectInfo*)gc_node_to_obj(pNode));
+    while ( pNode )
+    {
+        cbRectInfo& info = *((cbRectInfo*)gc_node_to_obj(pNode));
 
 
-               if ( info.mpBar == NULL ) 
-               {
-                       wxWindow* pClntWnd = mpLayout->GetFrameClient();
+        if ( info.mpBar == NULL ) 
+        {
+            wxWindow* pClntWnd = mpLayout->GetFrameClient();
 
 
-                       mpLayout->PositionClientWindow();
+            mpLayout->PositionClientWindow();
 
 
-                       // FIXME FIXME:: excessive!
+            // FIXME FIXME:: excessive!
 
 
-                       pClntWnd->Show( FALSE );
-                       pClntWnd->Show( TRUE  );
+            pClntWnd->Show( false );
+            pClntWnd->Show( true  );
 
 
-                       // OLD STUFF:: mpLayout->PositionClientWindow();
-               }
-               else
-               if ( info.mpBar->mpBarWnd )
-               {
-                       wxWindow* pWnd = info.mpBar->mpBarWnd;
+            // OLD STUFF:: mpLayout->PositionClientWindow();
+        }
+        else
+        if ( info.mpBar->mpBarWnd )
+        {
+            wxWindow* pWnd = info.mpBar->mpBarWnd;
 
 
-                       // resize
-                       info.mpPane->SizeBar( info.mpBar );
+            // resize
+            info.mpPane->SizeBar( info.mpBar );
 
 
-                       // repaint
+            // repaint
 
 
-                       /* OLD STUFF:: bool isChoice = info.mpBar->IsKindOf( CLASSINFO( wxChoice ) );
+            /* OLD STUFF:: bool isChoice = info.mpBar->IsKindOf( CLASSINFO( wxChoice ) );
 
 
-                       //#ifdef __WINDOWS__
-                       //int result = ::SendMessage( (HWND)pWnd->m_hWnd, WM_NCPAINT, 0, 0 );
-                       //#endif
-                       */
+            //#ifdef __WINDOWS__
+            //int result = ::SendMessage( (HWND)pWnd->m_hWnd, WM_NCPAINT, 0, 0 );
+            //#endif
+            */
 
 
-                       // FIXME FIXME:: there's no other way to repaint non-client area of the wxWindow!!
-                       //                               so we do *excessive* "hide 'n show"
+            // FIXME FIXME:: there's no other way to repaint non-client area of the wxWindow!!
+            //                 so we do *excessive* "hide 'n show"
 
 
-                       pWnd->Show(FALSE);
-                       pWnd->Show(TRUE);
-                               
-                       pWnd->Refresh();
-               }
+            pWnd->Show(false);
+            pWnd->Show(true);
+                
+            pWnd->Refresh();
+        }
 
 
-               pNode = pNode->Next();
-       }
+        pNode = pNode->GetNext();
+    }
 
 
-       // release data prepared for GC alg.
+    // release data prepared for GC alg.
 
 
-       pNode = items.First();
+    pNode = items.GetFirst();
 
 
-       while( pNode )
-       {
-               cbRectInfo* pInfo = (cbRectInfo*)(pNode->Data());
+    while( pNode )
+    {
+        cbRectInfo* pInfo = (cbRectInfo*)(pNode->GetData());
 
 
-               delete pInfo;
+        delete pInfo;
 
 
-               pNode = pNode->Next();
-       }
+        pNode = pNode->GetNext();
+    }
 
 
-       mGC.Reset(); // reinit GC
+    mGC.Reset(); // reinit GC
 
 
-       // FIXME:: this is a dirty-workaround for messy client-area,
-       //         as a result of docking bar out of floated-container window
+    // FIXME:: this is a dirty-workaround for messy client-area,
+    //         as a result of docking bar out of floated-container window
 
 
-       if ( mpLayout->mClientWndRefreshPending )
-       {
-               mpLayout->PositionClientWindow();
-               mpLayout->GetFrameClient()->Refresh();
-       }
+    if ( mpLayout->mClientWndRefreshPending )
+    {
+        mpLayout->PositionClientWindow();
+        mpLayout->GetFrameClient()->Refresh();
+    }
 }
 
 }