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.

318 lines
9.8 KiB

6 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-2023 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 _SCH_CONNECTION_H
  22. #define _SCH_CONNECTION_H
  23. #include <memory>
  24. #include <unordered_set>
  25. #include <wx/regex.h>
  26. #include <bus_alias.h>
  27. #include <sch_sheet_path.h>
  28. class CONNECTION_GRAPH;
  29. class SCH_ITEM;
  30. class SCH_SHEET_PATH;
  31. class MSG_PANEL_ITEM;
  32. enum class CONNECTION_TYPE
  33. {
  34. NONE, ///< No connection to this item
  35. NET, ///< This item represents a net
  36. BUS, ///< This item represents a bus vector
  37. BUS_GROUP, ///< This item represents a bus group
  38. };
  39. /**
  40. * Each graphical item can have a SCH_CONNECTION describing its logical
  41. * connection (to a bus or net). These are generated when netlisting, or when
  42. * editing operations that can change the netlist are performed.
  43. *
  44. * In hierarchical schematics, a single SCH_ITEM object can refer to multiple
  45. * distinct parts of a design (in the case of a sub-sheet that is instanced
  46. * more than once in a higher level sheet). Because of this, a single item may
  47. * contain more than one SCH_CONNECTION -- each is specific to a sheet.
  48. *
  49. * Symbols contain connections for each of their pins (and for each sheet they
  50. * exist on) but don't use their own connection object.
  51. */
  52. class SCH_CONNECTION
  53. {
  54. public:
  55. SCH_CONNECTION( SCH_ITEM* aParent = nullptr, const SCH_SHEET_PATH& aPath = SCH_SHEET_PATH() );
  56. SCH_CONNECTION( SCH_CONNECTION& aOther );
  57. SCH_CONNECTION( CONNECTION_GRAPH* aGraph );
  58. ~SCH_CONNECTION()
  59. {}
  60. /**
  61. * Note: the equality operator for SCH_CONNECTION only tests the net
  62. * properties, not the ownership / sheet location!
  63. */
  64. bool operator==( const SCH_CONNECTION& aOther ) const;
  65. bool operator!=( const SCH_CONNECTION& aOther ) const;
  66. void SetGraph( CONNECTION_GRAPH* aGraph )
  67. {
  68. m_graph = aGraph;
  69. }
  70. /**
  71. * Configures the connection given a label.
  72. * For CONNECTION_NET, this just sets the name.
  73. * For CONNECTION_BUS, this will deduce the correct BUS_TYPE and also
  74. * generate a correct list of members.
  75. */
  76. void ConfigureFromLabel( const wxString& aLabel );
  77. /**
  78. * Clears connectivity information
  79. */
  80. void Reset();
  81. /**
  82. * Copies connectivity information (but not parent) from another connection
  83. *
  84. * @param aOther is the connection to clone
  85. */
  86. void Clone( const SCH_CONNECTION& aOther );
  87. SCH_ITEM* Parent() const { return m_parent; }
  88. SCH_ITEM* Driver() const { return m_driver; }
  89. void SetDriver( SCH_ITEM* aItem );
  90. SCH_SHEET_PATH Sheet() const { return m_sheet; }
  91. void SetSheet( SCH_SHEET_PATH aSheet );
  92. SCH_SHEET_PATH LocalSheet() const { return m_local_sheet; }
  93. /**
  94. * Checks if the SCH_ITEM this connection is attached to can drive connections
  95. * Drivers can be labels, sheet pins, or symbol pins.
  96. *
  97. * @return true if the attached items is a driver
  98. */
  99. bool IsDriver() const;
  100. bool IsBus() const
  101. {
  102. return ( m_type == CONNECTION_TYPE::BUS || m_type == CONNECTION_TYPE::BUS_GROUP );
  103. }
  104. bool IsNet() const
  105. {
  106. return ( m_type == CONNECTION_TYPE::NET );
  107. }
  108. bool IsUnconnected() const { return ( m_type == CONNECTION_TYPE::NONE ); }
  109. bool IsDirty() const { return m_dirty; }
  110. void SetDirty() { m_dirty = true; }
  111. void ClearDirty() { m_dirty = false; }
  112. bool HasDriverChanged() const;
  113. void ClearDriverChanged();
  114. void* GetLastDriver() const { return m_lastDriver; }
  115. wxString Name( bool aIgnoreSheet = false ) const;
  116. wxString LocalName() const { return m_local_name; }
  117. wxString FullLocalName() const
  118. {
  119. return m_local_prefix + m_local_name + m_suffix;
  120. }
  121. void SetName( const wxString& aName )
  122. {
  123. m_name = aName;
  124. recacheName();
  125. }
  126. wxString GetNetName() const;
  127. wxString Prefix() const { return m_prefix; }
  128. void SetPrefix( const wxString& aPrefix );
  129. wxString BusPrefix() const { return m_bus_prefix; }
  130. wxString Suffix() const { return m_suffix; }
  131. void SetSuffix( const wxString& aSuffix );
  132. CONNECTION_TYPE Type() const { return m_type; }
  133. void SetType( CONNECTION_TYPE aType )
  134. {
  135. m_type = aType;
  136. recacheName();
  137. }
  138. int NetCode() const { return m_net_code; }
  139. void SetNetCode( int aCode ) { m_net_code = aCode; }
  140. int BusCode() const { return m_bus_code; }
  141. void SetBusCode( int aCode ) { m_bus_code = aCode; }
  142. int SubgraphCode() const { return m_subgraph_code; }
  143. void SetSubgraphCode( int aCode ) { m_subgraph_code = aCode; }
  144. long VectorStart() const { return m_vector_start; }
  145. long VectorEnd() const { return m_vector_end; }
  146. long VectorIndex() const { return m_vector_index; }
  147. wxString VectorPrefix() const { return m_vector_prefix; }
  148. const std::vector< std::shared_ptr< SCH_CONNECTION > >& Members() const
  149. {
  150. return m_members;
  151. }
  152. const std::vector< std::shared_ptr< SCH_CONNECTION > > AllMembers() const;
  153. static wxString PrintBusForUI( const wxString& aString );
  154. /**
  155. * Returns true if this connection is contained within aOther (but not the same as aOther)
  156. * @return true if this connection is a member of aOther
  157. */
  158. bool IsSubsetOf( SCH_CONNECTION* aOther ) const;
  159. /**
  160. * Returns true if this connection is a member of bus connection aOther
  161. *
  162. * Will always return false if aOther is not a bus connection
  163. */
  164. bool IsMemberOfBus( SCH_CONNECTION* aOther ) const;
  165. /**
  166. * Adds information about the connection object to aList
  167. */
  168. void AppendInfoToMsgPanel( std::vector<MSG_PANEL_ITEM>& aList ) const;
  169. /**
  170. * Test if \a aLabel has a bus notation.
  171. *
  172. * @param aLabel A wxString object containing the label to test.
  173. * @return true if text is a bus notation format otherwise false is returned.
  174. */
  175. static bool IsBusLabel( const wxString& aLabel );
  176. /**
  177. * Test if \a aLabel looks like a bus notation.
  178. * This check is much less expensive than IsBusLabel.
  179. *
  180. * @param aLabel A wxString object containing the label to test.
  181. * @return true if text might be a bus label
  182. */
  183. static bool MightBeBusLabel( const wxString& aLabel );
  184. private:
  185. void recacheName();
  186. bool m_dirty;
  187. SCH_SHEET_PATH m_sheet; ///< The hierarchical sheet this connection is on
  188. /**
  189. * When a connection is overridden by one on a different hierarchical sheet, it will be cloned
  190. * and m_sheet will point to the parent sheet. This member stores the original sheet so that it
  191. * can be used for applications such as net highlighting to retrieve the sheet of the parent
  192. * item from the highlighted connection.
  193. */
  194. SCH_SHEET_PATH m_local_sheet;
  195. SCH_ITEM* m_parent; ///< The SCH_ITEM this connection is owned by
  196. void* m_lastDriver; ///< WEAK POINTER (there is no guarantee it is still allocated)
  197. ///< Equality comparisons are OK, but that's pretty much it
  198. SCH_ITEM* m_driver; ///< The SCH_ITEM that drives this connection's net
  199. CONNECTION_TYPE m_type; ///< @see enum CONNECTION_TYPE
  200. wxString m_name; ///< Name of the connection.
  201. wxString m_cached_name; ///< Full name, including prefix and suffix
  202. wxString m_cached_name_with_path; ///< Full name including sheet path (if not global)
  203. /**
  204. * For bus members, we want to keep track of the "local" name of a member, that is,
  205. * the name it takes on from its parent bus name. This is because we always want to use
  206. * the local name for bus unfolding, matching within buses, etc. The actual resolved name
  207. * of this bus member might change, for example if it's connected elsewhere to some other
  208. * item with higher priority.
  209. */
  210. wxString m_local_name;
  211. /// Prefix if connection is member of a labeled bus group (or "" if not)
  212. wxString m_prefix;
  213. /// Local prefix for group bus members (used with m_local_name)
  214. wxString m_local_prefix;
  215. /// Optional prefix of a bux group (always empty for nets and vector buses)
  216. wxString m_bus_prefix;
  217. wxString m_suffix; ///< Name suffix (used only for disambiguation)
  218. int m_net_code; // TODO(JE) remove if unused
  219. int m_bus_code; // TODO(JE) remove if unused
  220. int m_subgraph_code; ///< Groups directly-connected items
  221. long m_vector_index; ///< Index of bus vector member nets
  222. long m_vector_start; ///< Highest member of a vector bus
  223. long m_vector_end; ///< Lowest member of a vector bus
  224. ///< Prefix name of the vector, if m_type == CONNECTION_BUS (or "" if not)
  225. wxString m_vector_prefix;
  226. /**
  227. * For bus connections, store a list of member connections
  228. *
  229. * NOTE: All connections that Clone() others share the list of member
  230. * pointers. This seems fine at the moment.
  231. */
  232. std::vector< std::shared_ptr< SCH_CONNECTION > > m_members;
  233. /**
  234. * Pointer to the connection graph for the schematic this connection exists on.
  235. * Needed for bus alias lookups.
  236. */
  237. CONNECTION_GRAPH* m_graph;
  238. };
  239. #endif