Mercurial > hg > vampy
view PyExtensionManager.cpp @ 46:af9c4cee95a8
VC++ fixes.
Much of this is changing "and" to "&&". I had never realised
until today that "and" is in fact a keyword in C++, albeit not
one that has been there since the start, so this should compile
(I eventually looked this up having been puzzled by how this
code could ever build with any other compiler). However,
despite its keywordness, "and" still doesn't seem to be acceptable
to VC++. Possibly there's an option to change this, or one could
use a macro -- but why not just stick with the token that compilers
are known to like?
author | cannam |
---|---|
date | Mon, 05 Oct 2009 16:14:25 +0000 |
parents | 27bab3a16c9a |
children | 5664fe298af2 |
line wrap: on
line source
/* * Vampy : This plugin is a wrapper around the Vamp plugin API. * It allows for writing Vamp plugins in Python. * Centre for Digital Music, Queen Mary University of London. * Copyright (C) 2008-2009 Gyorgy Fazekas, QMUL. (See Vamp sources * for licence information.) */ #include <Python.h> #include "vamp/vamp.h" #include "PyExtensionModule.h" #include "PyExtensionManager.h" #include <algorithm> using std::cerr; using std::endl; using std::string; using std::vector; using std::find; //static char* PyExtensionManager::m_exposedNames[] = { "ParameterDescriptor", "OutputDescriptor", "ParameterList", "OutputList", "FeatureList", "FeatureSet", "Feature", "RealTime", "frame2RealTime", /* //using builtin objects: "OneSamplePerStep", "FixedSampleRate", "VariableSampleRate", "TimeDomain", "FrequencyDomain", */ NULL }; PyExtensionManager::PyExtensionManager() { #ifdef _DEBUG cerr << "Creating extension manager." << endl; #endif } bool PyExtensionManager::initExtension() { cerr << "Initialising extension module." << endl; /// call the module initialiser first initvampy(); /// these references are all borrowed m_pyGlobalNamespace = PyImport_GetModuleDict(); if (!m_pyGlobalNamespace) {cerr << "Vampy::PyExtensionManager::initExtension: GlobalNamespace failed." << endl; return false;} PyObject *pyVampyModule = PyDict_GetItemString(m_pyGlobalNamespace,"vampy"); if (!pyVampyModule) {cerr << "Vampy::PyExtensionManager::initExtension: VampyModule failed." << endl; return false;} m_pyVampyNamespace = PyModule_GetDict(pyVampyModule); if (!m_pyVampyNamespace) {cerr << "Vampy::PyExtensionManager::initExtension: VampyNamespace failed." << endl; return false;} /// initialise local namespaces updateAllLocals(); #ifdef _DEBUG cerr << "Vampy: Extension namespaces updated." << endl; #endif return true; } PyExtensionManager::~PyExtensionManager() { #ifdef _DEBUG cerr << "Cleaning locals..." << endl; #endif cleanAllLocals(); #ifdef _DEBUG cerr << "Cleaning module..." << endl; #endif if (!cleanModule()) cerr << "Vampy::~PyExtensionManager: failed to clean extension module." << endl; cerr << "Vampy::~PyExtensionManager: Extension module cleaned." << endl; } void PyExtensionManager::setPlugModuleNames(vector<string> pyPlugs) { for (size_t i = 0; i < pyPlugs.size(); ++i) { string modName = pyPlugs[i]; string tmp = modName.substr(modName.rfind(':')+1,modName.size()-1); m_plugModuleNames.push_back(tmp); #ifdef _DEBUG_VALUES cerr << "Inserted module name: " << tmp << endl; #endif } } void PyExtensionManager::deleteModuleName(string plugKey) { string name = plugKey.substr(plugKey.rfind(':')+1,plugKey.size()-1); vector<string>::iterator it = find (m_plugModuleNames.begin(), m_plugModuleNames.end(), name); if (it != m_plugModuleNames.end()) m_plugModuleNames.erase(it); #ifdef _DEBUG_VALUES cerr << "PyExtensionManager::deleteModuleName: Deleted module name: " << name << endl; #endif } void PyExtensionManager::cleanAllLocals() const { for (size_t i = 0; i < m_plugModuleNames.size(); ++i) { cleanLocalNamespace(m_plugModuleNames[i].c_str()); } } void PyExtensionManager::updateAllLocals() const { for (size_t i = 0; i < m_plugModuleNames.size(); ++i) { updateLocalNamespace(m_plugModuleNames[i].c_str()); } } void PyExtensionManager::cleanLocalNamespace(const char* plugModuleName) const { /// these references are all borrowed PyObject *pyPlugModule = PyDict_GetItemString(m_pyGlobalNamespace,plugModuleName); if (!pyPlugModule) return; PyObject *pyPlugDict = PyModule_GetDict(pyPlugModule); if (!pyPlugDict) return; int i = 0; while (PyExtensionManager::m_exposedNames[i]) { char* name = PyExtensionManager::m_exposedNames[i]; i++; PyObject *key = PyString_FromString(name); if (!key) break; if (PyDict_Contains(pyPlugDict,key)) { if (PyDict_SetItem(pyPlugDict,key,Py_None) != 0) cerr << "Vampy::PyExtensionManager::cleanLocalNamespace: Failed: " << name << " of "<< plugModuleName << endl; #ifdef _DEBUG_VALUES else cerr << "Cleaned local name: " << name << endl; #endif } Py_DECREF(key); } } void PyExtensionManager::updateLocalNamespace(const char* plugModuleName) const { /// this allows the use of common syntax like: /// from vampy import * /// even after several unload/reload cycles /// these references are all borrowed PyObject *pyPlugModule = PyDict_GetItemString(m_pyGlobalNamespace,plugModuleName); if (!pyPlugModule) return; PyObject *pyPlugDict = PyModule_GetDict(pyPlugModule); if (!pyPlugDict) return; int i = 0; while (PyExtensionManager::m_exposedNames[i]) { const char* name = PyExtensionManager::m_exposedNames[i]; i++; PyObject *key = PyString_FromString(name); if (!key) break; if (PyDict_Contains(pyPlugDict,key)) { PyObject* item = PyDict_GetItem(m_pyVampyNamespace,key); if (PyDict_SetItem(pyPlugDict,key,item) != 0) cerr << "Vampy::PyExtensionManager::updateLocalNamespace: Failed: " << name << " of "<< plugModuleName << endl; #ifdef _DEBUG_VALUES else cerr << "Updated local name: " << name << endl; #endif } Py_DECREF(key); } } bool PyExtensionManager::cleanModule(void) const { PyObject *m = PyImport_AddModule("vampy"); if (!m) { if (PyErr_Occurred()) {PyErr_Print(); PyErr_Clear();} cerr << "Vampy::PyExtensionManager::cleanModule: PyImport_AddModule returned NULL!" << endl; return false; } else { PyObject *dict = PyModule_GetDict(m); #ifdef _DEBUG Py_ssize_t ln = PyDict_Size(dict); cerr << "Vampy::PyExtensionManager::cleanModule: Size of module dict = " << (int) ln << endl; #endif /// Clean the module dictionary. // printDict(dict); PyDict_Clear(dict); if (PyErr_Occurred()) { PyErr_Print(); PyErr_Clear(); return false; } PyObject *name = PyString_FromString("vampy"); if (name) PyDict_SetItemString(dict,"__name__",name); Py_XDECREF(name); #ifdef _DEBUG ln = PyDict_Size(dict); cerr << "Vampy::PyExtensionManager::cleanModule: Size of module dict (cleaned) = " << (int) ln << endl; #endif return true; } } void PyExtensionManager::printDict(PyObject* inDict) const { Py_ssize_t pyPos = 0; PyObject *pyKey, *pyDictValue; cerr << endl << endl << "Module dictionary contents: " << endl; while (PyDict_Next(inDict, &pyPos, &pyKey, &pyDictValue)) { char *key = PyString_AS_STRING(pyKey); char *val = PyString_AS_STRING(PyObject_Str(pyDictValue)); cerr << "key: [ '" << key << "' ] value: " << val << endl; } }