AnimatLab  2
Test
PyEmbedder.cpp
1 #include "StdAfx.h"
2 #include "PyEmbedder.h"
3 
4 #if defined(_DEBUG) && defined(SWIG_PYTHON_INTERPRETER_NO_DEBUG)
5 /* Use debug wrappers with the Python release dll */
6 # undef _DEBUG
7 # include <Python.h>
8 # define _DEBUG
9 #else
10 # include <Python.h>
11 #endif
12 
13 namespace AnimatSimPy
14 {
15 
16 PyEmbedder::PyEmbedder(void)
17 {
18  m_bPyInit = false;
19  InitPython();
20 }
21 
22 PyEmbedder::~PyEmbedder(void)
23 {
24 try
25 {
26  FinalizePython();
27 }
28 catch(...)
29 {Std_TraceMsg(0, "Caught Error in desctructor of PyEmbedder\r\n", "", -1, false, true);}
30 }
31 
32 void PyEmbedder::InitPython()
33 {
34  int iRet = 0;
35  if(!Py_IsInitialized())
36  {
37  Py_SetProgramName("AnimatLab");
38  Py_Initialize();
39 
40  if(!Py_IsInitialized())
41  THROW_ERROR(Al_Err_lFailedToInitPython, Al_Err_strFailedToInitPython);
42 
43  Simulator *lpSim = ActiveSim();
44  if(!lpSim)
45  THROW_ERROR(Al_Err_lSimNotDefined, Al_Err_strSimNotDefined);
46 
47  std::string strExePath = lpSim->ExecutablePath();
48  strExePath = Std_Replace(strExePath, "\\", "/");
49 
50  //Import base modules and set paths correctly.
51  std::string strInit = "import os,sys,traceback,math\n"
52  "sys.path.append(\"" + strExePath + "\")\n"
53  "os.chdir(\"" + strExePath + "\")\n";
54  iRet = PyRun_SimpleString(strInit.c_str());
55  if(iRet != 0)
56  THROW_ERROR(Al_Err_lFailedToInitPython, Al_Err_strFailedToInitPython);
57 
58  //Try to import AnimatSimPy
59  iRet = PyRun_SimpleString("import AnimatSimPy\n");
60  if(iRet != 0)
61  THROW_ERROR(Al_Err_lFailedToImportAnimatSimPy, Al_Err_strFailedToImportAnimatSimPy);
62 
63  //Setup sys exception handler for animatsim.
64  std::string strExcept = "def animat_excepthook(type, value, tb):\n"
65  " strErr = \"\".join(traceback.format_exception(type, value, tb))\n"
66  " AnimatSimPy.SetLastScriptError(strErr)\n"
67  "sys.excepthook = animat_excepthook\n";
68  iRet = PyRun_SimpleString(strExcept.c_str());
69  if(iRet != 0)
70  THROW_ERROR(Al_Err_lFailedToInitPython, Al_Err_strFailedToInitPython);
71 
72  //For testing of exception handler.
73  //std::string strTest = "a = \"text\"\n"
74  // "b = 5\n"
75  // "error = a + b\n";
76  //iRet = PyRun_SimpleString(strTest.c_str());
77  //if(iRet != 0)
78  //{
79  // std::string strErr = GetLastScriptError();
80  //}
81 
82  m_bPyInit = true;
83  }
84 }
85 
86 void PyEmbedder::FinalizePython()
87 {
88  if(Py_IsInitialized())
89  Py_Finalize();
90 }
91 
92 void PyEmbedder::ResetPython()
93 {
94  FinalizePython();
95  InitPython();
96 }
97 
98 bool PyEmbedder::ExecutePythonScript(const std::string strPy, bool bThrowError)
99 {
100  if(m_bPyInit && strPy.length() > 0)
101  {
102  int iRet = PyRun_SimpleString(strPy.c_str());
103  if(iRet != 0)
104  {
105  std::string strErr = GetLastScriptError();
106 
107  if(bThrowError)
108  THROW_PARAM_ERROR(Al_Err_lExecutingPythonScript, Al_Err_strExecutingPythonScript, "Trace:\r\n", strErr);
109  else
110  Std_LogMsg(StdLogError, strErr, "", -1, true);
111 
112  return false;
113  }
114  else
115  return true;
116  }
117 
118  return true;
119 }
120 
121 
122 }
void Std_TraceMsg(const int iLevel, std::string strMessage, std::string strSourceFile, int iSourceLine, bool bLogToFile, bool bPrintHeader)
Traces a message to the debugger window.
void Std_LogMsg(const int iLevel, std::string strMessage, std::string strSourceFile, int iSourceLine, bool bPrintHeader)
Logs a message,.
std::string Std_Replace(std::string strVal, std::string strFind, std::string strReplace)
Replaces a substring with another string.