Hide DLISTs behind iterators, first step towards refactoring the storage model

This commit is contained in:
Tomasz Włostowski 2016-09-27 20:04:30 +02:00
parent 4bdac4de70
commit 08314082db
19 changed files with 100 additions and 25 deletions

66
include/core/iterators.h Normal file
View File

@ -0,0 +1,66 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 CERN
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __ITERATORS_H
#define __ITERATORS_H
#include <dlist.h>
#include <iterator>
template<class T>
class DLIST_ITERATOR: public std::iterator<std::bidirectional_iterator_tag, T>
{
private:
T m_obj;
using reference = typename DLIST_ITERATOR<T>::reference ;
public:
explicit DLIST_ITERATOR<T>( T obj ) : m_obj(obj) {}
DLIST_ITERATOR<T>& operator++() { m_obj = m_obj->Next(); return *this; }
DLIST_ITERATOR<T>& operator--() { m_obj = m_obj->Prev(); return *this; }
bool operator==(DLIST_ITERATOR<T> other) const {return m_obj == other.m_obj;}
bool operator!=(DLIST_ITERATOR<T> other) const {return !(*this == other);}
reference operator*() {return m_obj;}
};
// helper object, used to convert a DLIST<T> to an iterator
template<class T> class DLIST_ITERATOR_WRAPPER
{
public:
explicit DLIST_ITERATOR_WRAPPER<T> ( DLIST<T>& list ) : m_list(list) {};
DLIST_ITERATOR<T*> begin() { return DLIST_ITERATOR<T*> ( m_list.GetFirst()); }
DLIST_ITERATOR<T*> end() { return DLIST_ITERATOR<T*> ( m_list.GetLast()); }
unsigned int Size() const {
return m_list.GetCount();
}
private:
DLIST<T>& m_list;
};
#endif

View File

@ -58,7 +58,7 @@ bool PCB_EDIT_FRAME::AppendBoardFile( const wxString& aFullFileName, int aCtl )
// Other items are append to the item list, so keep trace to the
// last existing item is enough
MODULE* module = GetBoard()->m_Modules.GetLast();
BOARD_ITEM* drawing = GetBoard()->m_Drawings.GetLast();
BOARD_ITEM* drawing = GetBoard()->DrawingsList().GetLast();
int zonescount = GetBoard()->GetAreaCount();
// Keep also the count of copper layers, because we can happen boards
@ -152,7 +152,7 @@ bool PCB_EDIT_FRAME::AppendBoardFile( const wxString& aFullFileName, int aCtl )
if( drawing )
drawing = drawing->Next();
else
drawing = GetBoard()->m_Drawings;
drawing = GetBoard()->DrawingsList();
for( ; drawing; drawing = drawing->Next() )
{

View File

@ -501,9 +501,7 @@ int genPlacementRoutingMatrix( BOARD* aBrd, EDA_MSG_PANEL* messagePanel )
TmpSegm.SetNetCode( -1 );
TmpSegm.SetWidth( RoutingMatrix.m_GridRouting / 2 );
EDA_ITEM* PtStruct = aBrd->m_Drawings;
for( ; PtStruct != NULL; PtStruct = PtStruct->Next() )
for( auto PtStruct : aBrd->Drawings() )
{
DRAWSEGMENT* DrawSegm;

View File

@ -251,7 +251,7 @@ void PlaceCells( BOARD* aPcb, int net_code, int flag )
}
// Place board outlines and texts on copper layers:
for( BOARD_ITEM* item = aPcb->m_Drawings; item; item = item->Next() )
for( auto item : aPcb->Drawings() )
{
switch( item->Type() )
{

View File

@ -357,7 +357,7 @@ void PCB_EDIT_FRAME::Block_SelectItems()
if( !blockOpts.includeBoardOutlineLayer )
layerMask.set( Edge_Cuts, false );
for( BOARD_ITEM* PtStruct = m_Pcb->m_Drawings; PtStruct != NULL; PtStruct = PtStruct->Next() )
for( auto PtStruct : m_Pcb->Drawings() )
{
if( !m_Pcb->IsLayerVisible( PtStruct->GetLayer() ) && ! blockOpts.includeItemsOnInvisibleLayers)
continue;

View File

@ -32,6 +32,7 @@
#include <dlist.h>
#include <core/iterators.h>
#include <common.h> // PAGE_INFO
#include <layers_id_colors_and_visibility.h>
@ -239,11 +240,23 @@ public:
/// Flags used in ratsnest calculation and update.
int m_Status_Pcb;
private:
DLIST<BOARD_ITEM> m_Drawings; // linked list of lines & texts
public:
DLIST<MODULE> m_Modules; // linked list of MODULEs
DLIST<TRACK> m_Track; // linked list of TRACKs and VIAs
DLIST<SEGZONE> m_Zone; // linked list of SEGZONEs
DLIST_ITERATOR_WRAPPER<TRACK> Tracks() { return DLIST_ITERATOR_WRAPPER<TRACK>(m_Track); }
DLIST_ITERATOR_WRAPPER<MODULE> Modules() { return DLIST_ITERATOR_WRAPPER<MODULE>(m_Modules); }
DLIST_ITERATOR_WRAPPER<BOARD_ITEM> Drawings() { return DLIST_ITERATOR_WRAPPER<BOARD_ITEM>(m_Drawings); }
// will be deprecated as soon as append board functionality is fixed
DLIST<BOARD_ITEM>& DrawingsList() { return m_Drawings; }
/// Ratsnest list for the BOARD
std::vector<RATSNEST_ITEM> m_FullRatsnest;

View File

@ -677,14 +677,13 @@ void DRC::testKeepoutAreas()
}
}
void DRC::testTexts()
{
std::vector<wxPoint> textShape; // a buffer to store the text shape (set of segments)
std::vector<D_PAD*> padList = m_pcb->GetPads();
// Test text areas for vias, tracks and pads inside text areas
for( BOARD_ITEM* item = m_pcb->m_Drawings; item; item = item->Next() )
for( auto item : m_pcb->Drawings() )
{
// Drc test only items on copper layers
if( ! IsCopperLayer( item->GetLayer() ) )

View File

@ -164,7 +164,7 @@ void PCB_EDIT_FRAME::Delete_Drawings_All_Layer( PCB_LAYER_ID aLayer )
ITEM_PICKER picker( NULL, UR_DELETED );
BOARD_ITEM* PtNext;
for( BOARD_ITEM* item = GetBoard()->m_Drawings; item; item = PtNext )
for( auto item : GetBoard()->Drawings() )
{
PtNext = item->Next();

View File

@ -1029,8 +1029,7 @@ static void CreateBoardSection( FILE* aFile, BOARD* aPcb )
fputs( "$BOARD\n", aFile );
// Extract the board edges
for( EDA_ITEM* drawing = aPcb->m_Drawings; drawing != 0;
drawing = drawing->Next() )
for( auto drawing : aPcb->Drawings() )
{
if( drawing->Type() == PCB_LINE_T )
{

View File

@ -76,7 +76,7 @@ static void idf_export_outline( BOARD* aPcb, IDF3_BOARD& aIDFBoard )
aIDFBoard.GetUserOffset( offX, offY );
// Retrieve segments and arcs from the board
for( BOARD_ITEM* item = aPcb->m_Drawings; item; item = item->Next() )
for( auto item : aPcb->Drawings() )
{
if( item->Type() != PCB_LINE_T || item->GetLayer() != Edge_Cuts )
continue;

View File

@ -771,7 +771,7 @@ static void export_vrml_pcbtext( MODEL_VRML& aModel, TEXTE_PCB* text )
static void export_vrml_drawings( MODEL_VRML& aModel, BOARD* pcb )
{
// draw graphic items
for( BOARD_ITEM* drawing = pcb->m_Drawings; drawing != 0; drawing = drawing->Next() )
for( auto drawing : pcb->Drawings() )
{
PCB_LAYER_ID layer = drawing->GetLayer();

View File

@ -176,7 +176,7 @@ bool GENDRILL_WRITER_BASE::genDrillMapFile( const wxString& aFullFileName,
BRDITEMS_PLOTTER itemplotter( plotter, m_pcb, plot_opts );
itemplotter.SetLayerSet( Edge_Cuts );
for( EDA_ITEM* PtStruct = m_pcb->m_Drawings; PtStruct != NULL; PtStruct = PtStruct->Next() )
for( auto PtStruct : m_pcb->Drawings() )
{
switch( PtStruct->Type() )
{

View File

@ -542,7 +542,7 @@ void PCB_IO::format( BOARD* aBoard, int aNestLevel ) const
m_out->Print( aNestLevel+1, "(thickness %s)\n",
FMTIU( dsnSettings.GetBoardThickness() ).c_str() );
m_out->Print( aNestLevel+1, "(drawings %d)\n", aBoard->m_Drawings.GetCount() );
m_out->Print( aNestLevel+1, "(drawings %d)\n", aBoard->Drawings().Size() );
m_out->Print( aNestLevel+1, "(tracks %d)\n", aBoard->GetNumSegmTrack() );
m_out->Print( aNestLevel+1, "(zones %d)\n", aBoard->GetNumSegmZone() );
m_out->Print( aNestLevel+1, "(modules %d)\n", aBoard->m_Modules.GetCount() );
@ -756,10 +756,10 @@ void PCB_IO::format( BOARD* aBoard, int aNestLevel ) const
}
// Save the graphical items on the board (not owned by a module)
for( BOARD_ITEM* item = aBoard->m_Drawings; item; item = item->Next() )
for( auto item : aBoard->Drawings() )
Format( item, aNestLevel );
if( aBoard->m_Drawings.GetCount() )
if( aBoard->Drawings().Size() )
m_out->Print( 0, "\n" );
// Do not save MARKER_PCBs, they can be regenerated easily.

View File

@ -266,7 +266,7 @@ bool BRDITEMS_PLOTTER::PlotAllTextsModule( MODULE* aModule )
// plot items like text and graphics, but not tracks and module
void BRDITEMS_PLOTTER::PlotBoardGraphicItems()
{
for( BOARD_ITEM* item = m_board->m_Drawings; item; item = item->Next() )
for( auto item : m_board->Drawings() )
{
switch( item->Type() )
{

View File

@ -194,7 +194,7 @@ void PCB_EDIT_FRAME::PrintPage( wxDC* aDC,
m_canvas->SetPrintMirrored( aPrintMirrorMode );
for( BOARD_ITEM* item = Pcb->m_Drawings; item; item = item->Next() )
for( auto item : Pcb->Drawings() )
{
switch( item->Type() )
{

View File

@ -412,7 +412,7 @@ void PCB_EDIT_FRAME::Swap_Layers( wxCommandEvent& event )
}
// Change other segments.
for( EDA_ITEM* item = GetBoard()->m_Drawings; item; item = item->Next() )
for( auto item : GetBoard()->Drawings() )
{
if( item->Type() == PCB_LINE_T )
{

View File

@ -804,7 +804,7 @@ int PCBNEW_CONTROL::AppendBoard( const TOOL_EVENT& aEvent )
// Other items are appended to the item list, so keep trace to the last existing item is enough
MODULE* module = board->m_Modules.GetLast();
BOARD_ITEM* drawing = board->m_Drawings.GetLast();
BOARD_ITEM* drawing = board->DrawingsList().GetLast();
int zonescount = board->GetAreaCount();
// Keep also the count of copper layers, to adjust if necessary
@ -868,7 +868,7 @@ int PCBNEW_CONTROL::AppendBoard( const TOOL_EVENT& aEvent )
selection.Add( module );
}
drawing = drawing ? drawing->Next() : board->m_Drawings;
drawing = drawing ? drawing->Next() : board->DrawingsList();
for( ; drawing; drawing = drawing->Next() )
{

View File

@ -142,7 +142,7 @@ static bool TestForExistingItem( BOARD* aPcb, BOARD_ITEM* aItem )
itemsList.push_back( item );
// Append drawings
for( item = aPcb->m_Drawings; item != NULL; item = item->Next() )
for( auto item : aPcb->Drawings() )
itemsList.push_back( item );
// Append zones outlines

View File

@ -269,7 +269,7 @@ void ZONE_CONTAINER::buildFeatureHoleList( BOARD* aPcb, SHAPE_POLY_SET& aFeature
}
// Add graphic items (copper texts) and board edges
for( BOARD_ITEM* item = aPcb->m_Drawings; item; item = item->Next() )
for( auto item : aPcb->Drawings() )
{
if( item->GetLayer() != GetLayer() && item->GetLayer() != Edge_Cuts )
continue;