PLearn 0.1
|
00001 // -*- C++ -*- 00002 00003 // PythonCodeSnippet.h 00004 // 00005 // Copyright (C) 2005 Nicolas Chapados 00006 // 00007 // Redistribution and use in source and binary forms, with or without 00008 // modification, are permitted provided that the following conditions are met: 00009 // 00010 // 1. Redistributions of source code must retain the above copyright 00011 // notice, this list of conditions and the following disclaimer. 00012 // 00013 // 2. Redistributions in binary form must reproduce the above copyright 00014 // notice, this list of conditions and the following disclaimer in the 00015 // documentation and/or other materials provided with the distribution. 00016 // 00017 // 3. The name of the authors may not be used to endorse or promote 00018 // products derived from this software without specific prior written 00019 // permission. 00020 // 00021 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 00022 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00023 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 00024 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00025 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00026 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00027 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00028 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00029 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00030 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 // 00032 // This file is part of the PLearn library. For more information on the PLearn 00033 // library, go to the PLearn Web site at www.plearn.org 00034 00035 /* ******************************************************* 00036 * $Id: PythonCodeSnippet.h 2797 2005-08-25 14:06:26Z chapados $ 00037 ******************************************************* */ 00038 00039 // Authors: Nicolas Chapados 00040 00043 #ifndef PythonCodeSnippet_INC 00044 #define PythonCodeSnippet_INC 00045 00046 // Python stuff must be included first 00047 #include <plearn/python/PythonGlobalInterpreterLock.h> 00048 #include <plearn/python/PythonObjectWrapper.h> 00049 00050 // Boost stuff 00051 #include <boost/function.hpp> 00052 #include <boost/bind.hpp> 00053 00054 // PLearn stuff 00055 #include <plearn/base/Object.h> 00056 #include <plearn/base/plexceptions.h> 00057 #include <plearn/base/PMemPool.h> 00058 00059 00060 namespace PLearn { 00061 using namespace std; 00062 00070 class PythonException : public PLearnError 00071 { 00072 typedef PLearnError inherited; 00073 00074 public: 00075 PythonException(const string& message) 00076 : inherited(message) 00077 { } 00078 }; 00079 00080 00110 class PythonCodeSnippet : public Object 00111 { 00112 typedef Object inherited; 00113 00114 public: 00119 typedef boost::function<PythonObjectWrapper ( 00120 const TVec<PythonObjectWrapper>& args)> StandaloneFunction; 00121 00123 static const char* InjectSetupSnippet; 00124 00126 static const char* SetCurrentSnippetVar; 00127 static const char* ResetCurrentSnippetVar; 00128 00129 public: 00141 string m_code; 00142 00148 bool m_remap_python_exceptions; 00149 00151 map<string, string> m_instance_params; 00152 00154 PythonObjectWrapper m_instance; 00155 00156 public: 00160 PythonCodeSnippet(const string& code = "", 00161 bool remap_python_exceptions = false); 00162 00163 PythonCodeSnippet(const PythonObjectWrapper& instance, 00164 bool remap_python_exceptions = false); 00165 00167 00168 00169 //##### Global Environment Interface #################################### 00170 00173 PythonObjectWrapper getGlobalObject(const string& object_name) const; 00174 00176 void setGlobalObject(const string& object_name, 00177 const PythonObjectWrapper& pow); 00178 template<typename T> 00179 void setGlobalObject(const string& object_name, 00180 const T& o) 00181 { 00182 setGlobalObject(object_name, PythonObjectWrapper(o)); 00183 } 00184 00185 00186 00187 //##### Function Call Interface ######################################### 00188 00190 bool isInvokable(const char* function_name) const; 00191 00193 PythonObjectWrapper invoke(const char* function_name) const; 00194 00198 PythonObjectWrapper invoke(const char* function_name, 00199 const TVec<PythonObjectWrapper>& args) const; 00200 00202 template <class T> 00203 PythonObjectWrapper invoke(const char* function_name, 00204 const T& arg1) const; 00205 00207 template <class T, class U> 00208 PythonObjectWrapper invoke(const char* function_name, 00209 const T& arg1, 00210 const U& arg2) const; 00211 00213 template <class T, class U, class V> 00214 PythonObjectWrapper invoke(const char* function_name, 00215 const T& arg1, 00216 const U& arg2, 00217 const V& arg3) const; 00218 00220 template <class T, class U, class V, class W> 00221 PythonObjectWrapper invoke(const char* function_name, 00222 const T& arg1, 00223 const U& arg2, 00224 const V& arg3, 00225 const W& arg4) const; 00226 00228 template <class T, class U, class V, class W, class X> 00229 PythonObjectWrapper invoke(const char* function_name, 00230 const T& arg1, 00231 const U& arg2, 00232 const V& arg3, 00233 const W& arg4, 00234 const X& arg5) const; 00235 00237 template <class T, class U, class V, class W, class X, class Y> 00238 PythonObjectWrapper invoke(const char* function_name, 00239 const T& arg1, 00240 const U& arg2, 00241 const V& arg3, 00242 const W& arg4, 00243 const X& arg5, 00244 const Y& arg6) const; 00245 00247 template <class T, class U, class V, class W, class X, class Y, class Z> 00248 PythonObjectWrapper invoke(const char* function_name, 00249 const T& arg1, 00250 const U& arg2, 00251 const V& arg3, 00252 const W& arg4, 00253 const X& arg5, 00254 const Y& arg6, 00255 const Z& arg7) const; 00256 00257 00258 //##### Function Injection Interface #################################### 00259 00281 void inject(const char* python_name, StandaloneFunction function_ptr); 00282 00287 template <class T> 00288 void inject(const char* python_name, const T* object, 00289 PythonObjectWrapper (T::*)(const TVec<PythonObjectWrapper>&) const); 00290 00295 template <class T> 00296 void inject(const char* python_name, T* object, 00297 PythonObjectWrapper (T::*)(const TVec<PythonObjectWrapper>&)); 00298 00299 00304 void dumpPythonEnvironment(); 00305 00306 00307 //##### PLearn::Object Standard Functions ############################### 00308 00309 // Declares other standard object methods 00310 PLEARN_DECLARE_OBJECT(PythonCodeSnippet); 00311 00312 // simply calls inherited::build() then build_() 00313 virtual void build(); 00314 00316 virtual void makeDeepCopyFromShallowCopy(CopiesMap& copies); 00317 00318 virtual void run(); 00319 00320 protected: 00322 static void declareOptions(OptionList& ol); 00323 00326 PythonObjectWrapper compileGlobalCode(const string& code); //const; 00327 00328 void setCurrentSnippet(const void* handle) const; 00329 void resetCurrentSnippet() const; 00330 00334 void handlePythonErrors(const string& extramsg= "") const; 00335 00337 static PyObject* pythonTrampoline(PyObject* self, PyObject* args); 00338 00342 void injectInternal(const char* python_name, StandaloneFunction* function_ptr); 00343 00344 protected: 00346 void* m_handle; 00347 00348 public: 00350 PythonObjectWrapper m_compiled_code; 00351 00352 protected: 00354 PObjectPool<StandaloneFunction> m_injected_functions; 00355 00357 PObjectPool<PyMethodDef> m_python_methods; 00358 00359 private: 00362 void build_(); 00363 }; 00364 00365 // Declares a few other classes and functions related to this class 00366 DECLARE_OBJECT_PTR(PythonCodeSnippet); 00367 00368 00369 //##### Implementation of call ############################################## 00370 00371 template <class T> 00372 PythonObjectWrapper 00373 PythonCodeSnippet::invoke(const char* function_name, 00374 const T& arg1) const 00375 { 00376 TVec<PythonObjectWrapper> args(1); 00377 args[0]= PythonObjectWrapper(arg1); 00378 return invoke(function_name, args); 00379 } 00380 00381 00382 template <class T, class U> 00383 PythonObjectWrapper 00384 PythonCodeSnippet::invoke(const char* function_name, 00385 const T& arg1, 00386 const U& arg2) const 00387 { 00388 TVec<PythonObjectWrapper> args(2); 00389 args[0]= PythonObjectWrapper(arg1); 00390 args[1]= PythonObjectWrapper(arg2); 00391 return invoke(function_name, args); 00392 } 00393 00394 00395 template <class T, class U, class V> 00396 PythonObjectWrapper 00397 PythonCodeSnippet::invoke(const char* function_name, 00398 const T& arg1, 00399 const U& arg2, 00400 const V& arg3) const 00401 { 00402 TVec<PythonObjectWrapper> args(3); 00403 args[0]= PythonObjectWrapper(arg1); 00404 args[1]= PythonObjectWrapper(arg2); 00405 args[2]= PythonObjectWrapper(arg3); 00406 return invoke(function_name, args); 00407 } 00408 00409 00410 template <class T, class U, class V, class W> 00411 PythonObjectWrapper 00412 PythonCodeSnippet::invoke(const char* function_name, 00413 const T& arg1, 00414 const U& arg2, 00415 const V& arg3, 00416 const W& arg4) const 00417 { 00418 TVec<PythonObjectWrapper> args(4); 00419 args[0]= PythonObjectWrapper(arg1); 00420 args[1]= PythonObjectWrapper(arg2); 00421 args[2]= PythonObjectWrapper(arg3); 00422 args[3]= PythonObjectWrapper(arg4); 00423 return invoke(function_name, args); 00424 } 00425 00426 template <class T, class U, class V, class W, class X> 00427 PythonObjectWrapper 00428 PythonCodeSnippet::invoke(const char* function_name, 00429 const T& arg1, 00430 const U& arg2, 00431 const V& arg3, 00432 const W& arg4, 00433 const X& arg5) const 00434 { 00435 TVec<PythonObjectWrapper> args(5); 00436 args[0]= PythonObjectWrapper(arg1); 00437 args[1]= PythonObjectWrapper(arg2); 00438 args[2]= PythonObjectWrapper(arg3); 00439 args[3]= PythonObjectWrapper(arg4); 00440 args[4]= PythonObjectWrapper(arg5); 00441 return invoke(function_name, args); 00442 } 00443 00444 template <class T, class U, class V, class W, class X, class Y> 00445 PythonObjectWrapper 00446 PythonCodeSnippet::invoke(const char* function_name, 00447 const T& arg1, 00448 const U& arg2, 00449 const V& arg3, 00450 const W& arg4, 00451 const X& arg5, 00452 const Y& arg6) const 00453 { 00454 TVec<PythonObjectWrapper> args(6); 00455 args[0]= PythonObjectWrapper(arg1); 00456 args[1]= PythonObjectWrapper(arg2); 00457 args[2]= PythonObjectWrapper(arg3); 00458 args[3]= PythonObjectWrapper(arg4); 00459 args[4]= PythonObjectWrapper(arg5); 00460 args[5]= PythonObjectWrapper(arg6); 00461 return invoke(function_name, args); 00462 } 00463 00464 00465 template <class T, class U, class V, class W, class X, class Y, class Z> 00466 PythonObjectWrapper 00467 PythonCodeSnippet::invoke(const char* function_name, 00468 const T& arg1, 00469 const U& arg2, 00470 const V& arg3, 00471 const W& arg4, 00472 const X& arg5, 00473 const Y& arg6, 00474 const Z& arg7) const 00475 { 00476 TVec<PythonObjectWrapper> args(7); 00477 args[0]= PythonObjectWrapper(arg1); 00478 args[1]= PythonObjectWrapper(arg2); 00479 args[2]= PythonObjectWrapper(arg3); 00480 args[3]= PythonObjectWrapper(arg4); 00481 args[4]= PythonObjectWrapper(arg5); 00482 args[5]= PythonObjectWrapper(arg6); 00483 args[6]= PythonObjectWrapper(arg7); 00484 return invoke(function_name, args); 00485 } 00486 00487 00488 //##### Implementation of inject ############################################ 00489 00490 template <class T> 00491 void PythonCodeSnippet::inject( 00492 const char* python_name, const T* object, 00493 PythonObjectWrapper (T::*member_function)(const TVec<PythonObjectWrapper>&) const) 00494 { 00495 StandaloneFunction func = boost::bind(member_function, object, _1); 00496 inject(python_name, func); 00497 } 00498 00499 template <class T> 00500 void PythonCodeSnippet::inject( 00501 const char* python_name, T* object, 00502 PythonObjectWrapper (T::*member_function)(const TVec<PythonObjectWrapper>&)) 00503 { 00504 StandaloneFunction func = boost::bind(member_function, object, _1); 00505 inject(python_name, func); 00506 } 00507 00508 00509 00510 } // end of namespace PLearn 00511 00512 #endif 00513 00514 00515 /* 00516 Local Variables: 00517 mode:c++ 00518 c-basic-offset:4 00519 c-file-style:"stroustrup" 00520 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00521 indent-tabs-mode:nil 00522 fill-column:79 00523 End: 00524 */ 00525 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :