Mercurial > hg > vampy
comparison PyExtensionManager.cpp @ 37:27bab3a16c9a vampy2final
new branch Vampy2final
author | fazekasgy |
---|---|
date | Mon, 05 Oct 2009 11:28:00 +0000 |
parents | |
children | 5664fe298af2 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 37:27bab3a16c9a |
---|---|
1 /* | |
2 | |
3 * Vampy : This plugin is a wrapper around the Vamp plugin API. | |
4 * It allows for writing Vamp plugins in Python. | |
5 | |
6 * Centre for Digital Music, Queen Mary University of London. | |
7 * Copyright (C) 2008-2009 Gyorgy Fazekas, QMUL. (See Vamp sources | |
8 * for licence information.) | |
9 | |
10 */ | |
11 | |
12 #include <Python.h> | |
13 #include "vamp/vamp.h" | |
14 #include "PyExtensionModule.h" | |
15 #include "PyExtensionManager.h" | |
16 #include <algorithm> | |
17 | |
18 using std::cerr; | |
19 using std::endl; | |
20 using std::string; | |
21 using std::vector; | |
22 using std::find; | |
23 | |
24 //static | |
25 char* PyExtensionManager::m_exposedNames[] = { | |
26 "ParameterDescriptor", | |
27 "OutputDescriptor", | |
28 "ParameterList", | |
29 "OutputList", | |
30 "FeatureList", | |
31 "FeatureSet", | |
32 "Feature", | |
33 "RealTime", | |
34 "frame2RealTime", | |
35 /* //using builtin objects: | |
36 "OneSamplePerStep", | |
37 "FixedSampleRate", | |
38 "VariableSampleRate", | |
39 "TimeDomain", | |
40 "FrequencyDomain", | |
41 */ | |
42 NULL | |
43 }; | |
44 | |
45 PyExtensionManager::PyExtensionManager() | |
46 { | |
47 #ifdef _DEBUG | |
48 cerr << "Creating extension manager." << endl; | |
49 #endif | |
50 } | |
51 | |
52 bool | |
53 PyExtensionManager::initExtension() | |
54 { | |
55 cerr << "Initialising extension module." << endl; | |
56 | |
57 /// call the module initialiser first | |
58 initvampy(); | |
59 | |
60 /// these references are all borrowed | |
61 m_pyGlobalNamespace = PyImport_GetModuleDict(); | |
62 if (!m_pyGlobalNamespace) | |
63 {cerr << "Vampy::PyExtensionManager::initExtension: GlobalNamespace failed." << endl; return false;} | |
64 PyObject *pyVampyModule = PyDict_GetItemString(m_pyGlobalNamespace,"vampy"); | |
65 if (!pyVampyModule) | |
66 {cerr << "Vampy::PyExtensionManager::initExtension: VampyModule failed." << endl; return false;} | |
67 m_pyVampyNamespace = PyModule_GetDict(pyVampyModule); | |
68 if (!m_pyVampyNamespace) | |
69 {cerr << "Vampy::PyExtensionManager::initExtension: VampyNamespace failed." << endl; return false;} | |
70 | |
71 /// initialise local namespaces | |
72 updateAllLocals(); | |
73 #ifdef _DEBUG | |
74 cerr << "Vampy: Extension namespaces updated." << endl; | |
75 #endif | |
76 return true; | |
77 } | |
78 | |
79 | |
80 PyExtensionManager::~PyExtensionManager() | |
81 { | |
82 #ifdef _DEBUG | |
83 cerr << "Cleaning locals..." << endl; | |
84 #endif | |
85 | |
86 cleanAllLocals(); | |
87 | |
88 #ifdef _DEBUG | |
89 cerr << "Cleaning module..." << endl; | |
90 #endif | |
91 | |
92 if (!cleanModule()) | |
93 cerr << "Vampy::~PyExtensionManager: failed to clean extension module." << endl; | |
94 cerr << "Vampy::~PyExtensionManager: Extension module cleaned." << endl; | |
95 } | |
96 | |
97 | |
98 | |
99 void | |
100 PyExtensionManager::setPlugModuleNames(vector<string> pyPlugs) | |
101 { | |
102 for (size_t i = 0; i < pyPlugs.size(); ++i) { | |
103 string modName = pyPlugs[i]; | |
104 string tmp = modName.substr(modName.rfind(':')+1,modName.size()-1); | |
105 m_plugModuleNames.push_back(tmp); | |
106 | |
107 #ifdef _DEBUG_VALUES | |
108 cerr << "Inserted module name: " << tmp << endl; | |
109 #endif | |
110 | |
111 } | |
112 } | |
113 | |
114 void | |
115 PyExtensionManager::deleteModuleName(string plugKey) | |
116 { | |
117 string name = plugKey.substr(plugKey.rfind(':')+1,plugKey.size()-1); | |
118 vector<string>::iterator it = | |
119 find (m_plugModuleNames.begin(), m_plugModuleNames.end(), name); | |
120 if (it != m_plugModuleNames.end()) m_plugModuleNames.erase(it); | |
121 #ifdef _DEBUG_VALUES | |
122 cerr << "PyExtensionManager::deleteModuleName: Deleted module name: " << name << endl; | |
123 #endif | |
124 } | |
125 | |
126 | |
127 void | |
128 PyExtensionManager::cleanAllLocals() const | |
129 { | |
130 for (size_t i = 0; i < m_plugModuleNames.size(); ++i) { | |
131 cleanLocalNamespace(m_plugModuleNames[i].c_str()); | |
132 } | |
133 } | |
134 | |
135 void | |
136 PyExtensionManager::updateAllLocals() const | |
137 { | |
138 for (size_t i = 0; i < m_plugModuleNames.size(); ++i) { | |
139 updateLocalNamespace(m_plugModuleNames[i].c_str()); | |
140 } | |
141 } | |
142 | |
143 void | |
144 PyExtensionManager::cleanLocalNamespace(const char* plugModuleName) const | |
145 { | |
146 | |
147 /// these references are all borrowed | |
148 PyObject *pyPlugModule = PyDict_GetItemString(m_pyGlobalNamespace,plugModuleName); | |
149 if (!pyPlugModule) return; | |
150 PyObject *pyPlugDict = PyModule_GetDict(pyPlugModule); | |
151 if (!pyPlugDict) return; | |
152 | |
153 int i = 0; | |
154 while (PyExtensionManager::m_exposedNames[i]) { | |
155 char* name = PyExtensionManager::m_exposedNames[i]; | |
156 i++; | |
157 PyObject *key = PyString_FromString(name); | |
158 if (!key) break; | |
159 if (PyDict_Contains(pyPlugDict,key)) { | |
160 if (PyDict_SetItem(pyPlugDict,key,Py_None) != 0) | |
161 cerr << "Vampy::PyExtensionManager::cleanLocalNamespace: Failed: " | |
162 << name << " of "<< plugModuleName << endl; | |
163 #ifdef _DEBUG_VALUES | |
164 else cerr << "Cleaned local name: " << name << endl; | |
165 #endif | |
166 } | |
167 Py_DECREF(key); | |
168 } | |
169 } | |
170 | |
171 void | |
172 PyExtensionManager::updateLocalNamespace(const char* plugModuleName) const | |
173 { | |
174 /// this allows the use of common syntax like: | |
175 /// from vampy import * | |
176 /// even after several unload/reload cycles | |
177 | |
178 /// these references are all borrowed | |
179 PyObject *pyPlugModule = PyDict_GetItemString(m_pyGlobalNamespace,plugModuleName); | |
180 if (!pyPlugModule) return; | |
181 PyObject *pyPlugDict = PyModule_GetDict(pyPlugModule); | |
182 if (!pyPlugDict) return; | |
183 | |
184 int i = 0; | |
185 while (PyExtensionManager::m_exposedNames[i]) { | |
186 const char* name = PyExtensionManager::m_exposedNames[i]; | |
187 i++; | |
188 PyObject *key = PyString_FromString(name); | |
189 if (!key) break; | |
190 if (PyDict_Contains(pyPlugDict,key)) { | |
191 PyObject* item = PyDict_GetItem(m_pyVampyNamespace,key); | |
192 if (PyDict_SetItem(pyPlugDict,key,item) != 0) | |
193 cerr << "Vampy::PyExtensionManager::updateLocalNamespace: Failed: " | |
194 << name << " of "<< plugModuleName << endl; | |
195 #ifdef _DEBUG_VALUES | |
196 else cerr << "Updated local name: " << name << endl; | |
197 #endif | |
198 } | |
199 Py_DECREF(key); | |
200 } | |
201 } | |
202 | |
203 | |
204 bool | |
205 PyExtensionManager::cleanModule(void) const | |
206 { | |
207 | |
208 PyObject *m = PyImport_AddModule("vampy"); | |
209 if (!m) { | |
210 if (PyErr_Occurred()) {PyErr_Print(); PyErr_Clear();} | |
211 cerr << "Vampy::PyExtensionManager::cleanModule: PyImport_AddModule returned NULL!" << endl; | |
212 return false; | |
213 } else { | |
214 PyObject *dict = PyModule_GetDict(m); | |
215 #ifdef _DEBUG | |
216 Py_ssize_t ln = PyDict_Size(dict); | |
217 cerr << "Vampy::PyExtensionManager::cleanModule: Size of module dict = " << (int) ln << endl; | |
218 #endif | |
219 /// Clean the module dictionary. | |
220 // printDict(dict); | |
221 PyDict_Clear(dict); | |
222 if (PyErr_Occurred()) | |
223 { PyErr_Print(); PyErr_Clear(); return false; } | |
224 PyObject *name = PyString_FromString("vampy"); | |
225 if (name) PyDict_SetItemString(dict,"__name__",name); | |
226 Py_XDECREF(name); | |
227 #ifdef _DEBUG | |
228 ln = PyDict_Size(dict); | |
229 cerr << "Vampy::PyExtensionManager::cleanModule: Size of module dict (cleaned) = " << (int) ln << endl; | |
230 #endif | |
231 return true; | |
232 } | |
233 } | |
234 | |
235 void | |
236 PyExtensionManager::printDict(PyObject* inDict) const | |
237 { | |
238 Py_ssize_t pyPos = 0; | |
239 PyObject *pyKey, *pyDictValue; | |
240 cerr << endl << endl << "Module dictionary contents: " << endl; | |
241 while (PyDict_Next(inDict, &pyPos, &pyKey, &pyDictValue)) | |
242 { | |
243 char *key = PyString_AS_STRING(pyKey); | |
244 char *val = PyString_AS_STRING(PyObject_Str(pyDictValue)); | |
245 cerr << "key: [ '" << key << "' ] value: " << val << endl; | |
246 } | |
247 } | |
248 |