KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_label_bus_connectivity.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.TXT for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 3
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
29
31
32#include <connection_graph.h>
33#include <sch_commit.h>
34#include <schematic.h>
35#include <sch_label.h>
36#include <sch_line.h>
37#include <sch_screen.h>
38#include <sch_sheet.h>
39#include <sch_sheet_pin.h>
41#include <tool/tool_manager.h>
42
43
44BOOST_AUTO_TEST_SUITE( LabelBusConnectivity )
45
46
48{
50 m_mgr()
51 {
52 m_mgr.LoadProject( "" );
53 m_schematic = std::make_unique<SCHEMATIC>( &m_mgr.Prj() );
54 m_schematic->Reset();
55 SCH_SHEET* defaultSheet = m_schematic->GetTopLevelSheet( 0 );
56
57 m_screen = new SCH_SCREEN( m_schematic.get() );
58 m_sheet = new SCH_SHEET( m_schematic.get() );
59 m_sheet->SetScreen( m_screen );
60 m_schematic->AddTopLevelSheet( m_sheet );
61 m_schematic->RemoveTopLevelSheet( defaultSheet );
62 delete defaultSheet;
63 }
64
66 std::unique_ptr<SCHEMATIC> m_schematic;
69};
70
71
81{
82 // Create a bus wire
83 SCH_LINE* busWire = new SCH_LINE( VECTOR2I( 0, 0 ), LAYER_BUS );
84 busWire->SetEndPoint( VECTOR2I( 5000000, 0 ) );
85 m_screen->Append( busWire );
86
87 // Create a label with a non-bus name, positioned on the bus wire
88 SCH_LABEL* label = new SCH_LABEL( VECTOR2I( 2500000, 0 ), wxT( "test" ) );
89 m_screen->Append( label );
90
91 // Build initial connectivity
92 SCH_SHEET_LIST sheets = m_schematic->BuildSheetListSortedByPageNumbers();
93 m_schematic->ConnectionGraph()->Recalculate( sheets, true );
94
95 SCH_SHEET_PATH path = sheets[0];
96
97 // Verify initial state: bus wire should have BUS connection type but no members
98 // (because "test" is not a bus name)
99 SCH_CONNECTION* busConn = busWire->Connection( &path );
100 BOOST_REQUIRE( busConn != nullptr );
101 BOOST_CHECK( busConn->IsBus() );
102 BOOST_CHECK( busConn->Members().empty() );
103
104 TOOL_MANAGER manager;
105 manager.SetEnvironment( m_schematic.get(), nullptr, nullptr, nullptr, nullptr );
106 SCH_COMMIT commit( &manager );
107 commit.Modify( label, m_screen );
108 label->SetText( wxT( "test[0..7]" ) );
109 commit.Push( "Change label to a bus", SKIP_UNDO );
110
111 // Verify: bus wire should now have members from the bus label
112 busConn = busWire->Connection( &path );
113 BOOST_REQUIRE( busConn != nullptr );
114 BOOST_CHECK( busConn->IsBus() );
115 BOOST_CHECK_MESSAGE( !busConn->Members().empty(),
116 "Bus wire should have members after label changed to bus name" );
117
118 // Verify the correct number of members (test[0..7] = 8 members)
119 if( !busConn->Members().empty() )
120 {
121 BOOST_CHECK_EQUAL( busConn->Members().size(), 8 );
122 }
123}
124
125
131{
132 // Create a bus wire
133 SCH_LINE* busWire = new SCH_LINE( VECTOR2I( 0, 0 ), LAYER_BUS );
134 busWire->SetEndPoint( VECTOR2I( 5000000, 0 ) );
135 m_screen->Append( busWire );
136
137 // Create a label with a bus name, positioned on the bus wire
138 SCH_LABEL* label = new SCH_LABEL( VECTOR2I( 2500000, 0 ), wxT( "DATA[0..3]" ) );
139 m_screen->Append( label );
140
141 // Build connectivity
142 SCH_SHEET_LIST sheets = m_schematic->BuildSheetListSortedByPageNumbers();
143 m_schematic->ConnectionGraph()->Recalculate( sheets, true );
144
145 SCH_SHEET_PATH path = sheets[0];
146
147 // Verify: bus wire should have members from the bus label
148 SCH_CONNECTION* busConn = busWire->Connection( &path );
149 BOOST_REQUIRE( busConn != nullptr );
150 BOOST_CHECK( busConn->IsBus() );
151 BOOST_CHECK_MESSAGE( !busConn->Members().empty(),
152 "Bus wire should have members from bus label" );
153
154 // Verify the correct number of members (DATA[0..3] = 4 members)
155 if( !busConn->Members().empty() )
156 {
157 BOOST_CHECK_EQUAL( busConn->Members().size(), 4 );
158 }
159}
160
161
168BOOST_FIXTURE_TEST_CASE( SheetPinBusConnectionSurvivesMove, LABEL_BUS_CONNECTIVITY_FIXTURE )
169{
170 const wxString busName( wxT( "bus{A B}" ) );
171 const int sheetLeft = 10000000;
172
173 SCH_SCREEN* childScreen = new SCH_SCREEN( m_schematic.get() );
174 SCH_SHEET* childSheet = new SCH_SHEET( m_schematic.get(), VECTOR2I( sheetLeft, 0 ),
175 VECTOR2I( 20000000, 20000000 ) );
176
177 childScreen->SetFileName( wxT( "child.kicad_sch" ) );
178 childSheet->SetScreen( childScreen );
179 childSheet->SetName( wxT( "child" ) );
180 childSheet->SetFileName( wxT( "child.kicad_sch" ) );
181 m_screen->Append( childSheet );
182
183 childScreen->Append( new SCH_HIERLABEL( VECTOR2I( 0, 0 ), busName ) );
184
185 // The pin rides the sheet's left edge, so its x has to track the sheet origin
186 SCH_SHEET_PIN* pin = new SCH_SHEET_PIN( childSheet, VECTOR2I( sheetLeft, 5000000 ), busName );
187 childSheet->AddPin( pin );
188
189 SCH_LINE* busWire = new SCH_LINE( VECTOR2I( 5000000, 5000000 ), LAYER_BUS );
190 busWire->SetEndPoint( pin->GetTextPos() );
191 m_screen->Append( busWire );
192
193 m_schematic->RefreshHierarchy();
194
195 SCH_SHEET_LIST sheets = m_schematic->Hierarchy();
196 m_schematic->ConnectionGraph()->Recalculate( sheets, true );
197
198 SCH_SHEET_PATH rootPath = sheets[0];
199 SCH_CONNECTION* pinConn = pin->Connection( &rootPath );
200
201 BOOST_REQUIRE_MESSAGE( pinConn != nullptr, "Sheet pin has no connection before the move" );
202 BOOST_REQUIRE_MESSAGE( pinConn->IsBus(), "Sheet pin is not a bus before the move" );
203
204 // Simulate dragging the pin along the sheet edge with its bus wire attached
205 const VECTOR2I newPos( sheetLeft, 8000000 );
206
207 pin->SetPosition( newPos );
208 busWire->SetEndPoint( pin->GetTextPos() );
209 pin->SetConnectivityDirty( true );
210 busWire->SetConnectivityDirty( true );
211
212 // A schematic this small is a minor graph, so SCHEMATIC::RecalculateConnections() rebuilds
213 // unconditionally after the move
214 BOOST_REQUIRE( m_schematic->ConnectionGraph()->IsMinor() );
215 m_schematic->ConnectionGraph()->Recalculate( sheets, true );
216
217 // SCH_PAINTER ignores the resolved connection while this flag is set, which is what drops
218 // the bus colour
219 BOOST_CHECK_MESSAGE( !pin->IsConnectivityDirty(),
220 "Sheet pin connectivity still dirty after recalculation" );
221
222 pinConn = pin->Connection( &rootPath );
223
224 BOOST_REQUIRE_MESSAGE( pinConn != nullptr, "Sheet pin lost its connection after the move" );
225 BOOST_CHECK_MESSAGE( pinConn->IsBus(), "Sheet pin lost its bus connection after the move" );
226}
227
228
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
Definition commit.h:102
virtual void SetText(const wxString &aText)
Definition eda_text.cpp:231
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Execute the changes.
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
bool IsBus() const
const std::vector< std::shared_ptr< SCH_CONNECTION > > & Members() const
void SetConnectivityDirty(bool aDirty=true)
Definition sch_item.h:600
SCH_CONNECTION * Connection(const SCH_SHEET_PATH *aSheet=nullptr) const
Retrieve the connection associated with this object in the given sheet.
Definition sch_item.cpp:503
Segment description base class to describe items which have 2 end points (track, wire,...
Definition sch_line.h:39
void SetEndPoint(const VECTOR2I &aPosition)
Definition sch_line.h:146
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition sch_sheet.h:48
void SetFileName(const wxString &aFilename)
Definition sch_sheet.h:390
void AddPin(SCH_SHEET_PIN *aSheetPin)
Add aSheetPin to the sheet.
void SetName(const wxString &aName)
Definition sch_sheet.h:143
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
Master controller class:
void SetEnvironment(EDA_ITEM *aModel, KIGFX::VIEW *aView, KIGFX::VIEW_CONTROLS *aViewControls, APP_SETTINGS_BASE *aSettings, TOOLS_HOLDER *aFrame)
Set the work environment (model, view, view controls and the parent window).
@ LAYER_BUS
Definition layer_ids.h:475
#define SKIP_UNDO
Definition sch_commit.h:38
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
std::string path
KIBIS_PIN * pin
BOOST_FIXTURE_TEST_CASE(LabelNetToBusConnectivity, LABEL_BUS_CONNECTIVITY_FIXTURE)
Test that changing a label from a net name to a bus name properly updates the connected bus wire's co...
BOOST_CHECK_EQUAL(result, "25.4")
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683