void PythonContext::setPyGlobal(const char *varName, PyObject *obj) { if(!initialised()) { emit exception( lit("SystemError"), tr("Python integration failed to initialise, see diagnostic log for more information."), -1, {}); return; } int ret = -1; PyGILState_STATE gil = PyGILState_Ensure(); if(obj) ret = PyDict_SetItemString(context_namespace, varName, obj); PyGILState_Release(gil); if(ret == 0) return; emit exception(lit("RuntimeError"), tr("Failed to set variable '%1'").arg(QString::fromUtf8(varName)), -1, {}); }
void PythonContext::setGlobal(const char *varName, const char *typeName, void *object) { if(!initialised()) { emit exception( lit("SystemError"), tr("Python integration failed to initialise, see diagnostic log for more information."), -1, {}); return; } PyGILState_STATE gil = PyGILState_Ensure(); // we don't need separate functions for each module, as they share type info PyObject *obj = PassObjectToPython(typeName, object); int ret = -1; if(obj) ret = PyDict_SetItemString(context_namespace, varName, obj); PyGILState_Release(gil); if(ret != 0) { emit exception(lit("RuntimeError"), tr("Failed to set variable '%1' of type '%2'") .arg(QString::fromUtf8(varName)) .arg(QString::fromUtf8(typeName)), -1, {}); return; } setPyGlobal(varName, obj); }
PyObject *PythonContext::QtObjectToPython(const char *typeName, QObject *object) { #if PYSIDE2_ENABLED if(!initialised()) Py_RETURN_NONE; if(!SbkPySide2_QtCoreTypes || !SbkPySide2_QtGuiTypes || !SbkPySide2_QtWidgetsTypes) { QWidget *w = qobject_cast<QWidget *>(object); if(w) return WrapBareQWidget(w); Py_RETURN_NONE; } PyObject *obj = Shiboken::Object::newObject(reinterpret_cast<SbkObjectType *>(Shiboken::SbkType<QObject>()), object, false, false, typeName); return obj; #else QWidget *w = qobject_cast<QWidget *>(object); if(w) return WrapBareQWidget(w); Py_RETURN_NONE; #endif }
// called by the IRQ handler at the completion of ADC conversion void callbackOnCompletion(ADC_HandleTypeDef* hadc) { if(hadc != (&hadc1)) { return; } if(false == initialised(Port::one)) { return; } if(Acquisition::single == s_config.acquisition) { stop(Port::one); } else { start(Port::one); } if(nullptr != s_config.oncompletion.callback) { s_config.oncompletion.callback(s_config.oncompletion.arg); } }
result_t init(Port p, const Config &config) { if(false == supported(p)) { return resNOK; } if(true == initialised(p)) { return resOK; } s_config = config; // init peripherals: adc1 and dma1 MX_ADC1_Init(); // dma is globally initted by stm32hal_bsp_init() because it hold all dma peripherals //MX_DMA_Init(); // init internal variables s_adc_isrunning = false; embot::binary::bit::set(initialisedmask, port2index(p)); return resOK; }
bool isrunning(Port p) { if(false == initialised(p)) { return false; } return s_adc_isrunning; }
result_t get(Port p, void *items) { if(false == initialised(p)) { return resNOK; } std::memmove(items, s_config.destination, static_cast<std::uint8_t>(s_config.itemsize)*s_config.numberofitems); return resOK; }
bool Session::isEmpty() const { if ( d->mailbox->uidnext() == 1 ) return true; if ( !d->msns.isEmpty() ) return false; if ( !d->unannounced.isEmpty() ) return false; if ( !initialised() ) return false; return true; }
// Function responsible of setting the keep-alive option of the class. inline void TCPSocket::_set_keep_alive_option() { if ( initialised() ) { tcp_keepalive alive; DWORD bytes = 0; alive.onoff = ( _keep_alive ? 1 : 0 ); alive.keepalivetime = _keep_alive_timeout; alive.keepaliveinterval = _keep_alive_interval; WSAIoctl(socket_ref(),SIO_KEEPALIVE_VALS,&alive,sizeof(alive),NULL,0,&bytes,NULL,NULL); } };
result_t configure(Port p, const embot::common::Callback &oncompletion) { if(false == initialised(p)) { return resNOK; } if(true == s_adc_isrunning) { stop(p); } s_config.oncompletion = oncompletion; return resOK; }
result_t configure(Port p, Acquisition acquisition) { if(false == initialised(p)) { return resNOK; } if(true == s_adc_isrunning) { stop(p); } s_config.acquisition = acquisition; return resOK; }
result_t stop(Port p) { if(false == initialised(p)) { return resNOK; } if(true == s_adc_isrunning) { HAL_ADC_Stop_DMA(&hadc1); s_adc_isrunning = false; } s_adc_isrunning = false; return resOK; }
void PythonContext::GlobalShutdown() { if(!initialised()) return; // must happen on the UI thread if(qApp->thread() != QThread::currentThread()) { qFatal("PythonContext::GlobalShutdown MUST be called from the UI thread"); return; } // acquire the GIL, so we can shut down PyGILState_Ensure(); Py_Finalize(); }
QWidget *PythonContext::QWidgetFromPy(PyObject *widget) { #if PYSIDE2_ENABLED if(!initialised()) return NULL; if(!SbkPySide2_QtCoreTypes || !SbkPySide2_QtGuiTypes || !SbkPySide2_QtWidgetsTypes) return UnwrapBareQWidget(widget); if(!Shiboken::Object::checkType(widget)) return UnwrapBareQWidget(widget); return (QWidget *)Shiboken::Object::cppPointer((SbkObject *)widget, Shiboken::SbkType<QWidget>()); #else return UnwrapBareQWidget(widget); #endif }
result_t start(Port p) { if(false == initialised(p)) { return resNOK; } if((nullptr == s_config.destination) || (0 == s_config.numberofitems)) { return resNOK; } if(true == s_adc_isrunning) { stop(p); } s_adc_isrunning = true; HAL_ADC_Start_DMA(&hadc1, (uint32_t*)s_config.destination, s_config.numberofitems*static_cast<uint8_t>(s_config.itemsize)); return resOK; }
result_t configure(Port p, void *destination, std::uint8_t numberofitems) { if(false == initialised(p)) { return resNOK; } if((nullptr == destination) || (0 == numberofitems)) { return resNOK; } if(true == s_adc_isrunning) { stop(p); } s_config.destination = destination; s_config.numberofitems = numberofitems; return resOK; }
// retrieve the held BAT BAT* get() const { if(!initialised()) { RAISE_ERROR("Empty BatHandle"); } return shared_ptr->handle; }
void PythonContext::executeString(const QString &filename, const QString &source) { if(!initialised()) { emit exception( lit("SystemError"), tr("Python integration failed to initialise, see diagnostic log for more information."), -1, {}); return; } location.file = filename; location.line = 1; PyGILState_STATE gil = PyGILState_Ensure(); PyObject *compiled = Py_CompileString(source.toUtf8().data(), filename.toUtf8().data(), source.count(QLatin1Char('\n')) == 0 ? Py_single_input : Py_file_input); PyObject *ret = NULL; if(compiled) { PyObject *traceContext = PyDict_New(); uintptr_t thisint = (uintptr_t) this; uint64_t thisuint64 = (uint64_t)thisint; PyObject *thisobj = PyLong_FromUnsignedLongLong(thisuint64); PyDict_SetItemString(traceContext, "thisobj", thisobj); PyDict_SetItemString(traceContext, "compiled", compiled); PyEval_SetTrace(&PythonContext::traceEvent, traceContext); m_Abort = false; m_State = PyGILState_GetThisThreadState(); ret = PyEval_EvalCode(compiled, context_namespace, context_namespace); m_State = NULL; // catch any output outputTick(); PyEval_SetTrace(NULL, NULL); Py_XDECREF(thisobj); Py_XDECREF(traceContext); } Py_DecRef(compiled); QString typeStr; QString valueStr; int finalLine = -1; QList<QString> frames; bool caughtException = (ret == NULL); if(caughtException) FetchException(typeStr, valueStr, finalLine, frames); Py_XDECREF(ret); PyGILState_Release(gil); if(caughtException) emit exception(typeStr, valueStr, finalLine, frames); }
BAT* get_no_except() const { if(!initialised()) return nullptr; return shared_ptr->handle; }
PythonContext::PythonContext(QObject *parent) : QObject(parent) { if(!initialised()) return; // acquire the GIL and make sure this thread is init'd PyGILState_STATE gil = PyGILState_Ensure(); // clone our own local context context_namespace = PyDict_Copy(main_dict); PyObject *rlcompleter = PyDict_GetItemString(main_dict, "rlcompleter"); // for compatibility with earlier versions of python that took a char * instead of const char * char noparams[1] = ""; // set global output that point to this context. It is responsible for deleting the context when // it goes out of scope PyObject *redirector = PyObject_CallFunction((PyObject *)&OutputRedirectorType, noparams); if(redirector) { PyDict_SetItemString(context_namespace, "_renderdoc_internal", redirector); OutputRedirector *output = (OutputRedirector *)redirector; output->context = this; Py_DECREF(redirector); } if(rlcompleter) { PyObject *Completer = PyObject_GetAttrString(rlcompleter, "Completer"); if(Completer) { // create a completer for our context's namespace m_Completer = PyObject_CallFunction(Completer, "O", context_namespace); if(m_Completer) { PyDict_SetItemString(context_namespace, "_renderdoc_completer", m_Completer); } else { QString typeStr; QString valueStr; int finalLine = -1; QList<QString> frames; FetchException(typeStr, valueStr, finalLine, frames); // failure is not fatal qWarning() << "Couldn't create completion object. " << typeStr << ": " << valueStr; PyErr_Clear(); } } Py_DecRef(Completer); } else { m_Completer = NULL; } // release the GIL again PyGILState_Release(gil); // every 100ms while running, check for new output outputTicker = new QTimer(this); outputTicker->setInterval(100); QObject::connect(outputTicker, &QTimer::timeout, this, &PythonContext::outputTick); // we have to start it here, because we can't start on another thread. outputTicker->start(); }