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.

153 lines
6.8 KiB

  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 modify it
  7. * under the terms of the GNU General Public License as published by the
  8. * Free Software Foundation, either version 3 of the License, or (at your
  9. * option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #ifndef PCBNEW_COMPONENT_CLASS_MANAGER_H
  20. #define PCBNEW_COMPONENT_CLASS_MANAGER_H
  21. #include <unordered_map>
  22. #include <unordered_set>
  23. #include <wx/string.h>
  24. #include <component_classes/component_class.h>
  25. #include <project/component_class_settings.h>
  26. class BOARD;
  27. class COMPONENT_CLASS_ASSIGNMENT_RULE;
  28. class DRC_TOOL;
  29. class FOOTPRINT;
  30. /**
  31. * A class to manage Component Classes in a board context
  32. *
  33. * This manager owns generated COMPONENT_CLASS objects, and guarantees that pointers to managed
  34. * objects are valid for the duration of the board lifetime. Note that, in order to maintain this
  35. * guarantee, there are two methods that must be called when updating the board from the netlist
  36. * (InitNetlistUpdate and FinishNetlistUpdate).
  37. */
  38. class COMPONENT_CLASS_MANAGER
  39. {
  40. public:
  41. explicit COMPONENT_CLASS_MANAGER( BOARD* board );
  42. /// @brief Gets the full effective class name for the given set of constituent classes
  43. static wxString
  44. GetFullClassNameForConstituents( const std::unordered_set<wxString>& classNames );
  45. /// @brief Gets the full effective class name for the given set of constituent classes
  46. /// @param classNames a sorted vector of consituent class names
  47. static wxString GetFullClassNameForConstituents( const std::vector<wxString>& classNames );
  48. /// @brief Gets an effective component class for the given constituent class names
  49. /// @param classNames The names of the constituent component classes
  50. /// @return Effective COMPONENT_CLASS object
  51. COMPONENT_CLASS*
  52. GetEffectiveStaticComponentClass( const std::unordered_set<wxString>& classNames );
  53. /// Returns the unassigned component class
  54. const COMPONENT_CLASS* GetNoneComponentClass() const { return m_noneClass.get(); }
  55. /// Prepare the manager for a board update
  56. /// Must be called prior to updating the PCB from the netlist
  57. void InitNetlistUpdate();
  58. /// Cleans up the manager after a board update
  59. /// Must be called after updating the PCB from the netlist
  60. void FinishNetlistUpdate();
  61. /// Fetches a read-only map of the fundamental component classes
  62. std::unordered_set<wxString> GetClassNames() const;
  63. /// Synchronises all dynamic component class assignment rules
  64. /// @returns false if rules fail to parse, true if successful
  65. bool SyncDynamicComponentClassAssignments(
  66. const std::vector<COMPONENT_CLASS_ASSIGNMENT_DATA>& aAssignments,
  67. bool aGenerateSheetClasses, const std::unordered_set<wxString>& aNewSheetPaths );
  68. /// Gets the dynamic component classes which match the given footprint
  69. const COMPONENT_CLASS* GetDynamicComponentClassesForFootprint( const FOOTPRINT* footprint );
  70. /// Gets the combined component class with the given static and dynamic constituent component classes
  71. const COMPONENT_CLASS* GetCombinedComponentClass( const COMPONENT_CLASS* staticClass,
  72. const COMPONENT_CLASS* dynamicClass );
  73. /// Forces the component class for all footprints to be recalculated. This should be called before running DRC as
  74. /// checking for valid component class cache entries is threadsafe, but computing them is not. Blocking during this
  75. /// check would be a negative performance impact for DRC computation, so we force recalculation instead.
  76. void ForceComponentClassRecalculation() const;
  77. /// Gets the component class validity ticker
  78. /// Used to check validity of cached component classes
  79. long long int GetTicker() const { return m_ticker; }
  80. /// Invalidates any caches component classes and recomputes caches if required. This will force
  81. /// recomputation of component classes on next access
  82. void InvalidateComponentClasses();
  83. /// Rebuilds any caches that may be required by custom assignment rules
  84. /// @param fp the footprint to rebuild. If null, rebuilds all footprint caches
  85. void RebuildRequiredCaches( FOOTPRINT* aFootprint = nullptr ) const;
  86. /// Determines whether any custom dynamic rules have a custom assignment condition
  87. bool HasCustomAssignmentConditions() const { return m_hasCustomAssignmentConditions; }
  88. static std::shared_ptr<COMPONENT_CLASS_ASSIGNMENT_RULE>
  89. CompileAssignmentRule( const COMPONENT_CLASS_ASSIGNMENT_DATA& aAssignment );
  90. protected:
  91. /// Sorts the given class names in to canonical order
  92. static std::vector<wxString> sortClassNames( const std::unordered_set<wxString>& classNames );
  93. /// Returns a constituent component class, re-using an existing instantiation where possible
  94. COMPONENT_CLASS* getOrCreateConstituentClass( const wxString& aClassName,
  95. COMPONENT_CLASS::USAGE aContext );
  96. /// Returns an effective component class for the given set of constituent class names
  97. /// Precondition: aClassNames is sorted by sortClassNames
  98. COMPONENT_CLASS* getOrCreateEffectiveClass( const std::vector<wxString>& aClassNames,
  99. COMPONENT_CLASS::USAGE aContext );
  100. /// The board these component classes are assigned to / from
  101. BOARD* m_board;
  102. /// The class to represent an unassigned component class
  103. std::shared_ptr<COMPONENT_CLASS> m_noneClass;
  104. /// All individual component classes from static assignments
  105. std::unordered_map<wxString, std::unique_ptr<COMPONENT_CLASS>> m_constituentClasses;
  106. /// Generated effective (composite) static component classes
  107. std::unordered_map<wxString, std::unique_ptr<COMPONENT_CLASS>> m_effectiveClasses;
  108. /// Cache of in-use static component class names
  109. /// Used for cleanup following netlist updates
  110. std::unordered_set<wxString> m_staticClassNamesCache;
  111. /// Active component class assignment rules
  112. std::vector<std::shared_ptr<COMPONENT_CLASS_ASSIGNMENT_RULE>> m_assignmentRules;
  113. /// Quick lookup of presence of custom dynamic assignment conditions
  114. bool m_hasCustomAssignmentConditions;
  115. /// Monotonically increasing ticker to test cached component class validity
  116. long long int m_ticker{ 0 };
  117. };
  118. #endif