v01
This commit is contained in:
271
thirdparty/Pangolin/include/pangolin/python/pyvar.h
vendored
Normal file
271
thirdparty/Pangolin/include/pangolin/python/pyvar.h
vendored
Normal file
@@ -0,0 +1,271 @@
|
||||
/* This file is part of the Pangolin Project.
|
||||
* http://github.com/stevenlovegrove/Pangolin
|
||||
*
|
||||
* Copyright (c) 2011 Steven Lovegrove
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
#include <structmember.h>
|
||||
#include <iomanip>
|
||||
#include <pangolin/var/var.h>
|
||||
#include <pangolin/python/pyuniqueobj.h>
|
||||
|
||||
namespace pangolin
|
||||
{
|
||||
|
||||
PyObject* GetPangoVarAsPython(const std::string& name)
|
||||
{
|
||||
VarState::VarStoreContainer::iterator i = VarState::I().vars.find(name);
|
||||
if(i != VarState::I().vars.end()) {
|
||||
VarValueGeneric* var = i->second;
|
||||
|
||||
try{
|
||||
if( !strcmp(var->TypeId(), typeid(bool).name() ) ) {
|
||||
const bool val = Var<bool>(*var).Get();
|
||||
return PyBool_FromLong( val );
|
||||
}else if( !strcmp(var->TypeId(), typeid(short).name() ) ||
|
||||
!strcmp(var->TypeId(), typeid(int).name() ) ||
|
||||
!strcmp(var->TypeId(), typeid(long).name() ) ) {
|
||||
const long val = Var<long>(*var).Get();
|
||||
return PyLong_FromLong( val );
|
||||
}else if( !strcmp(var->TypeId(), typeid(double).name() ) ||
|
||||
!strcmp(var->TypeId(), typeid(float).name() ) ) {
|
||||
const double val = Var<double>(*var).Get();
|
||||
return PyFloat_FromDouble(val);
|
||||
}else{
|
||||
const std::string val = var->str->Get();
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
return PyUnicode_FromString(val.c_str());
|
||||
#else
|
||||
return PyString_FromString(val.c_str());
|
||||
#endif
|
||||
}
|
||||
}catch(const std::exception&) {
|
||||
}
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
void SetPangoVarFromPython(const std::string& name, PyObject* val)
|
||||
{
|
||||
try{
|
||||
if (PyFloat_Check(val)) {
|
||||
pangolin::Var<double> pango_var(name);
|
||||
pango_var = PyFloat_AsDouble(val);
|
||||
pango_var.Meta().gui_changed = true;
|
||||
}else if (PyLong_Check(val)) {
|
||||
pangolin::Var<long> pango_var(name);
|
||||
pango_var = PyLong_AsLong(val);
|
||||
pango_var.Meta().gui_changed = true;
|
||||
}else if (PyBool_Check(val)) {
|
||||
pangolin::Var<bool> pango_var(name);
|
||||
pango_var = (val == Py_True) ? true : false;
|
||||
pango_var.Meta().gui_changed = true;
|
||||
}
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
else if (PyUnicode_Check(val)) {
|
||||
pangolin::Var<std::string> pango_var(name);
|
||||
pango_var = PyUnicode_AsUTF8(val);
|
||||
pango_var.Meta().gui_changed = true;
|
||||
}
|
||||
#else
|
||||
else if (PyString_Check(val)) {
|
||||
pangolin::Var<std::string> pango_var(name);
|
||||
pango_var = PyString_AsString(val);
|
||||
pango_var.Meta().gui_changed = true;
|
||||
} else if (PyInt_Check(val)) {
|
||||
pangolin::Var<int> pango_var(name);
|
||||
pango_var = PyInt_AsLong(val);
|
||||
pango_var.Meta().gui_changed = true;
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
PyUniqueObj pystr = PyObject_Repr(val);
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
const std::string str = PyUnicode_AsUTF8(pystr);
|
||||
#else
|
||||
const std::string str = PyString_AsString(pystr);
|
||||
#endif
|
||||
pangolin::Var<std::string> pango_var(name);
|
||||
pango_var = str;
|
||||
pango_var.Meta().gui_changed = true;
|
||||
}
|
||||
FlagVarChanged();
|
||||
}catch(const std::exception& e) {
|
||||
pango_print_error("%s\n", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
struct PyVar {
|
||||
static PyTypeObject Py_type;
|
||||
PyObject_HEAD
|
||||
|
||||
PyVar(PyTypeObject *type)
|
||||
{
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
ob_base.ob_refcnt = 1;
|
||||
ob_base.ob_type = type;
|
||||
#else
|
||||
ob_refcnt = 1;
|
||||
ob_type = type;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void Py_dealloc(PyVar* self)
|
||||
{
|
||||
delete self;
|
||||
}
|
||||
|
||||
static PyObject * Py_new(PyTypeObject *type, PyObject * /*args*/, PyObject * /*kwds*/)
|
||||
{
|
||||
PyVar* self = new PyVar(type);
|
||||
return (PyObject *)self;
|
||||
}
|
||||
|
||||
static int Py_init(PyVar *self, PyObject *args, PyObject * /*kwds*/)
|
||||
{
|
||||
char* cNamespace = 0;
|
||||
if (!PyArg_ParseTuple(args, "s", &cNamespace))
|
||||
return -1;
|
||||
|
||||
self->ns = std::string(cNamespace);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject* Py_getattr(PyVar *self, char* name)
|
||||
{
|
||||
const std::string prefix = self->ns + ".";
|
||||
const std::string full_name = self->ns.empty() ? name : prefix + std::string(name);
|
||||
|
||||
if( !strcmp(name, "__call__") ||
|
||||
!strcmp(name, "__dict__") ||
|
||||
!strcmp(name, "__methods__") ||
|
||||
!strcmp(name, "__class__") )
|
||||
{
|
||||
// Default behaviour
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
return PyObject_GenericGetAttr((PyObject*)self, PyUnicode_FromString(name));
|
||||
#else
|
||||
return PyObject_GenericGetAttr((PyObject*)self, PyString_FromString(name));
|
||||
#endif
|
||||
} else if( !strcmp(name, "__members__") ) {
|
||||
const int nss = prefix.size();
|
||||
PyObject* l = PyList_New(0);
|
||||
for(const std::string& s : VarState::I().var_adds) {
|
||||
if(!s.compare(0, nss, prefix)) {
|
||||
size_t dot = s.find_first_of('.', nss);
|
||||
std::string val = (dot != std::string::npos) ? s.substr(nss, dot - nss) : s.substr(nss);
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
PyList_Append(l, PyUnicode_FromString(val.c_str()));
|
||||
#else
|
||||
PyList_Append(l, PyString_FromString(val.c_str()));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return l;
|
||||
}else if( pangolin::VarState::I().Exists(full_name) ) {
|
||||
return GetPangoVarAsPython(full_name);
|
||||
}else{
|
||||
PyVar* obj = (PyVar*)PyVar::Py_new(&PyVar::Py_type,NULL,NULL);
|
||||
if(obj) {
|
||||
obj->ns = full_name;
|
||||
return PyObject_Init((PyObject *)obj,&PyVar::Py_type);
|
||||
}
|
||||
return (PyObject *)obj;
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static int Py_setattr(PyVar *self, char* name, PyObject* val)
|
||||
{
|
||||
const std::string full_name = self->ns.empty() ? name : self->ns + "." + std::string(name);
|
||||
SetPangoVarFromPython(full_name, val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string ns;
|
||||
};
|
||||
|
||||
// The uninitialized variable can be ignored.
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
||||
PyTypeObject PyVar::Py_type = {
|
||||
PyVarObject_HEAD_INIT(NULL,0)
|
||||
"pypangolin.Var", /* tp_name*/
|
||||
sizeof(PyVar), /* tp_basicsize*/
|
||||
0, /* tp_itemsize*/
|
||||
(destructor)PyVar::Py_dealloc, /* tp_dealloc*/
|
||||
0, /* tp_print*/
|
||||
(getattrfunc)PyVar::Py_getattr, /* tp_getattr*/
|
||||
(setattrfunc)PyVar::Py_setattr, /* tp_setattr*/
|
||||
0, /* tp_compare*/
|
||||
0, /* tp_repr*/
|
||||
0, /* tp_as_number*/
|
||||
0, /* tp_as_sequence*/
|
||||
0, /* tp_as_mapping*/
|
||||
0, /* tp_hash */
|
||||
0, /* tp_call*/
|
||||
0, /* tp_str*/
|
||||
0, /* tp_getattro*/
|
||||
0, /* tp_setattro*/
|
||||
0, /* tp_as_buffer*/
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags*/
|
||||
"PyVar object", /* tp_doc */
|
||||
0, /* tp_traverse */
|
||||
0, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
0, /* tp_iter */
|
||||
0, /* tp_iternext */
|
||||
0, /* tp_methods */
|
||||
0, /* tp_members */
|
||||
0, /* tp_getset */
|
||||
0, /* tp_base */
|
||||
0, /* tp_dict */
|
||||
0, /* tp_descr_get */
|
||||
0, /* tp_descr_set */
|
||||
0, /* tp_dictoffset */
|
||||
(initproc)PyVar::Py_init, /* tp_init */
|
||||
0, /* tp_alloc */
|
||||
(newfunc)PyVar::Py_new, /* tp_new */
|
||||
0, /* tp_free */
|
||||
0, /* tp_is_gc */
|
||||
0, /* tp_bases */
|
||||
0, /* tp_mro */
|
||||
0, /* tp_cache */
|
||||
0, /* tp_subclasses */
|
||||
0, /* tp_weaklist */
|
||||
0, /* tp_del */
|
||||
0 /* tp_version_tag */
|
||||
};
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user