add support for board listeners

This commit is contained in:
Oleg Endo 2020-04-13 04:29:16 +09:00 committed by Jon Evans
parent e3aec20f82
commit 7bf8a744f1
7 changed files with 150 additions and 10 deletions

View File

@ -201,9 +201,17 @@ public:
{
// Remove the first character ':' and all whitespace
remainingName = remainingName.Mid( 1 ).Trim().Trim( false );
BOARD* board = m_netinfoList->GetParent();
NETINFO_ITEM *newnet = new NETINFO_ITEM( m_board, remainingName, 0 );
// add the new netinfo through the board's function so that
// board listeners get notified and things stay in sync.
if( board != nullptr )
board->Add( newnet );
else
m_netinfoList->AppendNet( newnet );
rebuildList();
if( newnet->GetNet() > 0 )
@ -215,6 +223,11 @@ public:
{
// This indicates that the NETINFO_ITEM was not successfully appended
// to the list for unknown reasons
if( board != nullptr )
board->Remove( newnet );
else
m_netinfoList->RemoveNet( newnet );
delete newnet;
}
}

View File

@ -262,6 +262,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage, bool aCreateUndoEntry, bool a
connectivity->Update( boardItem );
view->Update( boardItem );
board->OnItemChanged( boardItem );
// if no undo entry is needed, the copy would create a memory leak
if( !aCreateUndoEntry )
@ -395,6 +396,7 @@ void BOARD_COMMIT::Revert()
view->Add( item );
connectivity->Add( item );
board->OnItemChanged( item );
delete copy;
break;
}

View File

@ -601,6 +601,8 @@ void BOARD::Add( BOARD_ITEM* aBoardItem, ADD_MODE aMode )
aBoardItem->SetParent( this );
aBoardItem->ClearEditFlags();
m_connectivity->Add( aBoardItem );
InvokeListeners( &BOARD_LISTENER::OnBoardItemAdded, *this, aBoardItem );
}
@ -679,6 +681,8 @@ void BOARD::Remove( BOARD_ITEM* aBoardItem )
}
m_connectivity->Remove( aBoardItem );
InvokeListeners( &BOARD_LISTENER::OnBoardItemRemoved, *this, aBoardItem );
}
@ -1429,6 +1433,9 @@ void BOARD::GetSortedPadListByXthenYCoord( std::vector<D_PAD*>& aVector, int aNe
void BOARD::PadDelete( D_PAD* aPad )
{
GetConnectivity()->Remove( aPad );
InvokeListeners( &BOARD_LISTENER::OnBoardItemRemoved, *this, aPad );
aPad->DeleteStructure();
}
@ -1799,3 +1806,54 @@ void BOARD::SanitizeNetcodes()
item->SetNetCode( NETINFO_LIST::ORPHANED );
}
}
void BOARD::AddListener( BOARD_LISTENER* aListener )
{
if( std::find( m_listeners.begin(), m_listeners.end(), aListener ) == m_listeners.end() )
m_listeners.push_back( aListener );
}
void BOARD::RemoveListener( BOARD_LISTENER* aListener )
{
auto i = std::find( m_listeners.begin(), m_listeners.end(), aListener );
if( i != m_listeners.end() )
{
std::iter_swap( i, m_listeners.end() - 1 );
m_listeners.pop_back();
}
}
void BOARD::OnItemChanged( BOARD_ITEM* aItem )
{
InvokeListeners( &BOARD_LISTENER::OnBoardItemChanged, *this, aItem );
}
void BOARD::ResetNetHighLight()
{
m_highLight.Clear();
m_highLightPrevious.Clear();
InvokeListeners( &BOARD_LISTENER::OnBoardHighlightNetChanged, *this );
}
void BOARD::SetHighLightNet( int aNetCode )
{
if( m_highLight.m_netCode != aNetCode )
{
m_highLight.m_netCode = aNetCode;
InvokeListeners( &BOARD_LISTENER::OnBoardHighlightNetChanged, *this );
}
}
void BOARD::HighLightON( bool aValue )
{
if( m_highLight.m_highLightOn != aValue )
{
m_highLight.m_highLightOn = aValue;
InvokeListeners( &BOARD_LISTENER::OnBoardHighlightNetChanged, *this );
}
}

View File

@ -151,6 +151,25 @@ protected:
}
};
/**
* BOARD_LISTENER
* provides an interface to hook into board modifications and get callbacks
* on certain modifications that are made to the board. This allows updating
* auxiliary views other than the primary board editor view.
*/
class BOARD;
class BOARD_LISTENER
{
public:
virtual ~BOARD_LISTENER() { }
virtual void OnBoardItemAdded( BOARD& aBoard, BOARD_ITEM* aBoardItem ) { }
virtual void OnBoardItemRemoved( BOARD& aBoard, BOARD_ITEM* aBoardItem ) { }
virtual void OnBoardNetSettingsChanged( BOARD& aBoard ) { }
virtual void OnBoardItemChanged( BOARD& aBoard, BOARD_ITEM* aBoardItem ) { }
virtual void OnBoardHighlightNetChanged( BOARD& aBoard ) { }
};
DECL_VEC_FOR_SWIG( MARKERS, MARKER_PCB* )
DECL_VEC_FOR_SWIG( ZONE_CONTAINERS, ZONE_CONTAINER* )
@ -202,6 +221,7 @@ private:
NETINFO_LIST m_NetInfo; // net info list (name, design constraints ..
PROJECT* m_project; // project this board is a part of (if any)
std::vector<BOARD_LISTENER*> m_listeners;
// The default copy constructor & operator= are inadequate,
// either write one or do not use it at all
@ -209,6 +229,13 @@ private:
BOARD& operator=( const BOARD& aOther ) = delete;
template <typename Func, typename... Args>
void InvokeListeners( Func&& aFunc, Args&&... args )
{
for( auto&& l : m_listeners )
( l->*aFunc )( std::forward<Args>( args )... );
}
public:
static inline bool ClassOf( const EDA_ITEM* aItem )
{
@ -347,18 +374,19 @@ public:
* Function ResetNetHighLight
* Reset all high light data to the init state
*/
void ResetNetHighLight()
{
m_highLight.Clear();
m_highLightPrevious.Clear();
}
void ResetNetHighLight();
/**
* Function GetHighLightNetCode
* @return netcode of net to highlight (-1 when no net selected)
*/
int GetHighLightNetCode() const { return m_highLight.m_netCode; }
void SetHighLightNet( int aNetCode) { m_highLight.m_netCode = aNetCode; }
/**
* Function SetHighLightNet
* Select the netcode to be highlighted.
*/
void SetHighLightNet( int aNetCode );
/**
* Function IsHighLightNetON
@ -368,11 +396,19 @@ public:
/**
* Function HighLightON
* Enable highlight.
* Enable net highlight.
* if m_highLight_NetCode >= 0, this net will be highlighted
*/
void HighLightON() { m_highLight.m_highLightOn = true; }
void HighLightOFF() { m_highLight.m_highLightOn = false; }
void HighLightON( bool aValue = true );
/**
* Function HighLightOFF
* Disable net highlight.
*/
void HighLightOFF()
{
HighLightON( false );
}
/**
* Function GetCopperLayerCount
@ -1119,6 +1155,28 @@ public:
void MapNets( const BOARD* aDestBoard );
void SanitizeNetcodes();
/**
* Add a listener to the board to receive calls whenever something on the
* board has been modified. The board does not take ownership of the
* listener object. Make sure to call RemoveListener before deleing the
* listener object. The order of listener invocations is not guaranteed.
* If the specified listener object has been added before, it will not be
* added again.
*/
void AddListener( BOARD_LISTENER* aListener );
/**
* Remove the specified listener. If it has not been added before, it
* will do nothing.
*/
void RemoveListener( BOARD_LISTENER* aListener );
/**
* Notify the board and its listeners that an item on the board has
* been modified in some way.
*/
void OnItemChanged( BOARD_ITEM* aItem );
};
#endif // CLASS_BOARD_H_

View File

@ -299,6 +299,8 @@ void DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::processItem( PICKED_ITEMS_LIST* aUndoLi
if( m_parent->SetTrackSegmentWidth( aItem, aUndoList, true ) == TRACK_ACTION_DRC_ERROR )
m_failedDRC = true;
}
m_brd->OnItemChanged( aItem );
}

View File

@ -225,6 +225,8 @@ void BOARD::SynchronizeNetsAndNetClasses()
m_designSettings.SetCustomDiffPairWidth( defaultNetClass->GetDiffPairWidth() );
m_designSettings.SetCustomDiffPairGap( defaultNetClass->GetDiffPairGap() );
m_designSettings.SetCustomDiffPairViaGap( defaultNetClass->GetDiffPairViaGap() );
InvokeListeners( &BOARD_LISTENER::OnBoardNetSettingsChanged, *this );
}

View File

@ -475,6 +475,7 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool
view->Add( eda_item );
connectivity->Add( item );
item->GetBoard()->OnItemChanged( item );
}
break;
@ -496,6 +497,7 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool
item->Move( aRedoCommand ? aList->m_TransformPoint : -aList->m_TransformPoint );
view->Update( item, KIGFX::GEOMETRY );
connectivity->Update( item );
item->GetBoard()->OnItemChanged( item );
}
break;
@ -506,6 +508,7 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool
aRedoCommand ? m_rotationAngle : -m_rotationAngle );
view->Update( item, KIGFX::GEOMETRY );
connectivity->Update( item );
item->GetBoard()->OnItemChanged( item );
}
break;
@ -516,6 +519,7 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool
aRedoCommand ? -m_rotationAngle : m_rotationAngle );
view->Update( item, KIGFX::GEOMETRY );
connectivity->Update( item );
item->GetBoard()->OnItemChanged( item );
}
break;
@ -525,6 +529,7 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool
item->Flip( aList->m_TransformPoint, m_Settings->m_FlipLeftRight );
view->Update( item, KIGFX::LAYERS );
connectivity->Update( item );
item->GetBoard()->OnItemChanged( item );
}
break;