KiCad PCB EDA Suite
Loading...
Searching...
No Matches
conn_engine.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 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
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20#include "conn_engine.h"
21#include "conn_tasks.h"
22#include <wx/thread.h>
23#include <algorithm>
24
25namespace SCH_CONNECTIVITY
26{
36
37void ENGINE::Update( const SCH_SHEET_LIST& aPaths, uint64_t aTextEpoch, const BUS_ALIASES& aAliases, bool aRebuild )
38{
39 wxASSERT( wxThread::IsMain() );
40
41 try
42 {
43 if( aRebuild )
44 clearStages( true );
45
46 const auto frame = m_inputs.Capture( aPaths, aTextEpoch );
47 m_records.Update( frame, m_inputs, aAliases );
48 const auto& records = m_records.Records();
49 const auto bundles = m_partitioner.Build( RecordNodes( records, KIND::BUNDLE, m_keys ), m_keys );
50 m_bundles.UpdateBatch( bundles, [&]( const auto& missing )
51 {
52 std::vector<BUNDLE_INPUT> inputs;
53 inputs.reserve( missing.size() );
54
55 for( const PARTITION* partition : missing )
56 inputs.push_back( PrepareBundle( *partition, records, m_keys ) );
57
58 std::vector<BUNDLE_BINDING> values( missing.size() );
59 ParallelFor( values.size(), [&]( size_t i ) { values[i] = BindBundle( inputs[i], m_keys ); } );
60 return values;
61 } );
62 m_slots.Update( m_bundles );
63 const auto signals = m_partitioner.Build( SignalNodes( records, m_slots.Slots(), m_keys ), m_keys );
64 m_signals.UpdateBatch( signals, [&]( const auto& missing )
65 {
66 std::vector<SIGNAL_RESULT> values( missing.size() );
67 ParallelFor( values.size(), [&]( size_t i )
68 {
69 values[i] = DeriveSignal( *missing[i], records, m_slots.Slots(), m_keys );
70 } );
71 return values;
72 } );
73 m_published.Update( m_bundles, m_signals, records, frame, m_inputs );
74 }
75 catch( ... )
76 {
77 Clear();
78 throw;
79 }
80}
81
82std::vector<CLAIM> ENGINE::DriverCandidates( NODE_ID aComponent ) const
83{
84 wxASSERT( wxThread::IsMain() );
85 const auto component = m_published.Components().find( aComponent );
86
87 if( component == m_published.Components().end() )
88 return {};
89
90 const auto& content = *component->second.content;
91 std::vector<CLAIM> result;
92
93 for( const RECORD_KEY& record : content.records )
94 {
95 const auto& claims = m_records.Records().Entries().at( record )->value.claims;
96
97 for( const CLAIM& claim : claims )
98 {
99 if( content.kind == KIND::SIGNAL || claim.schema )
100 result.push_back( claim );
101 }
102 }
103
104 if( content.kind == KIND::SIGNAL )
105 {
106 for( const SLOT_KEY& slot : content.slots )
107 result.push_back( m_slots.Slots().Entries().at( slot )->value.claim );
108 }
109
110 const CLAIM_LESS less{ m_keys };
111 std::stable_sort( result.begin(), result.end(), [&]( const CLAIM& a, const CLAIM& b ) { return less( b, a ); } );
112 return result;
113}
114
116{
117 wxASSERT( wxThread::IsMain() );
118 clearStages();
119 m_published.Clear();
120}
121
122void ENGINE::clearStages( bool aRetainSourceValues )
123{
124 m_signals.Clear();
125 m_slots.Clear();
126 m_bundles.Clear();
127 m_records.Clear();
128
129 if( aRetainSourceValues )
130 m_inputs.Invalidate();
131 else
132 m_inputs.Clear();
133}
134} // namespace SCH_CONNECTIVITY
COMPONENT_CACHE< SIGNAL_RESULT > m_signals
void clearStages(bool aRetainSourceValues=false)
void Update(const SCH_SHEET_LIST &aPaths, uint64_t aTextEpoch, const BUS_ALIASES &aAliases, bool aRebuild=false)
Refresh inputs, bundle slots and signal summaries with the source text epoch and effective aliases.
COMPONENT_CACHE< BUNDLE_BINDING > m_bundles
std::vector< CLAIM > DriverCandidates(NODE_ID aComponent) const
Owned eligible claims of one published component, strongest first.
CACHE_VERSIONS m_versions
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
Value keys and the key session of the schematic connectivity engine.
std::map< wxString, std::vector< wxString > > BUS_ALIASES
Bus alias table, from alias name to member texts.
Definition conn_bus.h:40
BUNDLE_INPUT PrepareBundle(const PARTITION &aPartition, const RECORD_STORE::RECORD_CACHE &aRecords, SESSION_KEYS &aKeys)
Collect the bus claims of a bundle partition and intern their leaf names on the main thread.
void ParallelFor(size_t aCount, FUNCTION &&aFunction, thread_pool &aPool=GetKiCadThreadPool())
Independent ordinal writes only; preparation and cache commits stay on the caller thread.
Definition conn_tasks.h:72
uint32_t NODE_ID
Session handle of a NODE_KEY graph node.
Definition conn_keys.h:43
std::vector< NODE_INPUT > SignalNodes(const RECORD_STORE::RECORD_CACHE &aRecords, const SLOT_STORE::SLOT_CACHE &aSlots, SESSION_KEYS &aKeys)
Main-thread interning of current signal records and slots for the signal fold.
std::vector< NODE_INPUT > RecordNodes(const RECORD_STORE::RECORD_CACHE &aRecords, KIND aKind, SESSION_KEYS &aKeys)
Main-thread node interning for one record stratum.
Strict weak order on claims by value.
Definition conn_claims.h:77
The claim of one item for the name of its island.
Definition conn_claims.h:53
Exact identity of one connected component.
One island in one sheet instance.
Definition conn_keys.h:87
One member position of a bus.
Definition conn_keys.h:127
wxString result
Test unit parsing edge cases and error handling.