// testbench.cpp : Defines the entry point for the application. // #include "stdafx.h" #include "python.h" #include "simwrapper.h" // Dummy class class rFoo { public: rFoo() {} }; typedef struct { PyObject_HEAD rFoo *m_foo; } PyPythonScriptObject; static PyObject *PyPythonScript_NewScript(rFoo *script); static void PyPythonScript_DeallocScript(PyPythonScriptObject *pso); static PyObject *PyPythonScript_GetAttr(PyPythonScriptObject *self, char *name); PyTypeObject PyPythonScript_Type = { PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ "simscript", /*tp_name*/ sizeof(PyPythonScriptObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ /* methods */ (destructor)PyPythonScript_DeallocScript, /*tp_dealloc*/ 0, /*tp_print*/ (getattrfunc)PyPythonScript_GetAttr, /*tp_getattr*/ (setattrfunc)0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ }; /* Allocation and deallocation of pythonscript Objects */ static PyObject * PyPythonScript_NewScript(rFoo *foo) { PyPythonScriptObject *pso; pso = PyObject_NEW(PyPythonScriptObject, &PyPythonScript_Type); if (pso == NULL) return NULL; pso->m_foo = foo; return (PyObject *)pso; } static void PyPythonScript_DeallocScript(PyPythonScriptObject *pso) { PyObject_DEL(pso); } static PyObject * PyPythonScript_getname(PyPythonScriptObject *self, PyObject* args) { // Parse arguments static char *str; if(PyTuple_Size(args) == 1) { if (!PyArg_ParseTuple(args,"s", &str)) return NULL; } else { return PyString_FromString(str); } return Py_None; } extern int PyStackless_Schedule(); static PyObject * PyPythonScript_breaker(PyPythonScriptObject *self, PyObject* args) { // Parse arguments static char *str; if(PyTuple_Size(args) == 1) { if (!PyArg_ParseTuple(args,"s", &str)) return NULL; } else { return Py_None; } // Suspend script execution and switch execution back // This call should save this execution stack for this tasklet // and restore PySW_SuspendTasklet(); return Py_None; } // Object method registration structure static PyMethodDef PyPythonScript_methods[] = { {"foobar", (PyCFunction)PyPythonScript_getname, METH_VARARGS}, {"breaker", (PyCFunction)PyPythonScript_breaker, METH_VARARGS}, {NULL, NULL} /* sentinel */ }; static PyObject * PyPythonScript_GetAttr(PyPythonScriptObject *self, char *name) { return Py_FindMethod(PyPythonScript_methods, (PyObject *)self, name); } int TestConditionFunction( PyObject *condf ) { if (condf && PyCallable_Check(condf)) { int cret = 0; PyObject *fargs = PyTuple_New(0); PyObject *pValue = PyObject_CallObject(condf, fargs); if (pValue != NULL) { cret = PyInt_AsLong(pValue); Py_DECREF(pValue); } Py_DECREF(fargs); return cret; } return -1; } /* note: to switch back to windows mode, change * /subsystem:console back to * /subsystem:windows in the cofiguration window. */ /* q&d function to check, print and clear errors */ #include "malloc.h" void CPCE (int ret, char *msg) { if (ret) { printf("%s\n", msg); PyErr_Print(); } else printf("%s OK\n", msg); } #if 0 int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) #else int main(int argc, char **argv) #endif { char *msg = NULL; // 1. Init python and stackless Py_Initialize(); int code = Py_IsInitialized(); /* no threads needed */ // 2. Init execution wrapper PySW_InitWrapper(); #if 0 /*** This code makes no sense and breaks in Python 2.3. Please read the documentation and use the API correctly. ***/ // 3. Store this instances threadstate PyThreadState *m_interp = PyEval_SaveThread(); // 4. Each script will have its own interpreter PyEval_AcquireLock(); m_interp = Py_NewInterpreter(); PyThreadState_Swap(m_interp); #endif // 5. Add extension module to test script execution rFoo foobar; PyPythonScript_Type.ob_type = &PyType_Type; PyObject *iface_class = PyPythonScript_NewScript(&foobar); PyImport_AddModule("simscript"); Py_InitModule4("simscript", PyPythonScript_methods, NULL, iface_class, PYTHON_API_VERSION); // 6. Use main PyObject *pName, *pModule, *pDict; pName = PyString_FromString("__main__"); pModule = PyImport_Import(pName); if (pModule != NULL) { PySW_SetPath("C:\\codebase\\main\\development\\3rdparty\\stackless_wrapper\\testbench"); PyObject *stacklessmodule = PyImport_AddModule("stackless"); pDict = PyModule_GetDict(pModule); // 7. Compile code (below) char sourcecode[] = " \n\ \n\ import simscript \n\ # import winsound \n\ # import sdk32 \n\ \n\ # winsound.PlaySound(\"c:\\WINDOWS\\MEDIA\\tada.wav\", winsound.SND_FILENAME') \n\ # sdk32.MessageBox(\"Jep\",\"foobar\",win32con.MB_OK) \n\ simscript.foobar(\"mainA\") \n\ \n\ def condition_func(): \n\ return 42 \n\ \n\ def run1(): \n\ print 'run1 starting' \n\ simscript.breaker('A\') \n\ print 'run1 between A/B' \n\ simscript.breaker('B') \n\ print 'run1 finished' \n\ \n\ def run2(): \n\ print 'run2 starting' \n\ simscript.breaker('C') \n\ print 'run2 between C/D' \n\ simscript.breaker('D') \n\ print 'run2 finished' \n\ \n\ simscript.foobar('mainB') \n\ "; PyObject *m_script_code = Py_CompileString(sourcecode, "pythoncode", Py_file_input); Py_INCREF(m_script_code); if( m_script_code ) { int *argll = (int*)_alloca(10000); for(int i=0; i<10; i++) { // 8. And reload it as current main module for execution PyObject *mainobj = PyImport_ExecCodeModule("__main__", m_script_code); if( !mainobj ) PyErr_Print(); // 9. Init main tasklet /* this is done automatically */ // 10. Extract tasklet 1 method from script and create tasklet PyObject *task1 = NULL; PyObject *func = PyDict_GetItemString(pDict, "run1"); if (func && PyCallable_Check(func)) task1 = PySW_CreateTasklet( func ); // 11. Extract tasklet 2 method from script and create tasklet PyObject *task2 = NULL; func = PyDict_GetItemString(pDict, "run2"); if (func && PyCallable_Check(func)) task2 = PySW_CreateTasklet( func ); // 12. Execute tasklet 1 & 2 code till defined execution points if( task1 && task2 ) { msg = "13. Execute tasklet 1 till point \"A\""; CPCE(PySW_RunTasklet(task1), msg); msg = "14. Execute tasklet 2 till point \"C\""; CPCE(PySW_RunTasklet(task2), msg); msg = "15. Execute tasklet 1 till point \"B\""; CPCE(PySW_ContinueTasklet( task1 ), msg); msg = "16. Emulate interpreter switch"; /* CT dropped */ msg = "17. Call condition func in a middle of tasklet 1 execution"; PyObject *condf = PyDict_GetItemString(pDict, "condition_func"); printf("%s returns %d\n", msg, TestConditionFunction( condf )); msg = "18. Execute tasklet 2 till point \"D\""; CPCE(PySW_ContinueTasklet( task2 ), msg); msg = "19. Execute tasklet 1 till end"; CPCE(PySW_ContinueTasklet( task1 ), msg); msg = "20. Reset tasklet 1 execution"; CPCE(PySW_ResetTasklet( task1 ), msg); msg = "21. Cleanup tasklet 1 execution"; CPCE(PySW_CleanupTasklet( task1 ), msg); msg = "22. Cleanup tasklet 2 execution (suspended)"; CPCE(PySW_CleanupTasklet( task2 ), msg); } Py_XDECREF(task1); Py_XDECREF(task2); } } else { // 21. Syntax error at script code PyErr_Print(); } } // 22. Release execution context /* CT dropped */ Py_Finalize(); return 0; }