/* 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 #include #include #include #include #include namespace pangolin { struct PyPangoIO { PyObject_HEAD static PyTypeObject Py_type; static PyMethodDef Py_methods[]; PyPangoIO(PyTypeObject *type, std::queue& line_queue, ConsoleLineType line_type) : line_queue(line_queue), line_type(line_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(PyPangoIO* self) { delete self; } static PyObject * Py_new(PyTypeObject */*type*/, PyObject */*args*/, PyObject */*kwds*/) { // Failure. Can only new in c++ return 0; } static int Py_init(PyPangoIO* /*self*/, PyObject* /*args*/, PyObject* /*kwds*/) { return 0; } static PyObject* Py_getattr(PyPangoIO *self, char* name) { #if PY_MAJOR_VERSION >= 3 PyObject* pystr = PyUnicode_FromString(name); #else PyObject* pystr = PyString_FromString(name); #endif return PyObject_GenericGetAttr((PyObject*)self, pystr ); } static int Py_setattr(PyPangoIO *self, char* name, PyObject* val) { #if PY_MAJOR_VERSION >= 3 PyObject* pystr = PyUnicode_FromString(name); #else PyObject* pystr = PyString_FromString(name); #endif return PyObject_GenericSetAttr((PyObject*)self, pystr, val); } static PyObject* Py_write(PyPangoIO* self, PyObject *args) { const char *text = 0; if (PyArg_ParseTuple(args, "s", &text)) { self->buffer += std::string(text); size_t nl = self->buffer.find_first_of('\n'); while(nl != std::string::npos) { const std::string line = self->buffer.substr(0,nl); self->line_queue.push(ConsoleLine(line,self->line_type)); self->buffer = self->buffer.substr(nl+1); nl = self->buffer.find_first_of('\n'); } } Py_RETURN_NONE; } std::string buffer; std::queue& line_queue; ConsoleLineType line_type; }; PyMethodDef PyPangoIO::Py_methods[] = { {"write", (PyCFunction)PyPangoIO::Py_write, METH_VARARGS, "Write to console" }, {NULL, NULL, 0, NULL} }; #pragma GCC diagnostic push // Ignore python missing initializer warning. #pragma GCC diagnostic ignored "-Wmissing-field-initializers" PyTypeObject PyPangoIO::Py_type = { PyVarObject_HEAD_INIT(NULL,0) "pangolin.PangoIO", /* tp_name*/ sizeof(PyPangoIO), /* tp_basicsize*/ 0, /* tp_itemsize*/ (destructor)PyPangoIO::Py_dealloc, /* tp_dealloc*/ 0, /* tp_print*/ (getattrfunc)PyPangoIO::Py_getattr, /* tp_getattr*/ (setattrfunc)PyPangoIO::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*/ "PyPangoIO object", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ PyPangoIO::Py_methods, /* 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)PyPangoIO::Py_init, /* tp_init */ 0, /* tp_alloc */ (newfunc)PyPangoIO::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 // Return to normal }