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, see <https://www.gnu.org/licenses/>.
18 */
19
20#ifndef TEXT_VAR_DEPENDENCY_H_
21#define TEXT_VAR_DEPENDENCY_H_
22
23#include <kicommon.h>
24#include <cstdint>
25#include <functional>
26#include <initializer_list>
27#include <shared_mutex>
28#include <unordered_map>
29#include <unordered_set>
30#include <vector>
31#include <wx/string.h>
32
33
34class EDA_ITEM;
35class EDA_TEXT;
36
37
47{
82
84 wxString primary;
85 wxString secondary;
86
87 bool operator==( const TEXT_VAR_REF_KEY& ) const = default;
88
98 static TEXT_VAR_REF_KEY FromToken( const wxString& aToken );
99
100 bool IsTrackable() const { return kind != KIND::OP; }
101};
102
103
109KICOMMON_API std::vector<TEXT_VAR_REF_KEY> FilterTrackable(
110 const std::vector<TEXT_VAR_REF_KEY>& aRefs );
111
112
114{
115 std::size_t operator()( const TEXT_VAR_REF_KEY& aKey ) const;
116};
117
118
127{
128public:
130
135 void Register( EDA_ITEM* aItem, const std::vector<TEXT_VAR_REF_KEY>& aKeys );
136
141 void Unregister( EDA_ITEM* aItem );
142
149 void ForEachDependent( const TEXT_VAR_REF_KEY& aKey,
150 const std::function<void( EDA_ITEM* )>& aFn ) const;
151
155 void Clear();
156
157 std::size_t DependentCount( const TEXT_VAR_REF_KEY& aKey ) const;
158 std::size_t ItemCount() const;
159
166 std::vector<TEXT_VAR_REF_KEY> GetRegisteredKeys() const;
167
168private:
169 mutable std::shared_mutex m_mutex;
170
171 std::unordered_map<TEXT_VAR_REF_KEY,
172 std::unordered_set<EDA_ITEM*>,
174
175 std::unordered_map<EDA_ITEM*, std::vector<TEXT_VAR_REF_KEY>> m_itemKeys;
176};
177
178
194{
195public:
203 using SourceKeyExtractor = std::function<std::vector<TEXT_VAR_REF_KEY>( EDA_ITEM* )>;
204
210 using InvalidateCallback = std::function<void( EDA_ITEM* aDependent,
211 const TEXT_VAR_REF_KEY& aKey )>;
212
217 using ListenerHandle = std::size_t;
218 static constexpr ListenerHandle INVALID_LISTENER = 0;
219
220 explicit TEXT_VAR_TRACKER( SourceKeyExtractor aSourceKeyExtractor = {} );
221
223 const TEXT_VAR_DEPENDENCY_INDEX& Index() const { return m_index; }
224
225 void SetSourceKeyExtractor( SourceKeyExtractor aExtractor );
226
235 [[nodiscard]] ListenerHandle AddInvalidateListener( InvalidateCallback aCallback );
236
241 void RemoveInvalidateListener( ListenerHandle aHandle );
242
249 void RegisterItem( EDA_ITEM* aItem, const std::vector<TEXT_VAR_REF_KEY>& aKeys );
250
254 void UnregisterItem( EDA_ITEM* aItem );
255
261 void HandleItemChanged( EDA_ITEM* aItem, const std::vector<TEXT_VAR_REF_KEY>& aUpdatedKeys );
262
267 void InvalidateKey( const TEXT_VAR_REF_KEY& aKey );
268
275 void InvalidateByKind( std::initializer_list<TEXT_VAR_REF_KEY::KIND> aKinds );
276
284 void InvalidateProjectScoped();
285
292 void InvalidateVariantScoped();
293
294 void Clear() { m_index.Clear(); }
295
296private:
297 void fanOutSourceKeys( EDA_ITEM* aItem );
298
301
302 // m_invalidateListeners is read from InvalidateKey (possibly re-entrantly
303 // via a callback that triggers another invalidation) and mutated by
304 // Add/RemoveInvalidateListener. A shared_mutex protects both paths and
305 // is held only long enough to snapshot the callbacks before invoking
306 // them unlocked.
307 mutable std::shared_mutex m_listenersMutex;
308 std::unordered_map<ListenerHandle, InvalidateCallback> m_invalidateListeners;
310};
311
312
313#endif // TEXT_VAR_DEPENDENCY_H_
A base class for most all the KiCad significant classes used in schematics and boards.
Definition eda_item.h:96
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition eda_text.h:89
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...