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 <advanced_config.h>
33#include <connection_graph.h>
35#include <sch_commit.h>
36#include <schematic.h>
37#include <sch_label.h>
38#include <sch_line.h>
39#include <sch_screen.h>
40#include <sch_sheet.h>
41#include <sch_sheet_pin.h>
43#include <tool/tool_manager.h>
44
45
46BOOST_AUTO_TEST_SUITE( LabelBusConnectivity )
47
48
50{
52 m_mgr()
53 {
54 m_mgr.LoadProject( "" );
55 m_schematic = std::make_unique<SCHEMATIC>( &m_mgr.Prj() );
56 m_schematic->Reset();
57 SCH_SHEET* defaultSheet = m_schematic->GetTopLevelSheet( 0 );
58
59 m_screen = new SCH_SCREEN( m_schematic.get() );
60 m_sheet = new SCH_SHEET( m_schematic.get() );
61 m_sheet->SetScreen( m_screen );
62 m_schematic->AddTopLevelSheet( m_sheet );
63 m_schematic->RemoveTopLevelSheet( defaultSheet );
64 delete defaultSheet;
65 }
66
68 std::unique_ptr<SCHEMATIC> m_schematic;
71};
72
73
83{
84 // Create a bus wire
85 SCH_LINE* busWire = new SCH_LINE( VECTOR2I( 0, 0 ), LAYER_BUS );
86 busWire->SetEndPoint( VECTOR2I( 5000000, 0 ) );
87 m_screen->Append( busWire );
88
89 // Create a label with a non-bus name, positioned on the bus wire
90 SCH_LABEL* label = new SCH_LABEL( VECTOR2I( 2500000, 0 ), wxT( "test" ) );
91 m_screen->Append( label );
92
93 // Build initial connectivity
94 SCH_SHEET_LIST sheets = m_schematic->BuildSheetListSortedByPageNumbers();
95 m_schematic->ConnectionGraph()->Recalculate( sheets, true );
96
97 SCH_SHEET_PATH path = sheets[0];
98
99 // Verify initial state: bus wire should have BUS connection type but no members
100 // (because "test" is not a bus name)
101 SCH_CONNECTION* busConn = busWire->Connection( &path );
102 BOOST_REQUIRE( busConn != nullptr );
103 BOOST_CHECK( busConn->IsBus() );
104 BOOST_CHECK( busConn->Members().empty() );
105
106 TOOL_MANAGER manager;
107 manager.SetEnvironment( m_schematic.get(), nullptr, nullptr, nullptr, nullptr );
108 SCH_COMMIT commit( &manager );
109 commit.Modify( label, m_screen );
110 label->SetText( wxT( "test[0..7]" ) );
111 commit.Push( "Change label to a bus", SKIP_UNDO );
112
113 // The push updates only the active engine, and the new engine publishes through the facade
114 if( ADVANCED_CFG::GetCfg().m_ConnectivityEngine )
115 {
116 const auto view = m_schematic->Connectivity().Connection( busWire->m_Uuid, path.Path() );
117 BOOST_REQUIRE( view );
118 BOOST_CHECK( view->IsBus() );
119 BOOST_CHECK_EQUAL( view->Members().leaves.size(), 8 );
120 return;
121 }
122
123 // Verify: bus wire should now have members from the bus label
124 busConn = busWire->Connection( &path );
125 BOOST_REQUIRE( busConn != nullptr );
126 BOOST_CHECK( busConn->IsBus() );
127 BOOST_CHECK_MESSAGE( !busConn->Members().empty(),
128 "Bus wire should have members after label changed to bus name" );
129
130 // Verify the correct number of members (test[0..7] = 8 members)
131 if( !busConn->Members().empty() )
132 {
133 BOOST_CHECK_EQUAL( busConn->Members().size(), 8 );
134 }
135}
136
137
143{
144 // Create a bus wire
145 SCH_LINE* busWire = new SCH_LINE( VECTOR2I( 0, 0 ), LAYER_BUS );
146 busWire->SetEndPoint( VECTOR2I( 5000000, 0 ) );
147 m_screen->Append( busWire );
148
149 // Create a label with a bus name, positioned on the bus wire
150 SCH_LABEL* label = new SCH_LABEL( VECTOR2I( 2500000, 0 ), wxT( "DATA[0..3]" ) );
151 m_screen->Append( label );
152
153 // Build connectivity
154 SCH_SHEET_LIST sheets = m_schematic->BuildSheetListSortedByPageNumbers();
155 m_schematic->ConnectionGraph()->Recalculate( sheets, true );
156
157 SCH_SHEET_PATH path = sheets[0];
158
159 // Verify: bus wire should have members from the bus label
160 SCH_CONNECTION* busConn = busWire->Connection( &path );
161 BOOST_REQUIRE( busConn != nullptr );
162 BOOST_CHECK( busConn->IsBus() );
163 BOOST_CHECK_MESSAGE( !busConn->Members().empty(),
164 "Bus wire should have members from bus label" );
165
166 // Verify the correct number of members (DATA[0..3] = 4 members)
167 if( !busConn->Members().empty() )
168 {
169 BOOST_CHECK_EQUAL( busConn->Members().size(), 4 );
170 }
171}
172
173
180BOOST_FIXTURE_TEST_CASE( SheetPinBusConnectionSurvivesMove, LABEL_BUS_CONNECTIVITY_FIXTURE )
181{
182 const wxString busName( wxT( "bus{A B}" ) );
183 const int sheetLeft = 10000000;
184
185 SCH_SCREEN* childScreen = new SCH_SCREEN( m_schematic.get() );
186 SCH_SHEET* childSheet = new SCH_SHEET( m_schematic.get(), VECTOR2I( sheetLeft, 0 ),
187 VECTOR2I( 20000000, 20000000 ) );
188
189 childScreen->SetFileName( wxT( "child.kicad_sch" ) );
190 childSheet->SetScreen( childScreen );
191 childSheet->SetName( wxT( "child" ) );
192 childSheet->SetFileName( wxT( "child.kicad_sch" ) );
193 m_screen->Append( childSheet );
194
195 childScreen->Append( new SCH_HIERLABEL( VECTOR2I( 0, 0 ), busName ) );
196
197 // The pin rides the sheet's left edge, so its x has to track the sheet origin
198 SCH_SHEET_PIN* pin = new SCH_SHEET_PIN( childSheet, VECTOR2I( sheetLeft, 5000000 ), busName );
199 childSheet->AddPin( pin );
200
201 SCH_LINE* busWire = new SCH_LINE( VECTOR2I( 5000000, 5000000 ), LAYER_BUS );
202 busWire->SetEndPoint( pin->GetTextPos() );
203 m_screen->Append( busWire );
204
205 m_schematic->RefreshHierarchy();
206
207 SCH_SHEET_LIST sheets = m_schematic->Hierarchy();
208 m_schematic->ConnectionGraph()->Recalculate( sheets, true );
209
210 SCH_SHEET_PATH rootPath = sheets[0];
211 SCH_CONNECTION* pinConn = pin->Connection( &rootPath );
212
213 BOOST_REQUIRE_MESSAGE( pinConn != nullptr, "Sheet pin has no connection before the move" );
214 BOOST_REQUIRE_MESSAGE( pinConn->IsBus(), "Sheet pin is not a bus before the move" );
215
216 // Simulate dragging the pin along the sheet edge with its bus wire attached
217 const VECTOR2I newPos( sheetLeft, 8000000 );
218
219 pin->SetPosition( newPos );
220 busWire->SetEndPoint( pin->GetTextPos() );
221 pin->SetConnectivityDirty( true );
222 busWire->SetConnectivityDirty( true );
223
224 // A schematic this small is a minor graph, so SCHEMATIC::RecalculateConnections() rebuilds
225 // unconditionally after the move
226 BOOST_REQUIRE( m_schematic->ConnectionGraph()->IsMinor() );
227 m_schematic->ConnectionGraph()->Recalculate( sheets, true );
228
229 // SCH_PAINTER ignores the resolved connection while this flag is set, which is what drops
230 // the bus colour
231 BOOST_CHECK_MESSAGE( !pin->IsConnectivityDirty(),
232 "Sheet pin connectivity still dirty after recalculation" );
233
234 pinConn = pin->Connection( &rootPath );
235
236 BOOST_REQUIRE_MESSAGE( pinConn != nullptr, "Sheet pin lost its connection after the move" );
237 BOOST_CHECK_MESSAGE( pinConn->IsBus(), "Sheet pin lost its bus connection after the move" );
238}
239
240
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
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
const KIID m_Uuid
Definition eda_item.h:599
virtual void SetText(const wxString &aText)
Definition eda_text.cpp:236
Commit for the schematic and symbol editors.
Definition sch_commit.h:54
void Push(const wxString &aMessage=wxEmptyString, 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)
Set the dirty flag.
Definition sch_item.cpp:314
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:580
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:392
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:708