Initial wrapping of kj/async Promises and EventLoop
This commit is contained in:
25
capnp/async.h
Normal file
25
capnp/async.h
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#ifndef __PYX_HAVE__capnp__async
|
||||||
|
#define __PYX_HAVE__capnp__async
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __PYX_HAVE_API__capnp__async
|
||||||
|
|
||||||
|
#ifndef __PYX_EXTERN_C
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define __PYX_EXTERN_C extern "C"
|
||||||
|
#else
|
||||||
|
#define __PYX_EXTERN_C extern
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
__PYX_EXTERN_C DL_IMPORT(PyObject) *wrap_kj_exception( ::kj::Exception &);
|
||||||
|
|
||||||
|
#endif /* !__PYX_HAVE_API__capnp__async */
|
||||||
|
|
||||||
|
#if PY_MAJOR_VERSION < 3
|
||||||
|
PyMODINIT_FUNC initasync(void);
|
||||||
|
#else
|
||||||
|
PyMODINIT_FUNC PyInit_async(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* !__PYX_HAVE__capnp__async */
|
||||||
54
capnp/async.pyx
Normal file
54
capnp/async.pyx
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# capnp.pyx
|
||||||
|
# distutils: language = c++
|
||||||
|
# distutils: extra_compile_args = --std=c++11 -fpermissive
|
||||||
|
# distutils: libraries = kj
|
||||||
|
# cython: c_string_type = str
|
||||||
|
# cython: c_string_encoding = default
|
||||||
|
# cython: embedsignature = True
|
||||||
|
|
||||||
|
cimport cython
|
||||||
|
cimport async_cpp as async
|
||||||
|
from cpython.ref cimport PyObject, Py_INCREF, Py_DECREF
|
||||||
|
from cython.operator cimport dereference as deref
|
||||||
|
|
||||||
|
cdef extern from "<utility>" namespace "std":
|
||||||
|
async.PyPromise movePromise"std::move"(async.PyPromise)
|
||||||
|
|
||||||
|
# This is a really weird function. By making it public, we'll be able to call it from asyncHelper.h
|
||||||
|
cdef public object wrap_kj_exception(async.Exception & exception):
|
||||||
|
return None # TODO
|
||||||
|
|
||||||
|
cdef class EventLoop:
|
||||||
|
cdef async.SimpleEventLoop thisptr
|
||||||
|
|
||||||
|
cpdef evalLater(self, func):
|
||||||
|
Py_INCREF(func)
|
||||||
|
return Promise()._init(async.evalLater(self.thisptr, <PyObject *>func))
|
||||||
|
|
||||||
|
cdef wait(self, async.PyPromise * promise):
|
||||||
|
return self.thisptr.wait(movePromise(deref(promise)))
|
||||||
|
|
||||||
|
cdef there(self, async.PyPromise * promise, object func, object error_func):
|
||||||
|
Py_INCREF(func)
|
||||||
|
Py_INCREF(error_func)
|
||||||
|
return Promise()._init(async.there(self.thisptr, deref(promise), <PyObject *>func, <PyObject *>error_func))
|
||||||
|
|
||||||
|
|
||||||
|
cdef EventLoop c_event_loop = EventLoop()
|
||||||
|
event_loop = c_event_loop
|
||||||
|
|
||||||
|
cdef class Promise:
|
||||||
|
cdef async.PyPromise * thisptr
|
||||||
|
cdef _init(self, async.PyPromise other):
|
||||||
|
self.thisptr = new async.PyPromise(movePromise(other))
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __dealloc__(self):
|
||||||
|
del self.thisptr
|
||||||
|
|
||||||
|
def wait(self):
|
||||||
|
return c_event_loop.wait(self.thisptr)
|
||||||
|
|
||||||
|
def then(self, func, error_func=None):
|
||||||
|
return c_event_loop.there(self.thisptr, func, error_func)
|
||||||
|
|
||||||
25
capnp/asyncHelper.h
Normal file
25
capnp/asyncHelper.h
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#include "kj/async.h"
|
||||||
|
#include "Python.h"
|
||||||
|
#include <iostream>
|
||||||
|
extern "C" {
|
||||||
|
PyObject * wrap_kj_exception(kj::Exception &);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject * wrapPyFunc(PyObject * func, PyObject * arg) {
|
||||||
|
PyObject * result = PyObject_CallFunctionObjArgs(func, arg, NULL);
|
||||||
|
Py_DECREF(func);
|
||||||
|
Py_DECREF(arg);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
::kj::Promise<PyObject *> evalLater(kj::EventLoop & loop, PyObject * func) {
|
||||||
|
return loop.evalLater([func]() { return wrapPyFunc(func, NULL); } );
|
||||||
|
}
|
||||||
|
|
||||||
|
::kj::Promise<PyObject *> there(kj::EventLoop & loop, kj::Promise<PyObject *> & promise, PyObject * func, PyObject * error_func) {
|
||||||
|
if(error_func == Py_None)
|
||||||
|
return loop.there(kj::mv(promise), [func](PyObject * arg) { return wrapPyFunc(func, arg); } );
|
||||||
|
else
|
||||||
|
return loop.there(kj::mv(promise), [func](PyObject * arg) { return wrapPyFunc(func, arg); }
|
||||||
|
, [error_func](kj::Exception arg) { return wrapPyFunc(error_func, wrap_kj_exception(arg)); } );
|
||||||
|
}
|
||||||
31
capnp/async_cpp.pxd
Normal file
31
capnp/async_cpp.pxd
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# schema.capnp.cpp.pyx
|
||||||
|
# distutils: language = c++
|
||||||
|
# distutils: extra_compile_args = --std=c++11
|
||||||
|
|
||||||
|
from cpython.ref cimport PyObject
|
||||||
|
|
||||||
|
cdef extern from "kj/exception.h" namespace " ::kj":
|
||||||
|
cdef cppclass Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
cdef extern from "kj/async.h" namespace " ::kj":
|
||||||
|
cdef cppclass Promise[T]:
|
||||||
|
Promise(Promise)
|
||||||
|
T wait()
|
||||||
|
|
||||||
|
ctypedef Promise[PyObject *] PyPromise
|
||||||
|
|
||||||
|
cdef extern from "kj/async.h" namespace " ::kj":
|
||||||
|
cdef cppclass EventLoop:
|
||||||
|
EventLoop()
|
||||||
|
# Promise[void] yieldFrom'yield'()
|
||||||
|
object wait(PyPromise)
|
||||||
|
object there(PyPromise)
|
||||||
|
PyPromise evalLater(PyObject * func)
|
||||||
|
PyPromise there(PyPromise, PyObject * func)
|
||||||
|
cdef cppclass SimpleEventLoop(EventLoop):
|
||||||
|
pass
|
||||||
|
|
||||||
|
cdef extern from "asyncHelper.h":
|
||||||
|
PyPromise evalLater(EventLoop &, PyObject * func)
|
||||||
|
PyPromise there(EventLoop & loop, PyPromise & promise, PyObject * func, PyObject * error_func)
|
||||||
Reference in New Issue
Block a user