Mercurial > hg > vampy
comparison PyPlugScanner.cpp @ 24:7d28bed0864e
* Rearrange Python plugin construction.
Formerly, the PyPluginAdapter has retained a single plugin instance pointer
for each plugin found, and its createPlugin method has simply returned a new
PyPlugin object wrapping the same instance pointer. This has a couple of
negative consequences:
- Because construction of the actual Python instance occurred before the
wrapper was constructed, it was not possible to pass arguments (i.e.
the sample rate) from the wrapper constructor to the Python plugin
instance constructor -- they had to be passed later, to initialise,
disadvantaging those plugins that would like to use the sample rate
for parameter & step/block size calculations etc
- Because there was only a single Python plugin instance, it was not
possible to run more than one instance at once with any isolation
This rework instead stores the Python class pointer (rather than instance
pointer) in the PyPluginAdapter, and each PyPlugin wrapper instance creates
its own Python plugin instance. What could possibly go wrong?
author | cannam |
---|---|
date | Mon, 17 Aug 2009 15:22:06 +0000 |
parents | 3af6b5990ad8 |
children | 7648f3f2fa14 |
comparison
equal
deleted
inserted
replaced
23:535d559300dc | 24:7d28bed0864e |
---|---|
60 //foreach m_path listFiles then return vector<pyPlugs> | 60 //foreach m_path listFiles then return vector<pyPlugs> |
61 //format: FullPathString/FileName.py:ClassName | 61 //format: FullPathString/FileName.py:ClassName |
62 | 62 |
63 vector<string> pyPlugs; | 63 vector<string> pyPlugs; |
64 string pluginKey; | 64 string pluginKey; |
65 PyObject *pyClassInstance; | 65 PyObject *pyClass; |
66 | 66 |
67 for (size_t i = 0; i < m_path.size(); ++i) { | 67 for (size_t i = 0; i < m_path.size(); ++i) { |
68 | 68 |
69 vector<string> files = listFiles(m_path[i],"py"); | 69 vector<string> files = listFiles(m_path[i],"py"); |
70 | 70 |
72 fi != files.end(); ++fi) { | 72 fi != files.end(); ++fi) { |
73 string script = *fi; | 73 string script = *fi; |
74 if (!script.empty()) { | 74 if (!script.empty()) { |
75 string classname=script.substr(0,script.rfind('.')); | 75 string classname=script.substr(0,script.rfind('.')); |
76 pluginKey=joinPath(m_path[i],script)+":"+classname; | 76 pluginKey=joinPath(m_path[i],script)+":"+classname; |
77 pyClassInstance = getScriptInstance(m_path[i],classname); | 77 pyClass = getScriptClass(m_path[i],classname); |
78 if (pyClassInstance == NULL) | 78 if (pyClass == NULL) |
79 cerr << "Warning: Syntax error in VamPy plugin: " | 79 cerr << "Warning: Syntax error in VamPy plugin: " |
80 << classname << ". Avoiding plugin." << endl; | 80 << classname << ". Avoiding plugin." << endl; |
81 else { | 81 else { |
82 pyPlugs.push_back(pluginKey); | 82 pyPlugs.push_back(pluginKey); |
83 m_pyInstances.push_back(pyClassInstance); | 83 m_pyClasses.push_back(pyClass); |
84 } | 84 } |
85 //pyPlugs.push_back(pluginKey); | 85 //pyPlugs.push_back(pluginKey); |
86 } | 86 } |
87 } | 87 } |
88 } | 88 } |
90 return pyPlugs; | 90 return pyPlugs; |
91 | 91 |
92 } | 92 } |
93 | 93 |
94 | 94 |
95 //For now return one class instance found in each script | 95 //For now return one class object found in each script |
96 vector<PyObject*> | 96 vector<PyObject*> |
97 PyPlugScanner::getPyInstances() | 97 PyPlugScanner::getPyClasses() |
98 { | 98 { |
99 return m_pyInstances; | 99 return m_pyClasses; |
100 | 100 |
101 } | 101 } |
102 | 102 |
103 | 103 |
104 //Validate | 104 //Validate |
105 //This should not be called more than once! | 105 //This should not be called more than once! |
106 PyObject* | 106 PyObject* |
107 PyPlugScanner::getScriptInstance(string path, string classname) | 107 PyPlugScanner::getScriptClass(string path, string classname) |
108 { | 108 { |
109 | 109 |
110 //Add plugin path to active Python Path | 110 //Add plugin path to active Python Path |
111 string pyCmd = "import sys\nsys.path.append('" + path + "')\n"; | 111 string pyCmd = "import sys\nsys.path.append('" + path + "')\n"; |
112 PyRun_SimpleString(pyCmd.c_str()); | 112 PyRun_SimpleString(pyCmd.c_str()); |
134 PyObject *pyClass = PyDict_GetItemString(pyDict, classname.c_str()); | 134 PyObject *pyClass = PyDict_GetItemString(pyDict, classname.c_str()); |
135 | 135 |
136 //Check if class is present and a callable method is implemented | 136 //Check if class is present and a callable method is implemented |
137 if (pyClass && PyCallable_Check(pyClass)) { | 137 if (pyClass && PyCallable_Check(pyClass)) { |
138 | 138 |
139 //Create an instance | 139 return pyClass; |
140 PyObject *pyInstance = PyObject_CallObject(pyClass, NULL); | |
141 //cerr << "__(getInstance) PyPlugin Class: " << m_class << " successfully created.__" << endl; | |
142 return pyInstance; | |
143 } | 140 } |
144 else { | 141 else { |
145 cerr << "ERROR: callable plugin class could not be found in source: " << classname << endl | 142 cerr << "ERROR: callable plugin class could not be found in source: " << classname << endl |
146 << "Hint: plugin source filename and plugin class name must be the same." << endl; | 143 << "Hint: plugin source filename and plugin class name must be the same." << endl; |
147 PyErr_Print(); | 144 PyErr_Print(); |