#include <xs/export.h>
#include <xs/unievent/Signal.h>
#include <xs/typemap/expected.h>
#include <xs/unievent/Listener.h>
#include <xs/CallbackDispatcher.h>
#include <xs/unievent/error.h>
using namespace xs;
using namespace xs::unievent;
using namespace panda::unievent;
using panda::string;
static PERL_ITHREADS_LOCAL struct {
Simple on_signal = Simple::shared("on_signal");
} cbn;
struct XSSignalListener : ISignalListener, XSListener {
void on_signal (const SignalSP& h, int signum) override {
call(cbn.on_signal, xs::out(h), Simple(signum));
}
};
MODULE = UniEvent::Signal PACKAGE = UniEvent::Signal
PROTOTYPES: DISABLE
BOOT {
Stash stash(__PACKAGE__);
stash.inherit("UniEvent::Handle");
stash.add_const_sub("TYPE", Simple(Signal::TYPE.name));
for (int i = 0; i < NSIG; ++i) {
auto name = Signal::signame(i);
if (name) xs::exp::create_constant(stash, name, i);
}
xs::exp::autoexport(stash);
xs::at_perl_destroy([]() { cbn.on_signal = nullptr; });
unievent::register_perl_class(Signal::TYPE, stash);
}
SignalSP create (SV* proto, int signum, Signal::signal_fn cb, DLoopSP loop = {}) {
PROTO = proto;
RETVAL = make_backref<Signal>(loop);
RETVAL->start(signum, cb);
}
SignalSP create_once (SV* proto, int signum, Signal::signal_fn cb, DLoopSP loop = {}) {
PROTO = proto;
RETVAL = make_backref<Signal>(loop);
RETVAL->once(signum, cb);
}
Signal* Signal::new (DLoopSP loop = {}) {
RETVAL = make_backref<Signal>(loop);
}
XSCallbackDispatcher* Signal::event () {
RETVAL = XSCallbackDispatcher::create(THIS->event);
}
void Signal::callback (Signal::signal_fn cb) {
THIS->event.remove_all();
if (cb) THIS->event.add(cb);
}
Ref Signal::event_listener (Sv lst = Sv(), bool weak = false) {
RETVAL = event_listener<XSSignalListener>(THIS, ST(0), lst, weak);
}
int Signal::signum ()
string signame (Sv obj_or_class_or_signum, SV* signum_sv = NULL) {
if (obj_or_class_or_signum.is_object_ref()) // $handle->signame()
RETVAL = xs::in<Signal*>(obj_or_class_or_signum)->signame();
else // $signal_class->signame($signum) or UniEvent::Signal::signame($signum)
RETVAL = Signal::signame(signum_sv ? SvIV(signum_sv) : SvIV(obj_or_class_or_signum));
}
void Signal::start (int signum, Signal::signal_fn cb = {}) {
XSRETURN_EXPECTED(THIS->start(signum, cb));
}
void Signal::once (int signum, Signal::signal_fn cb = {}) {
XSRETURN_EXPECTED(THIS->once(signum, cb));
}
void Signal::stop () {
XSRETURN_EXPECTED(THIS->stop());
}
void Signal::call_now (int signum)
SignalSP watch (SV* CLASS, int signum, Signal::signal_fn cb, LoopSP loop = {}) {
PROTO = CLASS;
if (!loop) loop = Loop::default_loop();
RETVAL = make_backref<Signal>(loop);
RETVAL->start(signum, cb);
}
MODULE = UniEvent::Signal PACKAGE = UniEvent
PROTOTYPES: DISABLE
SignalSP signal (int signum, Signal::signal_fn cb, DLoopSP loop = {}) {
RETVAL = make_backref<Signal>(loop);
RETVAL->start(signum, cb);
}
SignalSP signal_once (int signum, Signal::signal_fn cb, DLoopSP loop = {}) {
RETVAL = make_backref<Signal>(loop);
RETVAL->once(signum, cb);
}