Audacity 3.2.0
XMLMethodRegistry.h
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 XMLMethodRegistry.h
6
7 Paul Licameli
8
9**********************************************************************/
10
11#ifndef __AUDACITY_XML_METHOD_REGISTRY__
12#define __AUDACITY_XML_METHOD_REGISTRY__
13
14#include <forward_list>
15#include <string>
16#include <string_view>
17#include <functional>
18#include <type_traits>
19#include <unordered_map>
20#include <utility>
21#include <vector>
22
23class XMLTagHandler;
24class XMLWriter;
26
28
30class XML_API XMLMethodRegistryBase {
31public:
32
34template< typename Substructure >
35using Mutator = std::function< void(Substructure&, const XMLAttributeValueView &) >;
36
38template< typename Substructure >
39using Mutators = std::vector< std::pair< std::string, Mutator<Substructure> > >;
40
43protected:
44 using TypeErasedObjectAccessor = std::function< XMLTagHandler *( void* ) >;
45 using TagTable =
46 std::unordered_map< std::string_view, TypeErasedObjectAccessor >;
48 std::forward_list<std::string> mTags;
49
50 void Register(std::string tag, TypeErasedObjectAccessor accessor);
51 XMLTagHandler *CallObjectAccessor( const std::string_view &tag, void *p );
52
53 using TypeErasedAccessor = std::function< void*( void* ) >;
54 using TypeErasedAccessors = std::vector< TypeErasedAccessor >;
56
57 void PushAccessor( TypeErasedAccessor accessor );
58
59 using TypeErasedMutator = std::function< void( void*, const XMLAttributeValueView& ) >;
61 using MutatorTable = std::unordered_map<std::string_view,
62 std::pair<size_t, TypeErasedMutator>>;
64 std::forward_list<std::string> mMutatorTags;
65
66 void Register(std::string tag, TypeErasedMutator mutator);
67
68 bool CallAttributeHandler(const std::string_view& tag,
69 void *p, const XMLAttributeValueView &value );
70
71 using TypeErasedWriter = std::function< void(const void *, XMLWriter &) >;
72 using WriterTable = std::vector< TypeErasedWriter >;
73
75 void RegisterAttributeWriter( TypeErasedWriter writer );
76 void CallAttributeWriters( const void *p, XMLWriter &writer );
77
79 void RegisterObjectWriter( TypeErasedWriter writer );
80 void CallObjectWriters( const void *p, XMLWriter &writer );
81};
82
86template< typename Host >
88public:
89
90 // Typically statically constructed
92 template <
98 typename ObjectAccessor
100 >
101 ObjectReaderEntry( const std::string &tag, ObjectAccessor fn )
102 {
103 // Remember the function, type-erased
104 Get().Register( tag, [ fn = std::move(fn) ] (void *p) {
105 // CallObjectAccessor will guarantee p is not null
106 return fn( *static_cast<Host *>(p) );
107 } );
108 }
109};
110
111XMLTagHandler *CallObjectAccessor(const std::string_view& tag, Host& host)
112{
114}
115
125 template<
126 typename Accessor,
128 typename Substructure //<! Type deduction of the return of Accessor
129 = std::remove_reference_t< decltype(
130 std::declval<Accessor>()( std::declval<Host &>() )
131 ) >
132 >
134 {
135 // Remember the functions, type-erased
136 auto &registry = Get();
137 registry.PushAccessor(
138 [ fn = std::move(fn) ] ( void *p ) {
139 // CallAttributeHandler will guarantee p is not null
140 return &fn( *static_cast<Host *>(p) ); }
141 );
142 for (auto &pair : pairs)
143 registry.Register( pair.first,
144 [ fn = move(pair.second) ]( auto p, auto value ){
145 fn( *static_cast<Substructure*>(p), value ); }
146 );
147 }
148};
149
150// @return whether any function was found and called for the tag
152 const std::string_view &tag, Host &host, const XMLAttributeValueView& value )
153{
154 return XMLMethodRegistryBase::CallAttributeHandler( tag, &host, value );
155}
156
159 template <
167 typename Writer
169 >
170 explicit AttributeWriterEntry( Writer fn )
171 {
172 // Remember the function, type-erased
174 [ fn = std::move(fn) ] ( const void *p, XMLWriter &writer ) {
175 // CallObjectAccessor will guarantee p is not null
176 return fn( *static_cast<const Host *>(p), writer );
177 } );
178 }
179};
180
183 template <
191 typename Writer
193 >
194 explicit ObjectWriterEntry( Writer fn )
195 {
196 // Remember the function, type-erased
198 [ fn = std::move(fn) ] ( const void *p, XMLWriter &writer ) {
199 // CallObjectAccessor will guarantee p is not null
200 return fn( *static_cast<const Host *>(p), writer );
201 } );
202 }
203};
204
205void CallWriters( const Host &host, XMLWriter &writer )
206{
209}
210
213
214};
215
218#define DECLARE_XML_METHOD_REGISTRY(DECLSPEC, Name) \
219 template<> auto DECLSPEC Name::Get() -> Name &;
220
222#define DEFINE_XML_METHOD_REGISTRY(Name) \
223 template<> auto Name::Get() -> Name & \
224 { \
225 static Name registry; \
226 return registry; \
227 }
228
229#endif
static const auto fn
A view into an attribute value. The class does not take the ownership of the data.
Implementation helper for ProjectFileIORegistry.
WriterTable mObjectWriterTable
std::vector< TypeErasedAccessor > TypeErasedAccessors
TypeErasedAccessors mAccessors
void CallAttributeWriters(const void *p, XMLWriter &writer)
std::function< void(const void *, XMLWriter &) > TypeErasedWriter
std::forward_list< std::string > mMutatorTags
std::unordered_map< std::string_view, std::pair< size_t, TypeErasedMutator > > MutatorTable
From attribute name, to index in accessor table with a mutator.
std::vector< std::pair< std::string, Mutator< Substructure > > > Mutators
A helper type alias for a list of mutators, associated with tag strings.
std::vector< TypeErasedWriter > WriterTable
void RegisterObjectWriter(TypeErasedWriter writer)
void RegisterAttributeWriter(TypeErasedWriter writer)
std::function< XMLTagHandler *(void *) > TypeErasedObjectAccessor
std::function< void *(void *) > TypeErasedAccessor
bool CallAttributeHandler(const std::string_view &tag, void *p, const XMLAttributeValueView &value)
std::function< void(Substructure &, const XMLAttributeValueView &) > Mutator
A helper type alias for a function taking a structure and a string value.
std::unordered_map< std::string_view, TypeErasedObjectAccessor > TagTable
void CallObjectWriters(const void *p, XMLWriter &writer)
std::forward_list< std::string > mTags
std::function< void(void *, const XMLAttributeValueView &) > TypeErasedMutator
WriterTable mAttributeWriterTable
XMLTagHandler * CallObjectAccessor(const std::string_view &tag, void *p)
void Register(std::string tag, TypeErasedObjectAccessor accessor)
XMLTagHandler * CallObjectAccessor(const std::string_view &tag, Host &host)
bool CallAttributeHandler(const std::string_view &tag, Host &host, const XMLAttributeValueView &value)
static XMLMethodRegistry & Get()
Get the unique instance.
void CallWriters(const Host &host, XMLWriter &writer)
This class is an interface which should be implemented by classes which wish to be able to load and s...
Definition: XMLTagHandler.h:42
Base class for XMLFileWriter and XMLStringWriter that provides the general functionality for creating...
Definition: XMLWriter.h:26
AttributeReaderEntries(Accessor fn, Mutators< Substructure > pairs)
Typically statically constructed.
AttributeWriterEntry(Writer fn)
ObjectReaderEntry(const std::string &tag, ObjectAccessor fn)
Typically statically constructed.
ObjectWriterEntry(Writer fn)