39 template <
typename ROW,
typename TABLE,
typename KEY_OF>
40 void ReplaceRows(
const std::vector<ROW>& aPrevious,
const std::vector<ROW>& aCurrent, TABLE& aTable,
43 [[maybe_unused]]
const auto unordered = [](
const ROW& a,
const ROW& b )
45 return !( a.id < b.id );
47 assert( std::adjacent_find( aPrevious.begin(), aPrevious.end(), unordered ) == aPrevious.end() );
48 assert( std::adjacent_find( aCurrent.begin(), aCurrent.end(), unordered ) == aCurrent.end() );
50 auto previous = aPrevious.begin();
52 for(
const ROW& row : aCurrent )
54 for( ; previous != aPrevious.end() && previous->id < row.id; ++previous )
55 aTable.Erase( aKeyOf( previous->id ) );
57 const bool matched = previous != aPrevious.end() && previous->id == row.id;
59 if( !matched || !( *previous == row ) )
60 aTable.Set( aKeyOf( row.id ), row );
66 for( ; previous != aPrevious.end(); ++previous )
67 aTable.Erase( aKeyOf( previous->id ) );
85 wxASSERT( wxThread::IsMain() );
89 throw std::logic_error(
"Cannot compare text sources during source collection" );
91 const bool checkReferences = !aContextUnchanged || std::ranges::any_of( aPaths,
105 const auto instance =
m_keys.FindInstance(
path.Path() );
107 if( !instance || !
path.LastScreen() )
112 if( input ==
m_instanceInputs.end() || input->second.screen !=
path.LastScreen()->ConnectivityId() )
115 const auto* sources =
Sources( *instance );
120 for(
const auto& [
name, previous] : sources->environmentVariables )
123 const bool found = wxGetEnv(
name, &value );
125 if( found != previous.has_value() || ( found && value != *previous ) )
129 if( sources->randomUsed )
135 if( checkReferences && !sources->crossReferences.empty() )
142 std::optional<TEXT_EVAL_VCS::CONTEXT_PATH_SCOPE> vcs;
147 vcs.emplace( projectPath );
150 for(
const auto& [key, value] : sources->crossReferences )
152 wxString
text = key.first;
160 for(
const auto& [file, hash] : sources->gitHashes )
167 if( current != hash )
171 for(
const auto& [key, value] : sources->vcsValues )
178 if( current != value )
188 wxASSERT( wxThread::IsMain() );
197 const auto* previous =
m_screens.Find(
id );
200 const auto libraries = unchanged ? previous->value.librarySymbols :
nullptr;
208 const auto* previous =
m_screens.Find(
id );
211 const auto keyOf = [&](
const KIID& item )
231 uint64_t aTextEpoch )
233 wxASSERT( wxThread::IsMain() );
236 throw std::invalid_argument(
"Connectivity instance does not refer to source screen" );
247 const auto* previous =
m_instances.Find( instance );
251 && stamp->second.symbolRevision == input.symbolRevision && stamp->second.screen == input.screen
252 && stamp->second.textEpoch == input.textEpoch && stamp->second.pageOrder == input.pageOrder
253 && previous->value.ruleAreas.empty() && source.
ruleAreas.empty() )
255 stamp->second = input;
270 const auto keyOf = [&](
const KIID& item )
292 wxASSERT( wxThread::IsMain() );
293 const auto* source =
m_screens.Find( aScreen );
296 throw std::invalid_argument(
"Connectivity geometry requires captured screen facts" );
320 wxASSERT( wxThread::IsMain() );
322 const auto& geometry =
Geometry( aScreen );
326 if( stamp !=
m_islandInputs.end() && stamp->second == geometry.version )
347 wxASSERT( wxThread::IsMain() );
351 std::map<INST_ID, const SCH_SHEET_PATH*> paths;
355 if( !
path.empty() &&
path.LastScreen() )
359 std::set<SCREEN_ID> screens;
360 std::set<INST_ID> instances;
366 screens.insert( item.screen );
367 instances.insert( item.scope.instance );
373 const GEOMETRY_CACHE::ENTRY* geometry;
375 std::vector<ISLAND_JOB> jobs;
376 std::set<ISLAND_KEY, ISLAND_LESS> seen;
380 const auto& units =
m_instances.Find( item.scope.instance )->value.units;
383 if( !seen.insert( key ).second )
386 const auto& geometry =
Geometry( item.screen );
389 if( stamp ==
m_islandInputs.end() || stamp->second != geometry.version )
390 jobs.push_back( { std::move( key ), &geometry } );
393 std::vector<SCREEN_ISLANDS> results( jobs.size() );
399 results[i] = BuildScreenIslands( jobs[i].geometry->value, jobs[i].key.second );
402 for(
size_t i = 0; i < jobs.size(); ++i )
404 m_islands.Set( jobs[i].key, std::move( results[i] ) );
405 m_islandInputs.insert_or_assign( jobs[i].key, jobs[i].geometry->version );
414 Retain( screens, instances );
421 wxASSERT( wxThread::IsMain() );
444 wxASSERT( wxThread::IsMain() );
446 std::set<ISLAND_LOOKUP, ISLAND_LESS> liveIslands;
453 if( aInstances.contains(
id ) && input !=
m_instanceInputs.end() && aScreens.contains( input->second.screen ) )
455 liveIslands.emplace( input->second.screen, it->second->value.units );
460 for(
const auto& row : it->second->value.items )
461 m_text.Erase( { row.id,
id } );
463 for(
const auto& row : it->second->value.ruleAreas )
464 m_areas.Erase( { row.id,
id } );
476 if( aScreens.contains(
id ) )
482 for(
const auto& row : it->second->value.items )
483 m_facts.Erase( { id, row.id } );
495 if( liveIslands.contains( it->first ) )
501 const auto removed = it++;
static wxString GetCurrentHash(const wxString &aProjectFile, bool aShort)
Return the current HEAD commit hash for the repository containing aProjectFile.
virtual const wxString GetProjectPath() const
Return the full path of the project.
Holds all the data relating to one schematic.
PROJECT & Project() const
Return a reference to the project this schematic is part of.
bool IsValid() const
A simple test if the schematic is loaded, not a complete one.
bool ResolveCrossReference(wxString *token, int aDepth) const
Resolves text vars that refer to other items.
One sequence for all cache tables for the lifetime of an engine session.
Excludes derived graph text and shares dynamic source values through nested resolvers.
Session IDs are dense handles, never a canonical ordering.
uint64_t ConnectivityId() const
Process-local lifetime identity; file UUIDs can be shared by distinct screens.
uint64_t ConnectivityRevision() const
The only change signal that the connectivity engine reads from this screen.
uint64_t ConnectivitySymbolRevision() const
Changes with every bump except a wire-only bump, so wire edits keep cached text.
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
SCH_SCREEN * LastScreen()
int GetVirtualPageNumber() const
static wxDateTime CurrentTime()
const VCS_VALUE & VcsValue(const VCS_KEY &aKey, const std::function< VCS_VALUE()> &aRead)
const wxString & GitHash(const wxString &aPath, const std::function< wxString()> &aRead)
Return the value memoized for this frame.
static ENVIRONMENT * Current()
Record every source read through aEnvironment into aValues, including memo hits.
static bool empty(const wxTextEntryBase *aCtrl)
Value keys and the key session of the schematic connectivity engine.
INSTANCE_FACTS ExtractInstanceFacts(const SCREEN_FACTS &aFacts, const SCH_SCREEN &aScreen, const SCH_SHEET_PATH &aPath)
uint32_t INST_ID
Session handle of a sheet instance KIID_PATH.
void ParallelFor(size_t aCount, FUNCTION &&aFunction, thread_pool &aPool=GetKiCadThreadPool())
Independent ordinal writes only; preparation and cache commits stay on the caller thread.
uint64_t SCREEN_ID
Process-local SCH_SCREEN::ConnectivityId(), never a file UUID.
SCREEN_GEOMETRY GeometryOf(const SCREEN_FACTS &aFacts)
SCREEN_FACTS ExtractScreenFacts(const SCH_SCREEN &aScreen, std::shared_ptr< const LIBRARY_SYMBOL_FACTS > aLibrarySymbols, const SCREEN_FACTS *aUnchangedNonLines)
Main-thread snapshots; no derived connectivity or model pointers survive extraction.
SCREEN_ISLANDS BuildScreenIslands(const SCREEN_GEOMETRY &aFacts, const std::vector< std::pair< KIID, int > > &aUnits)
Kindless geometry for one unit signature.
std::vector< FRAME_INSTANCE > CaptureHierarchy(const SCH_SHEET_LIST &aPaths, SESSION_KEYS &aKeys)
Interns every sheet instance and returns the frame in KIID_PATH order, so each parent precedes its ch...
TEXT_EVAL::ENVIRONMENT::VCS_VALUE ReadSource(const TEXT_EVAL::ENVIRONMENT::VCS_KEY &aKey)
Re-read an owned query descriptor using any active frame memo.
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
One entry of the captured hierarchy.
The text and unit data that one sheet instance resolves for the items of its screen.
std::vector< INSTANCE_RULE_AREA_FACT > ruleAreas
std::vector< ITEM_TEXT_FACT > items
One item or pin in one sheet instance.
Orders keys by value through SESSION_KEYS::Less().
The value copy of one screen.
std::vector< ITEM_FACT > items
std::vector< RULE_AREA_FACT > ruleAreas
The islands of one screen and unit signature, sorted by anchor.
wxString result
Test unit parsing edge cases and error handling.