File: ModuleManager.h

package info (click to toggle)
audacity 3.7.3%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 125,252 kB
  • sloc: cpp: 358,238; ansic: 75,458; lisp: 7,761; sh: 3,410; python: 1,503; xml: 1,385; perl: 854; makefile: 122
file content (173 lines) | stat: -rw-r--r-- 5,401 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/**********************************************************************

  Audacity: A Digital Audio Editor

  ModuleManager.h

  Dominic Mazzoni
  James Crook

**********************************************************************/

#ifndef __AUDACITY_MODULEMANAGER_H__
#define __AUDACITY_MODULEMANAGER_H__

#include "IteratorX.h"
#include <functional>
#include <map>
#include <memory>
#include <vector>
#include <wx/string.h>

#include "Identifier.h"

class wxArrayString;
class wxDynamicLibrary;
class ComponentInterface;
class PluginProvider;
class wxWindow;
using PluginID = wxString;
class TranslatableString;

//
// Module Manager
//
// wxPluginManager would be MUCH better, but it's an "undocumented" framework.
//

#include "ModuleConstants.h"

typedef int (*fnModuleDispatch)(ModuleDispatchTypes type);

class Module
{
public:
   Module(const FilePath & name);
   virtual ~Module();

   void ShowLoadFailureError(const wxString &Error);
   bool Load(wxString &deferredErrorMessage);
   void Unload();
   bool HasDispatch() { return mDispatch != NULL; };
   int Dispatch(ModuleDispatchTypes type);
   void * GetSymbol(const wxString &name);
   const FilePath &GetName() const { return mName; }

private:
   const FilePath mName;
   std::unique_ptr<wxDynamicLibrary> mLib;
   fnModuleDispatch mDispatch;
};

class MODULE_MANAGER_API PluginProviderUniqueHandle final
{
   std::unique_ptr<PluginProvider> mPtr;
public:
   PluginProviderUniqueHandle() = default;
   explicit PluginProviderUniqueHandle(std::unique_ptr<PluginProvider> ptr) : mPtr(std::move(ptr)) { }
   ~PluginProviderUniqueHandle();

   PluginProviderUniqueHandle(PluginProviderUniqueHandle&&) = default;
   PluginProviderUniqueHandle& operator=(PluginProviderUniqueHandle&&) = default;

   PluginProviderUniqueHandle(const PluginProviderUniqueHandle&) = delete;
   PluginProviderUniqueHandle& operator=(const PluginProviderUniqueHandle&) = delete;

   PluginProvider* get() noexcept { return mPtr.get(); }
   const PluginProvider* get() const noexcept { return mPtr.get(); }

   PluginProvider* operator->() noexcept { return mPtr.get(); }
   const PluginProvider* operator->() const noexcept { return mPtr.get(); }
};

using PluginProviderHandlesMap = std::map<wxString, PluginProviderUniqueHandle>;

class MODULE_MANAGER_API ModuleManager final
{
public:

   // -------------------------------------------------------------------------
   // ModuleManager implementation
   // -------------------------------------------------------------------------

   static ModuleManager & Get();
   
   // This string persists in configuration files
   // So config compatibility will break if it is changed across Audacity versions
   static wxString GetPluginTypeString();

   static PluginID GetID(const PluginProvider *provider);

private:
   static void FindModules(FilePaths &files);
   using DelayedErrors =
      std::vector< std::pair< std::unique_ptr<Module>, wxString > >;
   static void TryLoadModules(
      const FilePaths &files, FilePaths &decided, DelayedErrors &errors);

public:
   void Initialize();
   int Dispatch(ModuleDispatchTypes type);

   // PluginManager use
   // Can be called before Initialize()
   bool DiscoverProviders();

   // Supports range-for iteration
   auto Providers() const
   { return make_iterator_range(mProviders.cbegin(), mProviders.cend()); }

   auto Providers()
   { return make_iterator_range(mProviders.begin(), mProviders.end()); }

   bool RegisterEffectPlugin(const PluginID & provider, const PluginPath & path,
                       TranslatableString &errMsg);

   PluginProvider *CreateProviderInstance(
      const PluginID & provider, const PluginPath & path);
   std::unique_ptr<ComponentInterface>
      LoadPlugin(const PluginID & provider, const PluginPath & path);

   bool IsProviderValid(const PluginID & provider, const PluginPath & path);
   bool CheckPluginExist(const PluginID& providerId, const PluginPath& path);

private:
   // I'm a singleton class
   ModuleManager();
   ~ModuleManager();
   ModuleManager(const ModuleManager&) = delete;
   ModuleManager &operator=(const ModuleManager&) = delete;

   void InitializeBuiltins();

   friend std::unique_ptr<ModuleManager> std::make_unique<ModuleManager>();

   friend std::default_delete<ModuleManager>;
   static std::unique_ptr<ModuleManager> mInstance;

   // Providers can each report availability of any number of Plug-Ins
   // identified by "paths", and are also factories of ComponentInterface
   // objects for each path
   PluginProviderHandlesMap mProviders;

   // Other libraries that receive notifications of events described by
   // ModuleDispatchTypes:
   std::vector<std::unique_ptr<Module>> mModules;
};

// ----------------------------------------------------------------------------
// A factory of PluginProvider objects
// ----------------------------------------------------------------------------
using PluginProviderFactory = std::unique_ptr<PluginProvider> (*)();

MODULE_MANAGER_API
void RegisterProviderFactory(PluginProviderFactory factory);
MODULE_MANAGER_API
void UnregisterProviderFactory(PluginProviderFactory factory);

// Guarantee the registry exists before any registrations, so it will
// be destroyed only after the un-registrations
static struct Init{
   Init() { RegisterProviderFactory(nullptr); } } sInitBuiltinModules;

#endif /* __AUDACITY_MODULEMANAGER_H__ */