KiCad PCB EDA Suite
Loading...
Searching...
No Matches
property_mgr.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 (C) 2020-2023 CERN
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * @author Tomasz Wlostowski <[email protected]>
8 * @author Maciej Suminski <[email protected]>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 3
13 * of the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 */
23
24#ifndef PROPERTY_MGR_H
25#define PROPERTY_MGR_H
26
27#include <core/wx_stl_compat.h> // Needed for stl hash extensions
28
29#include <wx/string.h>
30
31#include <algorithm>
32#include <functional>
33#include <list>
34#include <map>
35#include <unordered_map>
36#include <set>
37#include <vector>
38#include <memory>
39#include <eda_units.h>
40
41class PROPERTY_BASE;
42class TYPE_CAST_BASE;
44class INSPECTABLE;
45class COMMIT;
46
48using TYPE_ID = size_t;
49
50using PROPERTY_LISTENER = std::function<void( INSPECTABLE*, PROPERTY_BASE*, COMMIT* )>;
51
54using PROPERTY_LISTENER_HANDLE = std::size_t;
55
57{
58public:
60
62
63private:
64 bool m_ownsCommit = false;
65};
66
82{
83public:
85 {
86 static PROPERTY_MANAGER pm;
87 return pm;
88 }
89
98 void RegisterType( TYPE_ID aType, const wxString& aName );
99
107 PROPERTY_BASE* GetProperty( TYPE_ID aType, const wxString& aProperty ) const;
108
118 PROPERTY_BASE* GetProperty( const INSPECTABLE* aObject, const wxString& aProperty ) const;
119
126 const std::vector<PROPERTY_BASE*>& GetProperties( TYPE_ID aType ) const;
127
132 std::vector<PROPERTY_BASE*> GetProperties( const INSPECTABLE* aObject ) const;
133
138 std::vector<PROPERTY_BASE*> GetCommonDynamicProperties( const std::vector<const INSPECTABLE*>& aObjects ) const;
139
140 const std::map<PROPERTY_BASE*, int>& GetDisplayOrder( TYPE_ID aType ) const;
141
142 const std::vector<wxString>& GetGroupDisplayOrder( TYPE_ID aType ) const;
143
155 const void* TypeCast( const void* aSource, TYPE_ID aBase, TYPE_ID aTarget ) const;
156
157 void* TypeCast( void* aSource, TYPE_ID aBase, TYPE_ID aTarget ) const
158 {
159 return const_cast<void*>( TypeCast( (const void*) aSource, aBase, aTarget ) );
160 }
161
172 PROPERTY_BASE& AddProperty( PROPERTY_BASE* aProperty, const wxString& aGroup = wxEmptyString );
173
185 PROPERTY_BASE& ReplaceProperty( size_t aBase, const wxString& aName, PROPERTY_BASE* aNew,
186 const wxString& aGroup = wxEmptyString );
187
193 void AddTypeCast( TYPE_CAST_BASE* aCast );
194
201 void InheritsAfter( TYPE_ID aDerived, TYPE_ID aBase );
202
211 void Mask( TYPE_ID aDerived, TYPE_ID aBase, const wxString& aName );
212
221 void OverrideAvailability( TYPE_ID aDerived, TYPE_ID aBase, const wxString& aName,
222 std::function<bool( INSPECTABLE* )> aFunc );
223
232 void OverrideWriteability( TYPE_ID aDerived, TYPE_ID aBase, const wxString& aName,
233 std::function<bool( INSPECTABLE* )> aFunc );
234
241 bool IsAvailableFor( TYPE_ID aItemClass, PROPERTY_BASE* aProp, INSPECTABLE* aItem );
242
249 bool IsWriteableFor( TYPE_ID aItemClass, PROPERTY_BASE* aProp, INSPECTABLE* aItem );
250
254 bool IsOfType( TYPE_ID aDerived, TYPE_ID aBase ) const;
255
260 void Rebuild();
261
263 {
264 wxString name;
266 std::vector<PROPERTY_BASE*> properties;
267 };
268
269 std::vector<CLASS_INFO> GetAllClasses();
270
276 void PropertyChanged( INSPECTABLE* aObject, PROPERTY_BASE* aProperty );
277
284 [[nodiscard]] class PROPERTY_LISTENER_SUBSCRIPTION
285 RegisterListener( TYPE_ID aType, PROPERTY_LISTENER aListenerFunc );
286
297
298private:
300 m_dirty( false ),
301 m_managedCommit( nullptr )
302 {
303 }
304
305 // Explicit noexcept on this user-declared destructor short-circuits the
306 // implicit noexcept computation the compiler would otherwise perform by
307 // walking every member's destructor. That walk reaches the
308 // `std::map<wxString, std::unique_ptr<PROPERTY_BASE>>` member inside
309 // CLASS_DESC and, since this header only forward-declares PROPERTY_BASE
310 // / TYPE_CAST_BASE, fails with an "incomplete type" diagnostic at every
311 // TU that includes property_mgr.h. The destructor body in
312 // property_mgr.cpp sees the complete types via the property.h include
313 // there.
315
317
320 {
321 // Constructor body lives in property_mgr.cpp so it doesn't force
322 // every TU including this header to instantiate the destructors of
323 // `std::map<X, std::unique_ptr<PROPERTY_BASE>>` and
324 // `std::map<X, std::unique_ptr<TYPE_CAST_BASE>>` (which require
325 // complete PROPERTY_BASE / TYPE_CAST_BASE — only forward-declared
326 // here). Same applies to the destructor and the defaulted move
327 // operations.
328 CLASS_DESC( TYPE_ID aId );
329 ~CLASS_DESC() noexcept;
330 CLASS_DESC( CLASS_DESC&& ) noexcept;
331
334
336 std::vector<std::reference_wrapper<CLASS_DESC>> m_bases;
337
340
343
345 std::set<std::pair<size_t, wxString>> m_maskedBaseProperties;
346
348 std::map<std::pair<size_t, wxString>, std::function<bool( INSPECTABLE* )>> m_availabilityOverrides;
349
351 std::map<std::pair<size_t, wxString>, std::function<bool( INSPECTABLE* )>> m_writeabilityOverrides;
352
355
358
360 std::vector<wxString> m_groupDisplayOrder;
361
364
366 std::set<wxString> m_groups;
367
369 std::set<std::pair<size_t, wxString>> m_replaced;
370
372 void rebuild();
373
376 void collectPropsRecur( std::vector<PROPERTY_BASE*>& aResult,
377 std::set<std::pair<size_t, wxString>>& aReplaced,
378 std::map<PROPERTY_BASE*, int>& aDisplayOrder,
379 std::set<std::pair<size_t, wxString>>& aMasked ) const;
380 };
381
383 CLASS_DESC& getClass( TYPE_ID aTypeId );
384
385 std::unordered_map<TYPE_ID, wxString> m_classNames;
386
388 std::unordered_map<TYPE_ID, CLASS_DESC> m_classes;
389
392
393 std::map<TYPE_ID,
395
397
399};
400
401
403#define REGISTER_TYPE(x) PROPERTY_MANAGER::Instance().RegisterType(TYPE_HASH(x), TYPE_NAME(x))
404
405
412{
413public:
415
417 m_type( aType ),
418 m_handle( aHandle )
419 {
420 }
421
422 // Destructor + reset() are out-of-line so the chain reset() ->
423 // PROPERTY_MANAGER::UnregisterListener doesn't force consumers of this
424 // header to fully instantiate PROPERTY_MANAGER (which would require
425 // complete PROPERTY_BASE / TYPE_CAST_BASE for the unique_ptr members
426 // inside CLASS_DESC). Holders of this subscription as a class member
427 // (e.g. SCHEMATIC) therefore only see the declarations here, not the
428 // implicit PROPERTY_MANAGER destructor instantiation.
430
433
435 m_type( aOther.m_type ),
436 m_handle( aOther.m_handle )
437 {
438 aOther.m_handle = 0;
439 }
440
442
443 void reset();
444
445private:
448};
449
450
451#endif /* PROPERTY_MGR_H */
Represent a set of changes (additions, deletions or modifications) of a data model (e....
Definition commit.h:68
Class that other classes need to inherit from, in order to be inspectable.
Definition inspectable.h:39
A class to perform either relative or absolute display origin transforms for a single axis of a point...
PROPERTY_COMMIT_HANDLER(COMMIT *aCommit)
Move-only RAII wrapper around a single listener registration.
PROPERTY_LISTENER_HANDLE m_handle
PROPERTY_LISTENER_SUBSCRIPTION(PROPERTY_LISTENER_SUBSCRIPTION &&aOther) noexcept
PROPERTY_LISTENER_SUBSCRIPTION(const PROPERTY_LISTENER_SUBSCRIPTION &)=delete
PROPERTY_LISTENER_SUBSCRIPTION(TYPE_ID aType, PROPERTY_LISTENER_HANDLE aHandle)
PROPERTY_LISTENER_SUBSCRIPTION & operator=(const PROPERTY_LISTENER_SUBSCRIPTION &)=delete
const std::vector< PROPERTY_BASE * > & GetProperties(TYPE_ID aType) const
Return all properties for a specific type.
bool m_dirty
Flag indicating that the list of properties needs to be rebuild (RebuildProperties())
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declare an inheritance relationship between types.
bool IsWriteableFor(TYPE_ID aItemClass, PROPERTY_BASE *aProp, INSPECTABLE *aItem)
Checks overriden availability and original availability of a property, returns false if the property ...
void PropertyChanged(INSPECTABLE *aObject, PROPERTY_BASE *aProperty)
Callback to alert the notification system that a property has changed.
COMMIT * m_managedCommit
void Mask(TYPE_ID aDerived, TYPE_ID aBase, const wxString &aName)
Sets a base class property as masked in a derived class.
static PROPERTY_MANAGER & Instance()
friend class PROPERTY_COMMIT_HANDLER
PROPERTY_BASE & AddProperty(PROPERTY_BASE *aProperty, const wxString &aGroup=wxEmptyString)
Register a property.
void Rebuild()
Rebuild the list of all registered properties.
PROPERTY_BASE * GetProperty(TYPE_ID aType, const wxString &aProperty) const
Return a property for a specific type.
std::unordered_map< TYPE_ID, CLASS_DESC > m_classes
Map of all available types.
~PROPERTY_MANAGER() noexcept
const void * TypeCast(const void *aSource, TYPE_ID aBase, TYPE_ID aTarget) const
Cast a type to another type.
CLASS_DESC & getClass(TYPE_ID aTypeId)
Returns metadata for a specific type.
void RegisterType(TYPE_ID aType, const wxString &aName)
Associate a name with a type.
bool IsAvailableFor(TYPE_ID aItemClass, PROPERTY_BASE *aProp, INSPECTABLE *aItem)
Checks overriden availability and original availability of a property, returns false if the property ...
std::vector< CLASS_INFO > GetAllClasses()
void * TypeCast(void *aSource, TYPE_ID aBase, TYPE_ID aTarget) const
class PROPERTY_LISTENER_SUBSCRIPTION RegisterListener(TYPE_ID aType, PROPERTY_LISTENER aListenerFunc)
Register a listener for the given type and return a move-only subscription that auto-unregisters in i...
const std::map< PROPERTY_BASE *, int > & GetDisplayOrder(TYPE_ID aType) const
PROPERTY_LISTENER_HANDLE m_nextListenerHandle
void UnregisterListener(TYPE_ID aType, PROPERTY_LISTENER_HANDLE aHandle)
Remove a single listener registration by its handle.
void OverrideAvailability(TYPE_ID aDerived, TYPE_ID aBase, const wxString &aName, std::function< bool(INSPECTABLE *)> aFunc)
Sets an override availability functor for a base class property of a given derived class.
bool IsOfType(TYPE_ID aDerived, TYPE_ID aBase) const
Return true if aDerived is inherited from aBase.
PROPERTY_BASE & ReplaceProperty(size_t aBase, const wxString &aName, PROPERTY_BASE *aNew, const wxString &aGroup=wxEmptyString)
Replace an existing property for a specific type.
std::map< TYPE_ID, std::vector< std::pair< PROPERTY_LISTENER_HANDLE, PROPERTY_LISTENER > > > m_listeners
void OverrideWriteability(TYPE_ID aDerived, TYPE_ID aBase, const wxString &aName, std::function< bool(INSPECTABLE *)> aFunc)
Sets an override writeability functor for a base class property of a given derived class.
std::unordered_map< TYPE_ID, wxString > m_classNames
std::vector< PROPERTY_BASE * > GetCommonDynamicProperties(const std::vector< const INSPECTABLE * > &aObjects) const
Return the dynamic properties of the first object whose names every other object also has,...
const std::vector< wxString > & GetGroupDisplayOrder(TYPE_ID aType) const
void AddTypeCast(TYPE_CAST_BASE *aCast)
Register a type converter.
STL class.
STL namespace.
std::function< void(INSPECTABLE *, PROPERTY_BASE *, COMMIT *)> PROPERTY_LISTENER
std::size_t PROPERTY_LISTENER_HANDLE
Opaque handle returned by RegisterListener so a specific registration can be removed without disturbi...
size_t TYPE_ID
Unique type identifier.
Structure holding type meta-data.
std::vector< std::reference_wrapper< CLASS_DESC > > m_bases
Types after which this type inherits.
std::set< std::pair< size_t, wxString > > m_replaced
Replaced properties (TYPE_ID / name)
std::vector< wxString > m_groupDisplayOrder
List of property groups provided by this class in display order.
std::map< std::pair< size_t, wxString >, std::function< bool(INSPECTABLE *)> > m_availabilityOverrides
Overrides for base class property availabilities.
std::map< std::pair< size_t, wxString >, std::function< bool(INSPECTABLE *)> > m_writeabilityOverrides
Overrides for base class property writeable status.
std::map< wxString, std::unique_ptr< PROPERTY_BASE > > m_ownProperties
Properties unique to this type (i.e. not inherited)
std::vector< PROPERTY_BASE * > m_ownDisplayOrder
Non-owning list of classes's direct properties in display order.
std::set< std::pair< size_t, wxString > > m_maskedBaseProperties
Properties from bases that should be masked (hidden) on this subclass.
std::map< PROPERTY_BASE *, int > m_displayOrder
Compiled display order for all properties.
std::vector< PROPERTY_BASE * > m_allProperties
All properties (both unique to the type and inherited)
std::map< TYPE_ID, std::unique_ptr< TYPE_CAST_BASE > > m_typeCasts
Type converters available for this type.
void collectPropsRecur(std::vector< PROPERTY_BASE * > &aResult, std::set< std::pair< size_t, wxString > > &aReplaced, std::map< PROPERTY_BASE *, int > &aDisplayOrder, std::set< std::pair< size_t, wxString > > &aMasked) const
Traverses the class inheritance hierarchy bottom-to-top, gathering all properties available to a type...
void rebuild()
Recreates the list of properties.
const TYPE_ID m_id
Unique type identifier (obtained using TYPE_HASH)
std::set< wxString > m_groups
The property groups provided by this class.
std::vector< PROPERTY_BASE * > properties