ultimatepp/bazaar/CoreBoostPy/Callback.cpp

97 lines
2.4 KiB
C++

#include "Callback.h"
NAMESPACE_UPP
void* call_convertible(PyObject* po)
{
if(po == Py_None) return po;
if(PyFunction_Check(po)) return po;
if(PyCallable_Check(po) && PyMethod_Self(po)) return po;
return 0;
}
//Callback
struct CallbackActionPy : public CallbackAction {
object o;
virtual void Execute()
{
tuple args;
invoke<void>(o.ptr(), args.ptr());
}
CallbackActionPy(PyObject *callable) : o(handle<>(borrowed(callable))) {}
};
struct Callback_from_python
{
Callback_from_python() { converter::registry::push_back(&call_convertible, &construct, type_id<Callback>()); }
static void construct(PyObject* po, converter::rvalue_from_python_stage1_data* data)
{
void* d = ((converter::rvalue_from_python_storage<Callback>*)data)->storage.bytes;
if(po == Py_None) { new(d) Callback(); }
else if(PyFunction_Check(po)) { new(d) Callback(new CallbackActionPy(po)); }
else if(PyCallable_Check(po) && PyMethod_Self(po)) { new(d) Callback(new CallbackActionPy(po)); }
else { throw_error_already_set(); }
data->convertible = d;
}
};
//Gate
struct GateActionPy : public GateAction {
object o;
virtual bool Execute()
{
tuple args;
return invoke<bool>(o.ptr(), args.ptr());
}
GateActionPy(PyObject *callable) : o(handle<>(borrowed(callable))) {}
};
struct Gate_from_python
{
Gate_from_python() { converter::registry::push_back(&call_convertible, &construct, type_id<Gate>()); }
static void construct(PyObject* po, converter::rvalue_from_python_stage1_data* data)
{
void* d = ((converter::rvalue_from_python_storage<Gate>*)data)->storage.bytes;
if(po == Py_None) { new(d) Gate(); }
else if(PyFunction_Check(po)) { new(d) Gate(new GateActionPy(po)); }
else if(PyCallable_Check(po) && PyMethod_Self(po)) { new(d) Gate(new GateActionPy(po)); }
else { throw_error_already_set(); }
data->convertible = d;
}
};
void export_Callback()
{
ONCELOCK
{
Callback_from_python();
class_<Callback>("Callback", "Upp Callback")
.def(init<const Callback&>())
.def("clear", &Callback::Clear)
.def("valid", &Callback::operator bool)
.def("__call__", &Callback::Execute)
;
}
}
void export_Gate()
{
ONCELOCK
{
Callback_from_python();
class_<Gate>("Gate", "Upp Gate")
.def(init<const Gate&>())
.def("clear", &Gate::Clear)
.def("valid", &Gate::operator bool)
.def("__call__", &Gate::Execute)
;
}
}
END_UPP_NAMESPACE