KiCad PCB EDA Suite
Loading...
Searching...
No Matches
text_var_dependency.h
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
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU 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, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 */
20
21#ifndef TEXT_VAR_DEPENDENCY_H_
22#define TEXT_VAR_DEPENDENCY_H_
23
24#include <kicommon.h>
25#include <cstdint>
26#include <functional>
27#include <initializer_list>
28#include <shared_mutex>
29#include <unordered_map>
30#include <unordered_set>
31#include <vector>
32#include <wx/string.h>
33
34
35class EDA_ITEM;
36class EDA_TEXT;
37
38
48{
83
85 wxString primary;
86 wxString secondary;
87
88 bool operator==( const TEXT_VAR_REF_KEY& ) const = default;
89
99 static TEXT_VAR_REF_KEY FromToken( const wxString& aToken );
100
101 bool IsTrackable() const { return kind != KIND::OP; }
102};
103
104
110KICOMMON_API std::vector<TEXT_VAR_REF_KEY> FilterTrackable(
111 const std::vector<TEXT_VAR_REF_KEY>& aRefs );
112
113
115{
116 std::size_t operator()( const TEXT_VAR_REF_KEY& aKey ) const;
117};
118
119
128{
129public:
131
136 void Register( EDA_ITEM* aItem, const std::vector<TEXT_VAR_REF_KEY>& aKeys );
137
142 void Unregister( EDA_ITEM* aItem );
143
150 void ForEachDependent( const TEXT_VAR_REF_KEY& aKey,
151 const std::function<void( EDA_ITEM* )>& aFn ) const;
152
156 void Clear();
157
158 std::size_t DependentCount( const TEXT_VAR_REF_KEY& aKey ) const;
159 std::size_t ItemCount() const;
160
167 std::vector<TEXT_VAR_REF_KEY> GetRegisteredKeys() const;
168
169private:
170 mutable std::shared_mutex m_mutex;
171
172 std::unordered_map<TEXT_VAR_REF_KEY,
173 std::unordered_set<EDA_ITEM*>,
175
176 std::unordered_map<EDA_ITEM*, std::vector<TEXT_VAR_REF_KEY>> m_itemKeys;
177};
178
179
195{
196public:
204 using SourceKeyExtractor = std::function<std::vector<TEXT_VAR_REF_KEY>( EDA_ITEM* )>;
205
211 using InvalidateCallback = std::function<void( EDA_ITEM* aDependent,
212 const TEXT_VAR_REF_KEY& aKey )>;
213
218 using ListenerHandle = std::size_t;
219 static constexpr ListenerHandle INVALID_LISTENER = 0;
220
221 explicit TEXT_VAR_TRACKER( SourceKeyExtractor aSourceKeyExtractor = {} );
222
224 const TEXT_VAR_DEPENDENCY_INDEX& Index() const { return m_index; }
225
226 void SetSourceKeyExtractor( SourceKeyExtractor aExtractor );
227
236 [[nodiscard]] ListenerHandle AddInvalidateListener( InvalidateCallback aCallback );
237
242 void RemoveInvalidateListener( ListenerHandle aHandle );
243
250 void RegisterItem( EDA_ITEM* aItem, const std::vector<TEXT_VAR_REF_KEY>& aKeys );
251
255 void UnregisterItem( EDA_ITEM* aItem );
256
262 void HandleItemChanged( EDA_ITEM* aItem, const std::vector<TEXT_VAR_REF_KEY>& aUpdatedKeys );
263
268 void InvalidateKey( const TEXT_VAR_REF_KEY& aKey );
269
276 void InvalidateByKind( std::initializer_list<TEXT_VAR_REF_KEY::KIND> aKinds );
277
285 void InvalidateProjectScoped();
286
293 void InvalidateVariantScoped();
294
295 void Clear() { m_index.Clear(); }
296
297private:
298 void fanOutSourceKeys( EDA_ITEM* aItem );
299
302
303 // m_invalidateListeners is read from InvalidateKey (possibly re-entrantly
304 // via a callback that triggers another invalidation) and mutated by
305 // Add/RemoveInvalidateListener. A shared_mutex protects both paths and
306 // is held only long enough to snapshot the callbacks before invoking
307 // them unlocked.
308 mutable std::shared_mutex m_listenersMutex;
309 std::unordered_map<ListenerHandle, InvalidateCallback> m_invalidateListeners;
311};
312
313
314#endif // TEXT_VAR_DEPENDENCY_H_
A base class for most all the KiCad significant classes used in schematics and boards.
Definition eda_item.h:100
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition eda_text.h:93
Bidirectional index mapping TEXT_VAR_REF_KEY → dependent items and item → keys.
std::vector< TEXT_VAR_REF_KEY > GetRegisteredKeys() const
Enumerate every key currently present in the forward index.
std::unordered_map< TEXT_VAR_REF_KEY, std::unordered_set< EDA_ITEM * >, TEXT_VAR_REF_KEY_HASH > m_dependents
void Clear()
Drop every entry.
std::size_t DependentCount(const TEXT_VAR_REF_KEY &aKey) const
void Register(EDA_ITEM *aItem, const std::vector< TEXT_VAR_REF_KEY > &aKeys)
Replace the key set for aItem with aKeys.
std::unordered_map< EDA_ITEM *, std::vector< TEXT_VAR_REF_KEY > > m_itemKeys
TEXT_VAR_DEPENDENCY_INDEX()=default
void Unregister(EDA_ITEM *aItem)
Remove aItem from the index entirely.
void ForEachDependent(const TEXT_VAR_REF_KEY &aKey, const std::function< void(EDA_ITEM *)> &aFn) const
Invoke aFn exactly once per item registered under aKey.
SourceKeyExtractor m_extractSourceKeys
std::function< void(EDA_ITEM *aDependent, const TEXT_VAR_REF_KEY &aKey)> InvalidateCallback
Called when a dependent item should recompute its resolved text.
std::unordered_map< ListenerHandle, InvalidateCallback > m_invalidateListeners
TEXT_VAR_DEPENDENCY_INDEX m_index
const TEXT_VAR_DEPENDENCY_INDEX & Index() const
std::size_t ListenerHandle
Opaque handle returned by AddInvalidateListener and consumed by RemoveInvalidateListener.
TEXT_VAR_TRACKER(SourceKeyExtractor aSourceKeyExtractor={})
ListenerHandle m_nextListenerHandle
TEXT_VAR_DEPENDENCY_INDEX & Index()
std::function< std::vector< TEXT_VAR_REF_KEY >(EDA_ITEM *)> SourceKeyExtractor
Return the keys aItem could source as a cross-reference target.
static constexpr ListenerHandle INVALID_LISTENER
std::shared_mutex m_listenersMutex
#define KICOMMON_API
Definition kicommon.h:27
std::size_t operator()(const TEXT_VAR_REF_KEY &aKey) const
Identifies a single resolvable source that a text item's ${...} reference depends on.
static TEXT_VAR_REF_KEY FromToken(const wxString &aToken)
Parse a raw token (the text between ${ and }) into a key using lexical classification only — no looku...
KIND
Categorizes a reference by the source that will produce its value.
bool operator==(const TEXT_VAR_REF_KEY &) const =default
KICOMMON_API std::vector< TEXT_VAR_REF_KEY > FilterTrackable(const std::vector< TEXT_VAR_REF_KEY > &aRefs)
Filter aRefs down to the subset that should be registered in the index (drops OP and any future non-t...