Update TestDanglingEnds to O(n) speed

The elements don't care which they connect to, so don't search for
points on the page, just collect them all and then test them all

Adjusts f3dd5b73
This commit is contained in:
Seth Hillbrand 2023-08-30 14:21:58 -07:00
parent 0aaafc92fc
commit c2fd2f42eb
3 changed files with 37 additions and 26 deletions

View File

@ -55,7 +55,7 @@
* Flag to enable connectivity profiling
* @ingroup trace_env_vars
*/
static const wxChar ConnProfileMask[] = wxT( "CONN_PROFILE" );
static const wxChar DanglingProfileMask[] = wxT( "CONN_PROFILE" );
/*
* Flag to enable connectivity tracing
@ -637,19 +637,19 @@ void CONNECTION_GRAPH::Recalculate( const SCH_SHEET_LIST& aSheetList, bool aUnco
}
}
if( wxLog::IsAllowedTraceMask( ConnProfileMask ) )
if( wxLog::IsAllowedTraceMask( DanglingProfileMask ) )
update_items.Show();
PROF_TIMER build_graph( "buildConnectionGraph" );
buildConnectionGraph( aChangedItemHandler );
if( wxLog::IsAllowedTraceMask( ConnProfileMask ) )
if( wxLog::IsAllowedTraceMask( DanglingProfileMask ) )
build_graph.Show();
recalc_time.Stop();
if( wxLog::IsAllowedTraceMask( ConnProfileMask ) )
if( wxLog::IsAllowedTraceMask( DanglingProfileMask ) )
recalc_time.Show();
}
@ -1796,7 +1796,7 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
PROF_TIMER sub_graph( "buildItemSubGraphs" );
buildItemSubGraphs();
if( wxLog::IsAllowedTraceMask( ConnProfileMask ) )
if( wxLog::IsAllowedTraceMask( DanglingProfileMask ) )
sub_graph.Show();
@ -1816,7 +1816,7 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
PROF_TIMER proc_sub_graph( "ProcessSubGraphs" );
processSubGraphs();
if( wxLog::IsAllowedTraceMask( ConnProfileMask ) )
if( wxLog::IsAllowedTraceMask( DanglingProfileMask ) )
proc_sub_graph.Show();
// Absorbed subgraphs should no longer be considered

View File

@ -305,12 +305,6 @@ void SCH_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags )
schItem->ClearEditFlags();
}
if( frame )
{
frame->RecalculateConnections( this, NO_CLEANUP );
frame->TestDanglingEnds();
}
if( schematic )
{
if( bulkAddedItems.size() > 0 )
@ -326,7 +320,10 @@ void SCH_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags )
if( !( aCommitFlags & SKIP_UNDO ) )
{
if( frame )
{
frame->SaveCopyInUndoList( undoList, UNDO_REDO::UNSPECIFIED, false, dirtyConnectivity );
frame->RecalculateConnections( this, NO_CLEANUP );
}
}
m_toolMgr->PostEvent( { TC_MESSAGE, TA_MODEL_CHANGE, AS_GLOBAL } );
@ -528,7 +525,6 @@ void SCH_COMMIT::Revert()
if( frame )
{
frame->RecalculateConnections( nullptr, NO_CLEANUP );
frame->TestDanglingEnds();
}
clear();

View File

@ -62,6 +62,12 @@
#include "sch_bus_entry.h"
#include "sim/sim_model_ideal.h"
/*
* Flag to enable profiling of the TestDanglingEnds() function.
* @ingroup trace_env_vars
*/
static const wxChar DanglingProfileMask[] = wxT( "DANGLING_PROFILE" );
SCH_SCREEN::SCH_SCREEN( EDA_ITEM* aParent ) :
BASE_SCREEN( aParent, SCH_SCREEN_T ),
m_fileFormatVersionAtLoad( 0 ),
@ -1367,31 +1373,40 @@ void SCH_SCREEN::GetSheets( std::vector<SCH_ITEM*>* aItems ) const
void SCH_SCREEN::TestDanglingEnds( const SCH_SHEET_PATH* aPath,
std::function<void( SCH_ITEM* )>* aChangedHandler ) const
{
PROF_TIMER timer( __FUNCTION__ );
std::vector<DANGLING_END_ITEM> endPoints;
auto testDanglingEnds =
auto getends =
[&]( SCH_ITEM* item )
{
if( item->IsConnectable() )
item->GetEndPoints( endPoints );
};
auto update_state =
[&]( SCH_ITEM* item )
{
if( item->UpdateDanglingState( endPoints, aPath ) )
{
endPoints.clear();
for( SCH_ITEM* overlapping : Items().Overlapping( item->GetBoundingBox() ) )
overlapping->GetEndPoints( endPoints );
if( item->UpdateDanglingState( endPoints, aPath ) )
{
if( aChangedHandler )
(*aChangedHandler)( item );
}
if( aChangedHandler )
(*aChangedHandler)( item );
}
};
for( SCH_ITEM* item : Items() )
{
testDanglingEnds( item );
item->RunOnChildren( testDanglingEnds );
getends( item );
item->RunOnChildren( getends );
}
for( SCH_ITEM* item : Items() )
{
update_state( item );
item->RunOnChildren( update_state );
}
if( wxLog::IsAllowedTraceMask( DanglingProfileMask ) )
timer.Show();
}