You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

739 lines
25 KiB

7 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2018 CERN
  5. * Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
  6. * @author Jon Evans <jon@craftyjon.com>
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version 2
  11. * of the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License along
  19. * with this program. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. #ifndef _CONNECTION_GRAPH_H
  22. #define _CONNECTION_GRAPH_H
  23. #include <mutex>
  24. #include <vector>
  25. #include <erc_settings.h>
  26. #include <sch_connection.h>
  27. #include <sch_item.h>
  28. #include <wx/treectrl.h>
  29. #ifdef DEBUG
  30. // Uncomment this line to enable connectivity debugging features
  31. // #define CONNECTIVITY_DEBUG
  32. #endif
  33. class CONNECTION_GRAPH;
  34. class SCHEMATIC;
  35. class SCH_EDIT_FRAME;
  36. class SCH_HIERLABEL;
  37. class SCH_PIN;
  38. class SCH_SHEET_PIN;
  39. /**
  40. * A subgraph is a set of items that are electrically connected on a single sheet.
  41. *
  42. * For example, a label connected to a wire and so on.
  43. * A net is composed of one or more subgraphs.
  44. *
  45. * A set of items that appears to be physically connected may actually be more
  46. * than one subgraph, because some items don't connect electrically.
  47. *
  48. * For example, multiple bus wires can come together at a junction but have
  49. * different labels on each branch. Each label+wire branch is its own subgraph.
  50. */
  51. class CONNECTION_SUBGRAPH
  52. {
  53. public:
  54. enum class PRIORITY
  55. {
  56. INVALID = -1,
  57. NONE = 0,
  58. PIN,
  59. SHEET_PIN,
  60. HIER_LABEL,
  61. LOCAL_LABEL,
  62. POWER_PIN,
  63. GLOBAL
  64. };
  65. explicit CONNECTION_SUBGRAPH( CONNECTION_GRAPH* aGraph ) :
  66. m_graph( aGraph ),
  67. m_dirty( false ),
  68. m_absorbed( false ),
  69. m_is_bus_member( false ),
  70. m_absorbed_by( nullptr ),
  71. m_code( -1 ),
  72. m_multiple_drivers( false ),
  73. m_strong_driver( false ),
  74. m_local_driver( false ),
  75. m_bus_entry( nullptr ),
  76. m_hier_parent( nullptr ),
  77. m_driver( nullptr ),
  78. m_no_connect( nullptr ),
  79. m_driver_connection( nullptr )
  80. {}
  81. ~CONNECTION_SUBGRAPH()
  82. {
  83. for( SCH_CONNECTION* connection : m_bus_element_connections )
  84. delete connection;
  85. }
  86. friend class CONNECTION_GRAPH;
  87. /**
  88. * Determine which potential driver should drive the subgraph.
  89. *
  90. * If multiple possible drivers exist, picks one according to the priority.
  91. * If multiple "winners" exist, returns false and sets #m_driver to nullptr.
  92. *
  93. * @param aCheckMultipleDrivers controls whether the second driver should be captured for ERC.
  94. * @return true if m_driver was set, or false if a conflict occurred.
  95. */
  96. bool ResolveDrivers( bool aCheckMultipleDrivers = false );
  97. /**
  98. * Return the fully-qualified net name for this subgraph (if one exists)
  99. */
  100. wxString GetNetName() const;
  101. /// Return all the vector-based bus labels attached to this subgraph (if any).
  102. std::vector<SCH_ITEM*> GetVectorBusLabels() const;
  103. /// Return all the all bus labels attached to this subgraph (if any).
  104. std::vector<SCH_ITEM*> GetAllBusLabels() const;
  105. /// Return the candidate net name for a driver.
  106. const wxString& GetNameForDriver( SCH_ITEM* aItem ) const;
  107. const wxString GetNetclassForDriver( SCH_ITEM* aItem ) const;
  108. /// Combine another subgraph on the same sheet into this one.
  109. void Absorb( CONNECTION_SUBGRAPH* aOther );
  110. /// Add a new item to the subgraph.
  111. void AddItem( SCH_ITEM* aItem );
  112. /// Update all items to match the driver connection.
  113. void UpdateItemConnections();
  114. /// Provide a read-only reference to the items in the subgraph.
  115. const std::set<SCH_ITEM*>& GetItems() const
  116. {
  117. return m_items;
  118. }
  119. /// Find all items in the subgraph as well as child subgraphs recursively.
  120. void getAllConnectedItems( std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>>& aItems,
  121. std::set<CONNECTION_SUBGRAPH*>& aSubgraphs );
  122. /**
  123. * Return the priority (higher is more important) of a candidate driver
  124. *
  125. * 0: Invalid driver
  126. * 1: Symbol pin
  127. * 2: Hierarchical sheet pin
  128. * 3: Hierarchical label
  129. * 4: Local label
  130. * 5: Power pin
  131. * 6: Global label
  132. *
  133. * @param aDriver is the item to inspect
  134. * @return a PRIORITY
  135. */
  136. static PRIORITY GetDriverPriority( SCH_ITEM* aDriver );
  137. PRIORITY GetDriverPriority()
  138. {
  139. if( m_driver )
  140. return GetDriverPriority( m_driver );
  141. else
  142. return PRIORITY::NONE;
  143. }
  144. /**
  145. * @return pointer to the SCH_ITEM whose name sets the subgraph netname.
  146. * N.B. This item may not be in the subgraph.
  147. */
  148. const SCH_ITEM* GetDriver() const
  149. {
  150. return m_driver;
  151. }
  152. /**
  153. * @return #SCH_CONNECTION object for m_driver on #m_sheet.
  154. */
  155. const SCH_CONNECTION* GetDriverConnection() const
  156. {
  157. return m_driver_connection;
  158. }
  159. /**
  160. * @return pointer to the item causing a no-connect or nullptr if none.
  161. */
  162. const SCH_ITEM* GetNoConnect() const
  163. {
  164. return m_no_connect;
  165. }
  166. const SCH_SHEET_PATH& GetSheet() const
  167. {
  168. return m_sheet;
  169. }
  170. void RemoveItem( SCH_ITEM* aItem );
  171. // Use this to keep a connection pointer that is not owned by any item
  172. // This will be destroyed with the subgraph
  173. void StoreImplicitConnection( SCH_CONNECTION* aConnection )
  174. {
  175. m_bus_element_connections.insert( aConnection );
  176. }
  177. private:
  178. wxString driverName( SCH_ITEM* aItem ) const;
  179. CONNECTION_GRAPH* m_graph;
  180. bool m_dirty;
  181. /// True if this subgraph has been absorbed into another. No pointers here are safe if so!
  182. bool m_absorbed;
  183. /**
  184. * True if the subgraph is not actually part of a net. These are created for bus members
  185. * to ensure that bus-to-bus connection happens but they don't have any valid data
  186. */
  187. bool m_is_bus_member;
  188. /// If this subgraph is absorbed, points to the absorbing (and valid) subgraph
  189. CONNECTION_SUBGRAPH* m_absorbed_by;
  190. /// Set of subgraphs that have been absorbed by this subgraph
  191. std::set<CONNECTION_SUBGRAPH*> m_absorbed_subgraphs;
  192. long m_code;
  193. /**
  194. * True if this subgraph contains more than one driver that should be
  195. * shorted together in the netlist. For example, two labels or
  196. * two power ports.
  197. */
  198. bool m_multiple_drivers;
  199. /// True if the driver is "strong": a label or power object.
  200. bool m_strong_driver;
  201. /// True if the driver is a local (i.e. non-global) type.
  202. bool m_local_driver;
  203. /// Bus entry in graph, if any.
  204. SCH_ITEM* m_bus_entry;
  205. std::set<SCH_ITEM*> m_drivers;
  206. /**
  207. * If a subgraph is a bus, this map contains links between the bus members and any
  208. * local sheet neighbors with the same connection name.
  209. *
  210. * For example, if this subgraph is a bus D[7..0], and on the same sheet there is
  211. * a net with label D7, this map will contain an entry for the D7 bus member, and
  212. * the set will contain a pointer to the D7 net subgraph.
  213. */
  214. std::unordered_map< std::shared_ptr<SCH_CONNECTION>,
  215. std::unordered_set<CONNECTION_SUBGRAPH*> > m_bus_neighbors;
  216. /**
  217. * If this is a net, this vector contains links to any same-sheet buses that contain it.
  218. * The string key is the name of the connection that forms the link (which isn't necessarily
  219. * the same as the name of the connection driving this subgraph)
  220. */
  221. std::unordered_map< std::shared_ptr<SCH_CONNECTION>,
  222. std::unordered_set<CONNECTION_SUBGRAPH*> > m_bus_parents;
  223. /// Cache for lookup of any hierarchical (sheet) pins on this subgraph (for referring down).
  224. std::set<SCH_SHEET_PIN*> m_hier_pins;
  225. /// Cache for lookup of any hierarchical ports on this subgraph (for referring up).
  226. std::set<SCH_HIERLABEL*> m_hier_ports;
  227. /// If not null, this indicates the subgraph on a higher level sheet that is linked to this one.
  228. CONNECTION_SUBGRAPH* m_hier_parent;
  229. /// If not null, this indicates the subgraph(s) on a lower level sheet that are linked to
  230. /// this one.
  231. std::unordered_set<CONNECTION_SUBGRAPH*> m_hier_children;
  232. /// A cache of escaped netnames from schematic items.
  233. mutable std::unordered_map<SCH_ITEM*, wxString> m_driver_name_cache;
  234. /// Fully-resolved driver for the subgraph (might not exist in this subgraph).
  235. SCH_ITEM* m_driver;
  236. /// Contents of the subgraph.
  237. std::set<SCH_ITEM*> m_items;
  238. /// No-connect item in graph, if any.
  239. SCH_ITEM* m_no_connect;
  240. /// On which logical sheet is the subgraph contained.
  241. SCH_SHEET_PATH m_sheet;
  242. /// Cache for driver connection.
  243. SCH_CONNECTION* m_driver_connection;
  244. /// A cache of connections that are part of this subgraph but that don't have
  245. /// an owning element (i.e. bus members)
  246. std::set<SCH_CONNECTION*> m_bus_element_connections;
  247. };
  248. struct NET_NAME_CODE_CACHE_KEY
  249. {
  250. wxString Name;
  251. int Netcode;
  252. bool operator==(const NET_NAME_CODE_CACHE_KEY& other) const
  253. {
  254. return Name == other.Name && Netcode == other.Netcode;
  255. }
  256. };
  257. namespace std
  258. {
  259. template <>
  260. struct hash<NET_NAME_CODE_CACHE_KEY>
  261. {
  262. std::size_t operator()( const NET_NAME_CODE_CACHE_KEY& k ) const
  263. {
  264. const std::size_t prime = 19937;
  265. return hash<wxString>()( k.Name ) ^ ( hash<int>()( k.Netcode ) * prime );
  266. }
  267. };
  268. }
  269. /// Associate a #NET_CODE_NAME with all the subgraphs in that net.
  270. typedef std::unordered_map<NET_NAME_CODE_CACHE_KEY, std::vector<CONNECTION_SUBGRAPH*>> NET_MAP;
  271. /**
  272. * Calculate the connectivity of a schematic and generates netlists.
  273. */
  274. class CONNECTION_GRAPH
  275. {
  276. public:
  277. CONNECTION_GRAPH( SCHEMATIC* aSchematic = nullptr ) :
  278. m_last_net_code( 1 ),
  279. m_last_bus_code( 1 ),
  280. m_last_subgraph_code( 1 ),
  281. m_schematic( aSchematic )
  282. {}
  283. ~CONNECTION_GRAPH()
  284. {
  285. Reset();
  286. }
  287. void Reset();
  288. void SetSchematic( SCHEMATIC* aSchematic )
  289. {
  290. m_schematic = aSchematic;
  291. }
  292. void SetLastCodes( const CONNECTION_GRAPH* aOther )
  293. {
  294. m_last_net_code = aOther->m_last_net_code;
  295. m_last_bus_code = aOther->m_last_bus_code;
  296. m_last_subgraph_code = aOther->m_last_subgraph_code;
  297. }
  298. /**
  299. * Update the connection graph for the given list of sheets.
  300. *
  301. * @param aSheetList is the list of possibly modified sheets
  302. * @param aUnconditional is true if an unconditional full recalculation should be done
  303. * @param aChangedItemHandler an optional handler to receive any changed items
  304. */
  305. void Recalculate( const SCH_SHEET_LIST& aSheetList, bool aUnconditional = false,
  306. std::function<void( SCH_ITEM* )>* aChangedItemHandler = nullptr );
  307. /**
  308. * Return a bus alias pointer for the given name if it exists (from cache)
  309. *
  310. * CONNECTION_GRAPH caches these, they are owned by the SCH_SCREEN that
  311. * the alias was defined on. The cache is only used to update the graph.
  312. */
  313. std::shared_ptr<BUS_ALIAS> GetBusAlias( const wxString& aName );
  314. /**
  315. * Determine which subgraphs have more than one conflicting bus label.
  316. *
  317. * @see DIALOG_MIGRATE_BUSES
  318. * @return a list of subgraphs that need migration
  319. */
  320. std::vector<const CONNECTION_SUBGRAPH*> GetBusesNeedingMigration();
  321. /**
  322. * Run electrical rule checks on the connectivity graph.
  323. *
  324. * Precondition: graph is up-to-date
  325. *
  326. * @return the number of errors found
  327. */
  328. int RunERC();
  329. const NET_MAP& GetNetMap() const { return m_net_code_to_subgraphs_map; }
  330. /**
  331. * Return the subgraph for a given net name on a given sheet.
  332. *
  333. * @param aNetName is the local net name to look for.
  334. * @param aPath is a sheet path to look on.
  335. * @return the subgraph matching the query, or nullptr if none is found.
  336. */
  337. CONNECTION_SUBGRAPH* FindSubgraphByName( const wxString& aNetName,
  338. const SCH_SHEET_PATH& aPath );
  339. /**
  340. * Retrieve a subgraph for the given net name, if one exists.
  341. *
  342. * Search every sheet.
  343. *
  344. * @param aNetName is the full net name to search for.
  345. * @return the subgraph matching the query, or nullptr if none is found.
  346. */
  347. CONNECTION_SUBGRAPH* FindFirstSubgraphByName( const wxString& aNetName );
  348. CONNECTION_SUBGRAPH* GetSubgraphForItem( SCH_ITEM* aItem );
  349. const std::vector<CONNECTION_SUBGRAPH*> GetAllSubgraphs( const wxString& aNetName ) const;
  350. /**
  351. * Return the fully-resolved netname for a given subgraph.
  352. *
  353. * @param aSubGraph Reference to the subgraph.
  354. * @return Netname string usable with m_net_name_to_subgraphs_map.
  355. */
  356. wxString GetResolvedSubgraphName( const CONNECTION_SUBGRAPH* aSubGraph ) const;
  357. /**
  358. * For a set of items, this will remove the connected items and their
  359. * associated data including subgraphs and generated codes from the connection graph.
  360. *
  361. * @param aItems A vector of items whose presence should be removed from the graph.
  362. * @return The full set of all items associated with the input items that were removed.
  363. */
  364. std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> ExtractAffectedItems(
  365. const std::set<SCH_ITEM*> &aItems );
  366. /**
  367. * Combine the input graph contents into the current graph.
  368. *
  369. * @warning After merging, the original graph is invalid.
  370. *
  371. * @param aGraph Input graph reference to add to the current graph.
  372. */
  373. void Merge( CONNECTION_GRAPH& aGraph );
  374. private:
  375. /**
  376. * Update the graphical connectivity between items (i.e. where they touch)
  377. * The items passed in must be on the same sheet.
  378. *
  379. * In the first phase, all items in aItemList have their connections
  380. * initialized for the given sheet (since they may have connections on more
  381. * than one sheet, and each needs to be calculated individually). The
  382. * graphical connection points for the item are added to a map that stores
  383. * (x, y) -> [list of items].
  384. *
  385. * Any item that is stored in the list of items that have a connection point
  386. * at a given (x, y) location will eventually be electrically connected.
  387. * This means that we can't store SCH_SYMBOLs in this map -- we must store
  388. * a structure that links a specific pin on a symbol back to that symbol: a
  389. * SCH_PIN_CONNECTION. This wrapper class is a convenience for linking a pin
  390. * and symbol to a specific (x, y) point.
  391. *
  392. * In the second phase, we iterate over each value in the map, which is a
  393. * vector of items that have overlapping connection points. After some
  394. * checks to ensure that the items should actually connect, the items are
  395. * linked together using ConnectedItems().
  396. *
  397. * As a side effect, items are loaded into m_items for BuildConnectionGraph().
  398. *
  399. * @param aSheet is the path to the sheet of all items in the list.
  400. * @param aItemList is a list of items to consider.
  401. */
  402. void updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
  403. const std::vector<SCH_ITEM*>& aItemList );
  404. /**
  405. * Generate the connection graph (after all item connectivity has been updated).
  406. *
  407. * In the first phase, the algorithm iterates over all items, and then over
  408. * all items that are connected (graphically) to each item, placing them into
  409. * CONNECTION_SUBGRAPHs. Items that can potentially drive connectivity (i.e.
  410. * labels, pins, etc.) are added to the m_drivers vector of the subgraph.
  411. *
  412. * In the second phase, each subgraph is resolved. To resolve a subgraph,
  413. * the driver is first selected by CONNECTION_SUBGRAPH::ResolveDrivers(),
  414. * and then the connection for the chosen driver is propagated to all the
  415. * other items in the subgraph.
  416. */
  417. void buildConnectionGraph( std::function<void( SCH_ITEM* )>* aChangedItemHandler );
  418. /**
  419. * Generate individual item subgraphs on a per-sheet basis.
  420. */
  421. void buildItemSubGraphs();
  422. /**
  423. * Find all subgraphs in the connection graph and calls ResolveDrivers() in parallel.
  424. */
  425. void resolveAllDrivers();
  426. /**
  427. * Map the driver values for each subgraph.
  428. */
  429. void collectAllDriverValues();
  430. /**
  431. * Iterate through the global power pins to collect the global labels as drivers.
  432. */
  433. void generateGlobalPowerPinSubGraphs();
  434. /**
  435. * Iterate through labels to create placeholders for bus elements.
  436. */
  437. void generateBusAliasMembers();
  438. /**
  439. * Process all subgraphs to assign netcodes and merge subgraphs based on labels.
  440. */
  441. void processSubGraphs();
  442. /**
  443. * Helper to assign a new net code to a connection.
  444. *
  445. * @return the assigned code
  446. */
  447. int assignNewNetCode( SCH_CONNECTION& aConnection );
  448. /**
  449. *
  450. * @param aNetName string with the netname for coding
  451. * @return existing netcode (if it exists) or newly created one
  452. */
  453. int getOrCreateNetCode( const wxString& aNetName );
  454. /**
  455. * Ensure all members of the bus connection have a valid net code assigned.
  456. *
  457. * @param aConnection is a bus connection.
  458. */
  459. void assignNetCodesToBus( SCH_CONNECTION* aConnection );
  460. /**
  461. * Update all neighbors of a subgraph with this one's connectivity info.
  462. *
  463. * If this subgraph contains hierarchical links, this method will descent the
  464. * hierarchy and propagate the connectivity across all linked sheets.
  465. *
  466. * @param aSubgraph is the subgraph being processed.
  467. * @param aForce prevents this routine from skipping subgraphs.
  468. */
  469. void propagateToNeighbors( CONNECTION_SUBGRAPH* aSubgraph, bool aForce );
  470. /**
  471. * Remove references to the given subgraphs from all structures in the connection graph.
  472. *
  473. * @param aSubgraphs set of unique subgraphs to find/remove.
  474. */
  475. void removeSubgraphs( std::set<CONNECTION_SUBGRAPH*>& aSubgraphs );
  476. /**
  477. * Search for a matching bus member inside a bus connection.
  478. *
  479. * For bus groups, this returns a bus member that matches aSearch by name.
  480. * For bus vectors, this returns a bus member that matches by vector index.
  481. *
  482. * @param aBusConnection is the bus connection to search.
  483. * @param aSearch is the net connection to search for.
  484. * @returns a member of aBusConnection that matches aSearch.
  485. */
  486. static SCH_CONNECTION* matchBusMember( SCH_CONNECTION* aBusConnection,
  487. SCH_CONNECTION* aSearch );
  488. /**
  489. * Build a new default connection for the given item based on its properties.
  490. *
  491. * Handles strong drivers (power pins and labels) only.
  492. *
  493. * @param aItem is an item that can generate a connection name.
  494. * @param aSubgraph is used to determine the sheet to use and retrieve the cached name.
  495. * @return a connection generated from the item, or nullptr if item is not valid.
  496. */
  497. std::shared_ptr<SCH_CONNECTION> getDefaultConnection( SCH_ITEM* aItem,
  498. CONNECTION_SUBGRAPH* aSubgraph );
  499. void recacheSubgraphName( CONNECTION_SUBGRAPH* aSubgraph, const wxString& aOldName );
  500. /**
  501. * If the subgraph has multiple drivers of equal priority that are graphically connected,
  502. * ResolveDrivers() will have stored the second driver for use by this function, which actually
  503. * creates the markers.
  504. *
  505. * @param aSubgraph is the subgraph to examine
  506. * @return true for no errors, false for errors
  507. */
  508. bool ercCheckMultipleDrivers( const CONNECTION_SUBGRAPH* aSubgraph );
  509. bool ercCheckNetclassConflicts( const std::vector<CONNECTION_SUBGRAPH*>& subgraphs );
  510. /**
  511. * Check one subgraph for conflicting connections between net and bus labels.
  512. *
  513. * For example, a net wire connected to a bus port/pin, or vice versa
  514. *
  515. * @param aSubgraph is the subgraph to examine.
  516. * @return true for no errors, false for errors.
  517. */
  518. bool ercCheckBusToNetConflicts( const CONNECTION_SUBGRAPH* aSubgraph );
  519. /**
  520. * Check one subgraph for conflicting connections between two bus items.
  521. *
  522. * For example, a labeled bus wire connected to a hierarchical sheet pin
  523. * where the labeled bus doesn't contain any of the same bus members as the
  524. * sheet pin.
  525. *
  526. * @param aSubgraph is the subgraph to examine.
  527. * @return true for no errors, false for errors.
  528. */
  529. bool ercCheckBusToBusConflicts( const CONNECTION_SUBGRAPH* aSubgraph );
  530. /**
  531. * Check one subgraph for conflicting bus entry to bus connections.
  532. *
  533. * For example, a wire with label "A0" is connected to a bus labeled "D[8..0]"
  534. *
  535. * Will also check for mistakes related to bus group names, for example:
  536. * A bus group named "USB{DP DM}" should have bus entry connections like
  537. * "USB.DP" but someone might accidentally just enter "DP".
  538. *
  539. * @param aSubgraph is the subgraph to examine.
  540. * @return true for no errors, false for errors.
  541. */
  542. bool ercCheckBusToBusEntryConflicts( const CONNECTION_SUBGRAPH* aSubgraph );
  543. /**
  544. * Check one subgraph for proper presence or absence of no-connect symbols.
  545. *
  546. * A pin with a no-connect symbol should not have any connections.
  547. * A pin without a no-connect symbol should have at least one connection.
  548. *
  549. * @param aSubgraph is the subgraph to examine.
  550. * @return true for no errors, false for errors.
  551. */
  552. bool ercCheckNoConnects( const CONNECTION_SUBGRAPH* aSubgraph );
  553. /**
  554. * Check one subgraph for floating wires.
  555. *
  556. * Will throw an error for any subgraph that consists of just wires with no driver.
  557. *
  558. * @param aSubgraph is the subgraph to examine.
  559. * @return true for no errors, false for errors.
  560. */
  561. bool ercCheckFloatingWires( const CONNECTION_SUBGRAPH* aSubgraph );
  562. /**
  563. * Check one subgraph for proper connection of labels.
  564. *
  565. * Labels should be connected to something.
  566. *
  567. * @param aSubgraph is the subgraph to examine.
  568. * @param aCheckGlobalLabels is true if global labels should be checked for loneliness.
  569. * @return true for no errors, false for errors.
  570. */
  571. bool ercCheckLabels( const CONNECTION_SUBGRAPH* aSubgraph );
  572. /**
  573. * Check that a hierarchical sheet has at least one matching label inside the sheet for each
  574. * port on the parent sheet object.
  575. *
  576. * @param aSubgraph is the subgraph to examine.
  577. * @return the number of errors found.
  578. */
  579. int ercCheckHierSheets();
  580. /**
  581. * Get the number of pins in a given subgraph.
  582. *
  583. * @param aLocSubgraph Subgraph to search
  584. * @return total number of pins in the subgraph
  585. */
  586. size_t hasPins( const CONNECTION_SUBGRAPH* aLocSubgraph );
  587. private:
  588. /// All the sheets in the schematic (as long as we don't have partial updates).
  589. SCH_SHEET_LIST m_sheetList;
  590. /// All connectable items in the schematic.
  591. std::vector<SCH_ITEM*> m_items;
  592. /// The owner of all #CONNECTION_SUBGRAPH objects.
  593. std::vector<CONNECTION_SUBGRAPH*> m_subgraphs;
  594. /// Cache of a subset of #m_subgraphs.
  595. std::vector<CONNECTION_SUBGRAPH*> m_driver_subgraphs;
  596. /// Cache to lookup subgraphs in #m_driver_subgraphs by sheet path.
  597. std::unordered_map<SCH_SHEET_PATH, std::vector<CONNECTION_SUBGRAPH*>> m_sheet_to_subgraphs_map;
  598. std::vector<std::pair<SCH_SHEET_PATH, SCH_PIN*>> m_global_power_pins;
  599. std::unordered_map<wxString, std::shared_ptr<BUS_ALIAS>> m_bus_alias_cache;
  600. std::unordered_map<wxString, int> m_net_name_to_code_map;
  601. std::unordered_map<wxString, int> m_bus_name_to_code_map;
  602. std::unordered_map<wxString, std::vector<const CONNECTION_SUBGRAPH*>> m_global_label_cache;
  603. std::map< std::pair<SCH_SHEET_PATH, wxString>,
  604. std::vector<const CONNECTION_SUBGRAPH*> > m_local_label_cache;
  605. std::unordered_map<wxString, std::vector<CONNECTION_SUBGRAPH*>> m_net_name_to_subgraphs_map;
  606. std::unordered_map<SCH_ITEM*, CONNECTION_SUBGRAPH*> m_item_to_subgraph_map;
  607. NET_MAP m_net_code_to_subgraphs_map;
  608. int m_last_net_code;
  609. int m_last_bus_code;
  610. int m_last_subgraph_code;
  611. SCHEMATIC* m_schematic; ///< The schematic this graph represents.
  612. };
  613. #endif