pcbnew: Changing drawings from dlist to std::deque

This commit is contained in:
Seth Hillbrand 2019-05-30 06:33:59 -07:00
parent 3777c5270b
commit 961b22d603
12 changed files with 93 additions and 48 deletions

View File

@ -26,6 +26,8 @@
* @brief Implementation of EDA_ITEM base class for KiCad. * @brief Implementation of EDA_ITEM base class for KiCad.
*/ */
#include <deque>
#include <fctsys.h> #include <fctsys.h>
#include <trigo.h> #include <trigo.h>
#include <common.h> #include <common.h>
@ -127,21 +129,6 @@ EDA_ITEM* EDA_ITEM::Clone() const
} }
SEARCH_RESULT EDA_ITEM::IterateForward( EDA_ITEM* listStart,
INSPECTOR inspector,
void* testData,
const KICAD_T scanTypes[] )
{
for( EDA_ITEM* p = listStart; p; p = p->Pnext )
{
if( SEARCH_QUIT == p->Visit( inspector, testData, scanTypes ) )
return SEARCH_QUIT;
}
return SEARCH_CONTINUE;
}
// see base_struct.h // see base_struct.h
// many classes inherit this method, be careful: // many classes inherit this method, be careful:
SEARCH_RESULT EDA_ITEM::Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] ) SEARCH_RESULT EDA_ITEM::Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] )

View File

@ -27,6 +27,7 @@
* @brief General wrappers for kicad / wx structures and classes * @brief General wrappers for kicad / wx structures and classes
*/ */
%include <std_deque.i>
%include <std_vector.i> %include <std_vector.i>
%include <std_list.i> %include <std_list.i>
%include <std_basic_string.i> %include <std_basic_string.i>

View File

@ -32,6 +32,8 @@
#ifndef BASE_STRUCT_H_ #ifndef BASE_STRUCT_H_
#define BASE_STRUCT_H_ #define BASE_STRUCT_H_
#include <deque>
#include <core/typeinfo.h> #include <core/typeinfo.h>
#include "common.h" #include "common.h"
@ -366,6 +368,22 @@ public:
*/ */
virtual EDA_ITEM* Clone() const; // should not be inline, to save the ~ 6 bytes per call site. virtual EDA_ITEM* Clone() const; // should not be inline, to save the ~ 6 bytes per call site.
/**
* Function Visit
* may be re-implemented for each derived class in order to handle
* all the types given by its member data. Implementations should call
* inspector->Inspect() on types in scanTypes[], and may use
* IterateForward()
* to do so on lists of such data.
* @param inspector An INSPECTOR instance to use in the inspection.
* @param testData Arbitrary data used by the inspector.
* @param scanTypes Which KICAD_T types are of interest and the order
* is significant too, terminated by EOT.
* @return SEARCH_RESULT SEARCH_QUIT if the Iterator is to stop the scan,
* else SCAN_CONTINUE, and determined by the inspector.
*/
virtual SEARCH_RESULT Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] );
/** /**
* Function IterateForward * Function IterateForward
* walks through the object tree calling the inspector() on each object * walks through the object tree calling the inspector() on each object
@ -386,23 +404,37 @@ public:
static SEARCH_RESULT IterateForward( EDA_ITEM* listStart, static SEARCH_RESULT IterateForward( EDA_ITEM* listStart,
INSPECTOR inspector, INSPECTOR inspector,
void* testData, void* testData,
const KICAD_T scanTypes[] ); const KICAD_T scanTypes[] )
{
for( EDA_ITEM* p = listStart; p; p = p->Pnext )
{
if( SEARCH_QUIT == p->Visit( inspector, testData, scanTypes ) )
return SEARCH_QUIT;
}
return SEARCH_CONTINUE;
}
/** /**
* Function Visit * @copydoc SEARCH_RESULT IterateForward( EDA_ITEM*, INSPECTOR, void*, const KICAD_T )
* may be re-implemented for each derived class in order to handle *
* all the types given by its member data. Implementations should call * This changes first parameter to avoid the DList and use the main queue instead
* inspector->Inspect() on types in scanTypes[], and may use
* IterateForward()
* to do so on lists of such data.
* @param inspector An INSPECTOR instance to use in the inspection.
* @param testData Arbitrary data used by the inspector.
* @param scanTypes Which KICAD_T types are of interest and the order
* is significant too, terminated by EOT.
* @return SEARCH_RESULT SEARCH_QUIT if the Iterator is to stop the scan,
* else SCAN_CONTINUE, and determined by the inspector.
*/ */
virtual SEARCH_RESULT Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] ); template< class T >
static SEARCH_RESULT IterateForward( std::deque<T>& aList,
INSPECTOR inspector,
void* testData,
const KICAD_T scanTypes[] )
{
for( auto it : aList )
{
if( static_cast<EDA_ITEM*>( it )->Visit( inspector, testData, scanTypes ) == SEARCH_QUIT )
return SEARCH_QUIT;
}
return SEARCH_CONTINUE;
}
/** /**
* Function GetClass * Function GetClass

View File

@ -31,6 +31,7 @@
#define MACROS_H #define MACROS_H
#include <wx/wx.h> #include <wx/wx.h>
#include <deque>
#include <vector> #include <vector>
#include <map> #include <map>
#include <set> #include <set>
@ -149,12 +150,14 @@ template <typename T> inline const T& Clamp( const T& lower, const T& value, con
#ifdef SWIG #ifdef SWIG
/// Declare a std::vector and also the swig %template in unison /// Declare a std::vector and also the swig %template in unison
#define DECL_VEC_FOR_SWIG(TypeName, MemberType) namespace std { %template(TypeName) vector<MemberType>; } typedef std::vector<MemberType> TypeName; #define DECL_VEC_FOR_SWIG(TypeName, MemberType) namespace std { %template(TypeName) vector<MemberType>; } typedef std::vector<MemberType> TypeName;
#define DECL_DEQ_FOR_SWIG(TypeName, MemberType) namespace std { %template(TypeName) deque<MemberType>; } typedef std::deque<MemberType> TypeName;
#define DECL_MAP_FOR_SWIG(TypeName, KeyType, ValueType) namespace std { %template(TypeName) map<KeyType, ValueType>; } typedef std::map<KeyType, ValueType> TypeName; #define DECL_MAP_FOR_SWIG(TypeName, KeyType, ValueType) namespace std { %template(TypeName) map<KeyType, ValueType>; } typedef std::map<KeyType, ValueType> TypeName;
#define DECL_SPTR_FOR_SWIG(TypeName, MemberType) %shared_ptr(MemberType) namespace std { %template(TypeName) shared_ptr<MemberType>; } typedef std::shared_ptr<MemberType> TypeName; #define DECL_SPTR_FOR_SWIG(TypeName, MemberType) %shared_ptr(MemberType) namespace std { %template(TypeName) shared_ptr<MemberType>; } typedef std::shared_ptr<MemberType> TypeName;
#define DECL_SET_FOR_SWIG(TypeName, MemberType) namespace std { %template(TypeName) set<MemberType>; } typedef std::set<MemberType> TypeName; #define DECL_SET_FOR_SWIG(TypeName, MemberType) namespace std { %template(TypeName) set<MemberType>; } typedef std::set<MemberType> TypeName;
#else #else
/// Declare a std::vector but no swig %template /// Declare a std::vector but no swig %template
#define DECL_VEC_FOR_SWIG(TypeName, MemberType) typedef std::vector<MemberType> TypeName; #define DECL_VEC_FOR_SWIG(TypeName, MemberType) typedef std::vector<MemberType> TypeName;
#define DECL_DEQ_FOR_SWIG(TypeName, MemberType) typedef std::deque<MemberType> TypeName;
#define DECL_MAP_FOR_SWIG(TypeName, KeyType, ValueType) typedef std::map<KeyType, ValueType> TypeName; #define DECL_MAP_FOR_SWIG(TypeName, KeyType, ValueType) typedef std::map<KeyType, ValueType> TypeName;
#define DECL_SPTR_FOR_SWIG(TypeName, MemberType) typedef std::shared_ptr<MemberType> TypeName; #define DECL_SPTR_FOR_SWIG(TypeName, MemberType) typedef std::shared_ptr<MemberType> TypeName;
#define DECL_SET_FOR_SWIG(TypeName, MemberType) typedef std::set<MemberType> TypeName; #define DECL_SET_FOR_SWIG(TypeName, MemberType) typedef std::set<MemberType> TypeName;

View File

@ -102,7 +102,7 @@ void BOARD::ConvertBrdLayerToPolygonalContours( PCB_LAYER_ID aLayer, SHAPE_POLY_
} }
// convert graphic items on copper layers (texts) // convert graphic items on copper layers (texts)
for( BOARD_ITEM* item = m_Drawings; item; item = item->Next() ) for( auto item : m_drawings )
{ {
if( !item->IsOnLayer( aLayer ) ) if( !item->IsOnLayer( aLayer ) )
continue; continue;

View File

@ -913,9 +913,9 @@ void BOARD::Add( BOARD_ITEM* aBoardItem, ADD_MODE aMode )
case PCB_TEXT_T: case PCB_TEXT_T:
case PCB_TARGET_T: case PCB_TARGET_T:
if( aMode == ADD_APPEND ) if( aMode == ADD_APPEND )
m_Drawings.PushBack( aBoardItem ); m_drawings.push_back( aBoardItem );
else else
m_Drawings.PushFront( aBoardItem ); m_drawings.push_front( aBoardItem );
break; break;
@ -989,7 +989,10 @@ void BOARD::Remove( BOARD_ITEM* aBoardItem )
case PCB_LINE_T: case PCB_LINE_T:
case PCB_TEXT_T: case PCB_TEXT_T:
case PCB_TARGET_T: case PCB_TARGET_T:
m_Drawings.Remove( aBoardItem ); m_drawings.erase(
std::remove_if( m_drawings.begin(), m_drawings.end(),
[aBoardItem](BOARD_ITEM* aItem)
{ return aItem == aBoardItem;} ) );
break; break;
// other types may use linked list // other types may use linked list
@ -1101,7 +1104,7 @@ EDA_RECT BOARD::ComputeBoundingBox( bool aBoardEdgesOnly ) const
LSET visible = GetVisibleLayers(); LSET visible = GetVisibleLayers();
// Check segments, dimensions, texts, and fiducials // Check segments, dimensions, texts, and fiducials
for( BOARD_ITEM* item = m_Drawings; item; item = item->Next() ) for( auto item : m_drawings )
{ {
if( aBoardEdgesOnly && (item->Type() != PCB_LINE_T || item->GetLayer() != Edge_Cuts ) ) if( aBoardEdgesOnly && (item->Type() != PCB_LINE_T || item->GetLayer() != Edge_Cuts ) )
continue; continue;
@ -1263,7 +1266,7 @@ SEARCH_RESULT BOARD::Visit( INSPECTOR inspector, void* testData, const KICAD_T s
case PCB_TEXT_T: case PCB_TEXT_T:
case PCB_DIMENSION_T: case PCB_DIMENSION_T:
case PCB_TARGET_T: case PCB_TARGET_T:
result = IterateForward( m_Drawings, inspector, testData, p ); result = IterateForward<BOARD_ITEM*>( m_drawings, inspector, testData, p );
// skip over any types handled in the above call. // skip over any types handled in the above call.
for( ; ; ) for( ; ; )

View File

@ -161,6 +161,7 @@ protected:
DECL_VEC_FOR_SWIG(MARKERS, MARKER_PCB*) DECL_VEC_FOR_SWIG(MARKERS, MARKER_PCB*)
DECL_VEC_FOR_SWIG(ZONE_CONTAINERS, ZONE_CONTAINER*) DECL_VEC_FOR_SWIG(ZONE_CONTAINERS, ZONE_CONTAINER*)
DECL_VEC_FOR_SWIG(TRACKS, TRACK*) DECL_VEC_FOR_SWIG(TRACKS, TRACK*)
DECL_DEQ_FOR_SWIG(DRAWINGS, BOARD_ITEM*)
/** /**
@ -178,6 +179,9 @@ private:
/// MARKER_PCBs for clearance problems, owned by pointer. /// MARKER_PCBs for clearance problems, owned by pointer.
MARKERS m_markers; MARKERS m_markers;
/// BOARD_ITEMs for drawings on the board, owned by pointer.
DRAWINGS m_drawings;
/// edge zone descriptors, owned by pointer. /// edge zone descriptors, owned by pointer.
ZONE_CONTAINERS m_ZoneDescriptorList; ZONE_CONTAINERS m_ZoneDescriptorList;
@ -236,8 +240,8 @@ public:
const wxString &GetFileName() const { return m_fileName; } const wxString &GetFileName() const { return m_fileName; }
private: /// Flags used in ratsnest calculation and update.
DLIST<BOARD_ITEM> m_Drawings; // linked list of lines & texts int m_Status_Pcb;
public: public:
@ -246,13 +250,10 @@ public:
DLIST_ITERATOR_WRAPPER<TRACK> Tracks() { return DLIST_ITERATOR_WRAPPER<TRACK>(m_Track); } 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<MODULE> Modules() { return DLIST_ITERATOR_WRAPPER<MODULE>(m_Modules); }
DLIST_ITERATOR_WRAPPER<BOARD_ITEM> Drawings() { return DLIST_ITERATOR_WRAPPER<BOARD_ITEM>(m_Drawings); } DRAWINGS& Drawings() { return m_drawings; }
ZONE_CONTAINERS& Zones() { return m_ZoneDescriptorList; } ZONE_CONTAINERS& Zones() { return m_ZoneDescriptorList; }
const std::vector<BOARD_CONNECTED_ITEM*> AllConnectedItems(); const std::vector<BOARD_CONNECTED_ITEM*> AllConnectedItems();
// will be deprecated as soon as append board functionality is fixed
DLIST<BOARD_ITEM>& DrawingsList() { return m_Drawings; }
/// zone contour currently in progress /// zone contour currently in progress
ZONE_CONTAINER* m_CurrentZoneContour; ZONE_CONTAINER* m_CurrentZoneContour;
@ -264,7 +265,7 @@ public:
bool IsEmpty() const bool IsEmpty() const
{ {
return m_Drawings.GetCount() == 0 && m_Modules.GetCount() == 0 && m_Track.GetCount() == 0; return m_drawings.empty() && m_Modules.GetCount() == 0 && m_Track.GetCount() == 0;
} }
void Move( const wxPoint& aMoveVector ) override; void Move( const wxPoint& aMoveVector ) override;

View File

@ -601,7 +601,7 @@ void PCB_IO::formatGeneral( BOARD* aBoard, int aNestLevel ) const
m_out->Print( aNestLevel+1, "(thickness %s)\n", m_out->Print( aNestLevel+1, "(thickness %s)\n",
FormatInternalUnits( dsnSettings.GetBoardThickness() ).c_str() ); FormatInternalUnits( dsnSettings.GetBoardThickness() ).c_str() );
m_out->Print( aNestLevel+1, "(drawings %d)\n", aBoard->Drawings().Size() ); m_out->Print( aNestLevel+1, "(drawings %zu)\n", aBoard->Drawings().size() );
m_out->Print( aNestLevel+1, "(tracks %d)\n", aBoard->GetNumSegmTrack() ); m_out->Print( aNestLevel+1, "(tracks %d)\n", aBoard->GetNumSegmTrack() );
m_out->Print( aNestLevel+1, "(modules %d)\n", aBoard->m_Modules.GetCount() ); m_out->Print( aNestLevel+1, "(modules %d)\n", aBoard->m_Modules.GetCount() );
m_out->Print( aNestLevel+1, "(nets %d)\n", m_mapping->GetSize() ); m_out->Print( aNestLevel+1, "(nets %d)\n", m_mapping->GetSize() );
@ -727,7 +727,7 @@ void PCB_IO::format( BOARD* aBoard, int aNestLevel ) const
for( auto item : aBoard->Drawings() ) for( auto item : aBoard->Drawings() )
Format( item, aNestLevel ); Format( item, aNestLevel );
if( aBoard->Drawings().Size() ) if( aBoard->Drawings().size() )
m_out->Print( 0, "\n" ); m_out->Print( 0, "\n" );
// Do not save MARKER_PCBs, they can be regenerated easily. // Do not save MARKER_PCBs, they can be regenerated easily.

View File

@ -89,7 +89,7 @@ void BOARD::Print( PCB_BASE_FRAME* aFrame, wxDC* DC, const wxPoint& offset )
} }
// Draw the graphic items // Draw the graphic items
for( BOARD_ITEM* item = m_Drawings; item; item = item->Next() ) for( auto item : m_drawings )
{ {
if( item->IsMoving() ) if( item->IsMoving() )
continue; continue;

View File

@ -232,7 +232,7 @@ void PCB_EDIT_FRAME::RunActionPlugin( ACTION_PLUGIN* aActionPlugin )
} }
// Append drawings // Append drawings
for( BOARD_ITEM* item = currentPcb->m_Drawings; item != NULL; item = item->Next() ) for( auto item : currentPcb->Drawings() )
{ {
ITEM_PICKER picker( item, UR_CHANGED ); ITEM_PICKER picker( item, UR_CHANGED );
itemsList.PushItem( picker ); itemsList.PushItem( picker );
@ -354,7 +354,7 @@ void PCB_EDIT_FRAME::RunActionPlugin( ACTION_PLUGIN* aActionPlugin )
} }
} }
for( BOARD_ITEM* item = currentPcb->m_Drawings; item != NULL; item = item->Next() ) for( auto item : currentPcb->Drawings() )
{ {
if( !oldBuffer->ContainsItem( item ) ) if( !oldBuffer->ContainsItem( item ) )
{ {

View File

@ -777,6 +777,23 @@ static void moveNoFlagToVector( DLIST<T>& aList, std::vector<BOARD_ITEM*>& aTarg
} }
} }
// Helper function for PCBNEW_CONTROL::placeBoardItems()
template<typename T>
static void moveNoFlagToVector( std::deque<T>& aList, std::vector<BOARD_ITEM*>& aTarget, bool aIsNew )
{
std::copy_if( aList.begin(), aList.end(), std::back_inserter( aTarget ),
[](T aItem){
bool retval = aItem->GetFlags() & FLAG0;
aItem->ClearFlags( FLAG0 );
return retval;
} );
if( aIsNew )
aList.clear();
}
static void moveNoFlagToVector( ZONE_CONTAINERS& aList, std::vector<BOARD_ITEM*>& aTarget, bool aIsNew ) static void moveNoFlagToVector( ZONE_CONTAINERS& aList, std::vector<BOARD_ITEM*>& aTarget, bool aIsNew )
{ {
if( aList.size() == 0 ) if( aList.size() == 0 )
@ -823,7 +840,7 @@ int PCBNEW_CONTROL::placeBoardItems( BOARD* aBoard )
moveNoFlagToVector( aBoard->m_Track, items, isNew ); moveNoFlagToVector( aBoard->m_Track, items, isNew );
moveNoFlagToVector( aBoard->m_Modules, items, isNew ); moveNoFlagToVector( aBoard->m_Modules, items, isNew );
moveNoFlagToVector( aBoard->DrawingsList(), items, isNew ); moveNoFlagToVector( aBoard->Drawings(), items, isNew );
moveNoFlagToVector( aBoard->Zones(), items, isNew ); moveNoFlagToVector( aBoard->Zones(), items, isNew );
return placeBoardItems( items, isNew ); return placeBoardItems( items, isNew );

View File

@ -64,6 +64,7 @@ target_link_libraries( qa_pcbnew
legacy_gal legacy_gal
gal gal
common common
gal
qa_utils qa_utils
lib_dxf lib_dxf
idf3 idf3