/* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright The KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef PCBNEW_COMPONENT_CLASS_MANAGER_H #define PCBNEW_COMPONENT_CLASS_MANAGER_H #include #include #include #include #include class BOARD; class COMPONENT_CLASS_ASSIGNMENT_RULE; class DRC_TOOL; class FOOTPRINT; /** * A class to manage Component Classes in a board context * * This manager owns generated COMPONENT_CLASS objects, and guarantees that pointers to managed * objects are valid for the duration of the board lifetime. Note that, in order to maintain this * guarantee, there are two methods that must be called when updating the board from the netlist * (InitNetlistUpdate and FinishNetlistUpdate). */ class COMPONENT_CLASS_MANAGER { public: explicit COMPONENT_CLASS_MANAGER( BOARD* board ); /// @brief Gets the full effective class name for the given set of constituent classes static wxString GetFullClassNameForConstituents( const std::unordered_set& classNames ); /// @brief Gets the full effective class name for the given set of constituent classes /// @param classNames a sorted vector of consituent class names static wxString GetFullClassNameForConstituents( const std::vector& classNames ); /// @brief Gets an effective component class for the given constituent class names /// @param classNames The names of the constituent component classes /// @return Effective COMPONENT_CLASS object COMPONENT_CLASS* GetEffectiveStaticComponentClass( const std::unordered_set& classNames ); /// Returns the unassigned component class const COMPONENT_CLASS* GetNoneComponentClass() const { return m_noneClass.get(); } /// Prepare the manager for a board update /// Must be called prior to updating the PCB from the netlist void InitNetlistUpdate(); /// Cleans up the manager after a board update /// Must be called after updating the PCB from the netlist void FinishNetlistUpdate(); /// Fetches a read-only map of the fundamental component classes std::unordered_set GetClassNames() const; /// Synchronises all dynamic component class assignment rules /// @returns false if rules fail to parse, true if successful bool SyncDynamicComponentClassAssignments( const std::vector& aAssignments, bool aGenerateSheetClasses, const std::unordered_set& aNewSheetPaths ); /// Gets the dynamic component classes which match the given footprint const COMPONENT_CLASS* GetDynamicComponentClassesForFootprint( const FOOTPRINT* footprint ); /// Gets the combined component class with the given static and dynamic constituent component classes const COMPONENT_CLASS* GetCombinedComponentClass( const COMPONENT_CLASS* staticClass, const COMPONENT_CLASS* dynamicClass ); /// Forces the component class for all footprints to be recalculated. This should be called before running DRC as /// checking for valid component class cache entries is threadsafe, but computing them is not. Blocking during this /// check would be a negative performance impact for DRC computation, so we force recalculation instead. void ForceComponentClassRecalculation() const; /// Gets the component class validity ticker /// Used to check validity of cached component classes long long int GetTicker() const { return m_ticker; } /// Invalidates any caches component classes and recomputes caches if required. This will force /// recomputation of component classes on next access void InvalidateComponentClasses(); /// Rebuilds any caches that may be required by custom assignment rules /// @param fp the footprint to rebuild. If null, rebuilds all footprint caches void RebuildRequiredCaches( FOOTPRINT* aFootprint = nullptr ) const; /// Determines whether any custom dynamic rules have a custom assignment condition bool HasCustomAssignmentConditions() const { return m_hasCustomAssignmentConditions; } static std::shared_ptr CompileAssignmentRule( const COMPONENT_CLASS_ASSIGNMENT_DATA& aAssignment ); protected: /// Sorts the given class names in to canonical order static std::vector sortClassNames( const std::unordered_set& classNames ); /// Returns a constituent component class, re-using an existing instantiation where possible COMPONENT_CLASS* getOrCreateConstituentClass( const wxString& aClassName, COMPONENT_CLASS::USAGE aContext ); /// Returns an effective component class for the given set of constituent class names /// Precondition: aClassNames is sorted by sortClassNames COMPONENT_CLASS* getOrCreateEffectiveClass( const std::vector& aClassNames, COMPONENT_CLASS::USAGE aContext ); /// The board these component classes are assigned to / from BOARD* m_board; /// The class to represent an unassigned component class std::shared_ptr m_noneClass; /// All individual component classes from static assignments std::unordered_map> m_constituentClasses; /// Generated effective (composite) static component classes std::unordered_map> m_effectiveClasses; /// Cache of in-use static component class names /// Used for cleanup following netlist updates std::unordered_set m_staticClassNamesCache; /// Active component class assignment rules std::vector> m_assignmentRules; /// Quick lookup of presence of custom dynamic assignment conditions bool m_hasCustomAssignmentConditions; /// Monotonically increasing ticker to test cached component class validity long long int m_ticker{ 0 }; }; #endif