-
-
Save mattn/2428308 to your computer and use it in GitHub Desktop.
mruby & libuv
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <mruby.h> | |
#include <mruby/proc.h> | |
#include <mruby/data.h> | |
#include <compile.h> | |
#include <variable.h> | |
#include <uv.h> | |
typedef struct { | |
mrb_state* mrb; | |
mrb_value proc; /* callback */ | |
void* data; /* uv pointer */ | |
} mrb_uv_data; | |
static void | |
uv_handle_free(mrb_state *mrb, void *p) | |
{ | |
uv_close((uv_handle_t*) ((mrb_uv_data*)p)->data, NULL); | |
free(((mrb_uv_data*)p)->data); | |
} | |
static const struct mrb_data_type uv_handle_data_type = { | |
"uv_handle", uv_handle_free, | |
}; | |
static mrb_value | |
mrb_uv_run(mrb_state *mrb, mrb_value self) | |
{ | |
if (uv_run(uv_default_loop()) != 0) { | |
mrb_raise(mrb, E_SYSTEMCALL_ERROR, uv_strerror(uv_last_error(uv_default_loop()))); | |
} | |
return mrb_nil_value(); | |
} | |
static mrb_value | |
mrb_uv_timer_init(mrb_state *mrb, mrb_value self) | |
{ | |
mrb_uv_data* uvdata = (mrb_uv_data*) malloc(sizeof(mrb_uv_data)); | |
uvdata->mrb = mrb; | |
uvdata->data = malloc(sizeof(uv_timer_t)); | |
uvdata->proc = mrb_nil_value(); | |
if (uv_timer_init(uv_default_loop(), (uv_timer_t*) uvdata->data) != 0) { | |
mrb_raise(mrb, E_SYSTEMCALL_ERROR, uv_strerror(uv_last_error(uv_default_loop()))); | |
} | |
mrb_iv_set(mrb, self, mrb_intern(mrb, "data"), mrb_obj_value( | |
Data_Wrap_Struct(mrb, (struct RClass*) &self, | |
&uv_handle_data_type, (void*) uvdata))); | |
return self; | |
} | |
void | |
_uv_timer_cb(uv_timer_t* timer, int status) | |
{ | |
mrb_uv_data* uvdata = (mrb_uv_data*) timer->data; | |
mrb_yield(uvdata->mrb, uvdata->proc, mrb_fixnum_value(status)); | |
} | |
static mrb_value | |
mrb_uv_timer_start(mrb_state *mrb, mrb_value self) | |
{ | |
mrb_value value; | |
mrb_uv_data* uvdata; | |
struct RProc *b; | |
mrb_value argc, *argv; | |
int nargs; | |
mrb_get_args(mrb, "b*", &b, &argv, &argc); | |
value = mrb_iv_get(mrb, self, mrb_intern(mrb, "data")); | |
Data_Get_Struct(mrb, value, &uv_handle_data_type, uvdata); | |
uvdata->proc = mrb_obj_value(b); | |
((uv_timer_t*) uvdata->data)->data = uvdata; | |
if (uv_timer_start((uv_timer_t*) uvdata->data, _uv_timer_cb, | |
mrb_fixnum(argv[0]), mrb_fixnum(argv[1])) != 0) { | |
mrb_raise(mrb, E_SYSTEMCALL_ERROR, uv_strerror(uv_last_error(uv_default_loop()))); | |
} | |
return mrb_nil_value(); | |
} | |
static mrb_value | |
mrb_uv_timer_stop(mrb_state *mrb, mrb_value self) | |
{ | |
mrb_value value; | |
mrb_uv_data* uvdata; | |
struct RProc *b; | |
mrb_value argc, *argv; | |
int nargs; | |
value = mrb_iv_get(mrb, self, mrb_intern(mrb, "data")); | |
Data_Get_Struct(mrb, value, &uv_handle_data_type, uvdata); | |
if (uv_timer_stop((uv_timer_t*) uvdata->data) != 0) { | |
mrb_raise(mrb, E_SYSTEMCALL_ERROR, uv_strerror(uv_last_error(uv_default_loop()))); | |
} | |
return mrb_nil_value(); | |
} | |
int | |
main() | |
{ | |
int n; | |
mrb_state* mrb; | |
struct mrb_parser_state* st; | |
struct RClass *uv, *uv_timer; | |
mrb = mrb_open(); | |
uv = mrb_define_module(mrb, "UV"); | |
mrb_define_class_method(mrb, uv, "run", mrb_uv_run, ARGS_REQ(1)); | |
uv_timer = mrb_define_class_under(mrb, uv, "Timer", mrb_class_obj_get(mrb, "Object")); | |
mrb_define_method(mrb, uv_timer, "initialize", mrb_uv_timer_init, ARGS_ANY()); | |
mrb_define_method(mrb, uv_timer, "start", mrb_uv_timer_start, ARGS_REQ(3)); | |
mrb_define_method(mrb, uv_timer, "stop", mrb_uv_timer_stop, ARGS_REQ(1)); | |
{ | |
char* code = | |
"require 'UV' \n" | |
"t = UV::Timer.new() \n" | |
"t.start(1000, 1000) {|x| \n" | |
" p x \n" | |
"} \n" | |
"p UV.run() \n"; | |
st = mrb_parse_string(mrb, code); | |
n = mrb_generate_code(mrb, st->tree); | |
mrb_pool_close(st->pool); | |
mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_nil_value()); | |
} | |
} | |
/* vim:set et ts=2 sts=2 sw=2 tw=0: */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment