/[svn]/linuxsampler/trunk/src/plugins/InstrumentEditorFactory.cpp
ViewVC logotype

Contents of /linuxsampler/trunk/src/plugins/InstrumentEditorFactory.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1478 - (show annotations) (download)
Tue Nov 13 19:19:18 2007 UTC (16 years, 5 months ago) by senoner
File size: 8558 byte(s)
* work in progress: win32 editor plugin loader

1 /***************************************************************************
2 * *
3 * Copyright (C) 2007 Christian Schoenebeck *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the Free Software *
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
18 * MA 02111-1307 USA *
19 ***************************************************************************/
20
21 #include "InstrumentEditorFactory.h"
22
23 #include "../common/global_private.h"
24
25 #if defined(WIN32)
26 #include <windows.h>
27 #else
28 #include <dlfcn.h>
29 #include <errno.h>
30 #include <dirent.h>
31 #endif
32 #include <string.h>
33
34 #ifndef CONFIG_PLUGIN_DIR
35 # error "Configuration macro CONFIG_PLUGIN_DIR not defined!"
36 #endif // CONFIG_PLUGIN_DIR
37
38 namespace LinuxSampler {
39
40 std::map<String, InstrumentEditorFactory::InnerFactory*> InstrumentEditorFactory::InnerFactories;
41
42 bool InstrumentEditorFactory::bPluginsLoaded = false;
43
44 std::list<void*> InstrumentEditorFactory::LoadedDLLs;
45
46 std::vector<String> InstrumentEditorFactory::AvailableEditors() {
47 // make sure plugins were loaded already
48 LoadPlugins();
49 // render result
50 std::vector<String> result;
51 std::map<String, InnerFactory*>::iterator iter = InnerFactories.begin();
52 for (; iter != InnerFactories.end(); iter++)
53 result.push_back(iter->first);
54 return result;
55 }
56
57 std::vector<String> InstrumentEditorFactory::MatchingEditors(String sTypeName, String sTypeVersion) {
58 // make sure plugins were loaded already
59 LoadPlugins();
60 // render result
61 std::vector<String> result;
62 std::map<String, InnerFactory*>::iterator iter = InnerFactories.begin();
63 for (; iter != InnerFactories.end(); iter++) {
64 InstrumentEditor* pEditor = iter->second->Create();
65 if (pEditor->IsTypeSupported(sTypeName, sTypeVersion))
66 result.push_back(iter->first);
67 iter->second->Destroy(pEditor);
68 }
69 return result;
70 }
71
72 String InstrumentEditorFactory::AvailableEditorsAsString() {
73 std::vector<String> drivers = AvailableEditors();
74 String result;
75 std::vector<String>::iterator iter = drivers.begin();
76 for (; iter != drivers.end(); iter++) {
77 if (result != "") result += ",";
78 result += "'" + *iter + "'";
79 }
80 return result;
81 }
82
83 InstrumentEditor* InstrumentEditorFactory::Create(String InstrumentEditorName) throw (Exception) {
84 if (InnerFactories.count(InstrumentEditorName)) {
85 InnerFactory* pInnerFactory = InnerFactories[InstrumentEditorName];
86 return pInnerFactory->Create();
87 } else throw Exception("unknown instrument editor");
88 }
89
90 void InstrumentEditorFactory::Destroy(InstrumentEditor* pInstrumentEditor) throw (Exception) {
91 if (InnerFactories.count(pInstrumentEditor->Name())) {
92 InnerFactory* pInnerFactory = InnerFactories[pInstrumentEditor->Name()];
93 return pInnerFactory->Destroy(pInstrumentEditor);
94 } else throw Exception("unknown instrument editor");
95 }
96
97 void InstrumentEditorFactory::LoadPlugins() {
98 if (!bPluginsLoaded) {
99 dmsg(1,("Loading instrument editor plugins..."));
100 #if defined(WIN32)
101 bool firstFileFound = true;
102 WIN32_FIND_DATA win32FindData;
103 String plugindir = (String)CONFIG_PLUGIN_DIR + (String)("\\*.DLL");
104 HANDLE hDir = FindFirstFile(plugindir.c_str(), &win32FindData);
105 if (hDir == INVALID_HANDLE_VALUE) {
106 if(GetLastError() != ERROR_FILE_NOT_FOUND) {
107 std::cerr << "Could not open instrument editor plugins directory "
108 << "(" << CONFIG_PLUGIN_DIR << "): Error "
109 << GetLastError() << std::endl;
110 return;
111 }
112 else {
113 firstFileFound = false;
114 }
115 }
116
117 while(GetLastError() != ERROR_NO_MORE_FILES && firstFileFound) {
118 if(!(win32FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
119 String sPath = (String)CONFIG_PLUGIN_DIR + ((String)"\\" + (String)win32FindData.cFileName);
120 // load the DLL (the plugins should register themselfes automatically)
121 void* pDLL = myhinstance = LoadLibrary( sPath.c_str() );
122 if (pDLL) LoadedDLLs.push_back(pDLL);
123 else {
124 std::cerr << "Failed to load instrument editor plugin: "
125 << sPath << std::endl;
126 }
127 }
128 int res = FindNextFile(hDir, &win32FindData);
129 if(res == 0 && GetLastError() != ERROR_NO_MORE_FILES) {
130 std::cerr << "Error while reading plugins directory FindNextFile Error "
131 << GetLastError() << std::endl;
132 return;
133 }
134 }
135 FindClose(hDir);
136 #else // POSIX
137 DIR* hDir = opendir(CONFIG_PLUGIN_DIR);
138 if (!hDir) {
139 std::cerr << "Could not open instrument editor plugins directory "
140 << "(" << CONFIG_PLUGIN_DIR << "): "
141 << strerror(errno) << std::endl;
142 return;
143 }
144 for (dirent* pEntry = readdir(hDir); pEntry; pEntry = readdir(hDir)) {
145 // skip entries that are not regular files
146 if (pEntry->d_type != DT_REG) continue;
147 String sPath = pEntry->d_name;
148 // skip files that are not .so files
149 if (
150 sPath.substr(sPath.length() - 3) != ".so" &&
151 sPath.find(".so.") == String::npos
152 ) continue;
153 // make it a full qualified path
154 sPath = CONFIG_PLUGIN_DIR + ("/" + sPath);
155 // load the DLL (the plugins should register themselfes automatically)
156 void* pDLL = dlopen(sPath.c_str(), RTLD_NOW);
157 if (pDLL) LoadedDLLs.push_back(pDLL);
158 else {
159 std::cerr << "Failed to load instrument editor plugin: "
160 << sPath << std::endl;
161 }
162 }
163 closedir(hDir);
164 #endif
165 bPluginsLoaded = true;
166 dmsg(1,("OK\n"));
167 }
168 }
169
170 void InstrumentEditorFactory::ClosePlugins() {
171 if (LoadedDLLs.size()) {
172 dmsg(1,("Unloading instrument editor plugins..."));
173 // free all inner factories
174 {
175 std::map<String, InnerFactory*>::iterator iter = InnerFactories.begin();
176 for (; iter != InnerFactories.end(); iter++) delete iter->second;
177 InnerFactories.clear();
178 }
179 // free the DLLs
180 {
181 std::list<void*>::iterator iter = LoadedDLLs.begin();
182 for (; iter != LoadedDLLs.end(); iter++) {
183 #if defined(WIN32)
184 FreeLibrary((HINSTANCE)*iter);
185 #else
186 dlclose(*iter);
187 #endif
188 }
189 LoadedDLLs.clear();
190 dmsg(1,("OK\n"));
191 }
192 }
193 bPluginsLoaded = false;
194 }
195
196 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC