40 wxASSERT( wxThread::IsMain() );
43 const bool aliasesChanged =
m_parses.SetAliases( aAliases );
44 bool claimNamesChanged =
false;
45 std::vector<const SOURCE_CACHE::ENTRY*> sources;
47 std::set<INST_ID> liveInstances;
48 std::set<INST_ID> changedInstances;
49 std::set<RECORD_KEY, RECORD_ORDER> liveRecords;
57 std::vector<RECORD_JOB> jobs;
58 const auto eraseSource = [&](
const ITEM_KEY& key )
60 if( !claimNamesChanged )
62 const auto* source =
m_sources.Find( key );
63 claimNamesChanged = source && source->value.claim.has_value();
71 const INST_ID instance = frame.scope.instance;
73 if( !liveInstances.insert( instance ).second )
74 throw std::invalid_argument(
"Duplicate connectivity frame instance" );
76 const auto* facts = aInputs.
FindScreen( frame.screen );
80 throw std::invalid_argument(
"Connectivity frame inputs were not captured" );
84 const bool instanceChanged = old ==
m_prepared.end() || aliasesChanged
85 || old->second.sourceVersion != facts->version
86 || old->second.textVersion !=
text->version
87 || old->second.scope != frame.scope;
89 if( !instanceChanged )
93 const bool reuseClaims = old !=
m_prepared.end() && symbolSource
94 && old->second.symbolSource == symbolSource && !aliasesChanged
95 && old->second.textVersion ==
text->version && old->second.scope == frame.scope
96 && facts->value.ruleAreas.empty() &&
text->value.ruleAreas.empty()
97 && old->second.factCount == facts->value.items.size()
98 && std::ranges::all_of( facts->value.items, [&](
const ITEM_FACT& fact )
100 if( fact.type != SCH_LINE_T )
103 const auto* source = m_sources.Find( { fact.id, instance } );
104 return source && source->value.type ==
SCH_LINE_T;
110 old->second.sourceVersion = facts->version;
116 facts->value.items.size(), {} };
117 stamp.
items.reserve( prepared.items.size() );
119 for(
auto& [
id, source] : prepared.items )
121 if( !claimNamesChanged )
123 const auto* previous =
m_sources.Find( { id, instance } );
124 const auto* oldClaim = previous && previous->value.claim ? &*previous->value.claim :
nullptr;
125 claimNamesChanged = source.claim ? !oldClaim || source.claim->name != oldClaim->name
126 : oldClaim !=
nullptr;
129 m_sources.Set( { id, instance }, std::move( source ) );
130 stamp.items.push_back(
id );
135 for(
const KIID&
id : old->second.items )
137 if( !std::binary_search( stamp.items.begin(), stamp.items.end(),
id ) )
138 eraseSource( { id, instance } );
142 m_prepared.insert_or_assign( instance, std::move( stamp ) );
145 changedInstances.insert( instance );
146 const auto& islands = aInputs.
Islands( frame.screen,
text->value.units ).value;
148 for(
const ISLAND& island : islands.islands )
150 const RECORD_KEY key{ instance, island.anchor };
152 if( !liveRecords.insert( key ).second )
153 throw std::logic_error(
"Duplicate connectivity island anchor" );
156 sources.reserve( island.items.size() );
157 input.hasWire = island.hasWire;
158 input.hasBusLine = island.hasBusLine;
160 input.items.reserve( island.items.size() );
162 for(
const KIID&
id : island.items )
164 const auto* source =
m_sources.Find( { id, instance } );
167 throw std::logic_error(
"Connectivity island source was not prepared" );
169 sources.push_back( source );
170 input.items.emplace_back(
id, source->version );
175 if( previous !=
m_recordInputs.end() && previous->second == input )
181 for(
size_t i = 0; i < island.items.size(); ++i )
182 claims.
items.emplace( island.items[i], sources[i]->value );
184 jobs.push_back( { key, input, { island.items, input.hasWire, input.hasBusLine },
185 std::move( claims ) } );
189 std::vector<ISLAND_RECORD> results( jobs.size() );
192 results[i] = BuildIslandRecord( jobs[i].geometry, jobs[i].claims, m_keys );
195 for(
size_t i = 0; i < jobs.size(); ++i )
197 m_records.Set( jobs[i].key, std::move( results[i] ) );
198 m_recordInputs.insert_or_assign( jobs[i].key, std::move( jobs[i].input ) );
203 if( liveInstances.contains( it->first ) )
209 for(
const KIID&
id : it->second.items )
210 eraseSource( { id, it->first } );
217 if( ( liveInstances.contains( it->first.inst ) && !changedInstances.contains( it->first.inst ) )
218 || liveRecords.contains( it->first ) )
228 if( claimNamesChanged )
230 std::set<wxString> liveText;
232 for(
const auto& [key, source] :
m_sources.Entries() )
234 if( source->value.claim )
235 liveText.insert(
m_keys.Name( source->value.claim->name ) );