Files
project_misth/include/binding/ruby.h
T

120 lines
3.5 KiB
C++

#ifndef RUBY_H
#define RUBY_H
#include "pch.h"
#include "utils.h"
#define DEF_SYM(name) inline mrb_sym sym_##name = mrb_intern_cstr(Ruby::mrb, #name);
#define SYM(name) mrb_symbol_value(sym_##name)
#define HASH_GET(h, key) mrb_hash_get(Ruby::mrb, h, SYM(key))
#define HASH_FLOAT(h, key, out) \
do { \
mrb_value v = HASH_GET(h, key); \
if (mrb_fixnum_p(v)) \
out = (float)mrb_fixnum(v); \
} while (0)
#define HASH_BOOL(h, key, out) \
do { \
mrb_value v = HASH_GET(h, key); \
if (!mrb_nil_p(v)) \
out = mrb_bool(v); \
} while (0)
struct Wrapper {
int id;
};
#define DEF_RB(NAME, FN_FREE, FN_INIT) \
static void NAME##_free(mrb_state *mrb, void *ptr) { \
UNUSED(mrb); \
int id = ((Wrapper *)ptr)->id; \
FN_FREE; \
delete (Wrapper *)ptr; \
} \
static const struct mrb_data_type NAME##_type = { \
#NAME, \
NAME##_free \
}; \
static mrb_value NAME##_init(mrb_state *mrb, mrb_value self) { \
UNUSED(mrb); \
Wrapper *s = new Wrapper(); \
FN_INIT; \
DATA_PTR(self) = s; \
DATA_TYPE(self) = &NAME##_type; \
return self; \
}
#define ADD_METHOD(NAME, METHOD, FUNC, ARGS) \
mrb_define_method(Ruby::mrb, NAME##_class, METHOD, FUNC, ARGS);
#define DEF_CLASS(NAME, ARGS) \
RClass *NAME##_class = mrb_define_class(Ruby::mrb, #NAME, Ruby::mrb->object_class); \
ADD_METHOD(NAME, "initialize", NAME##_init, ARGS);
#define DEF_MODULE(NAME) \
RClass *NAME##_module = mrb_define_module(Ruby::mrb, #NAME);
#define ADD_MODULE_METHOD(MODULE, METHOD, FUNC, ARGS) \
mrb_define_class_method(Ruby::mrb, MODULE##_module, METHOD, FUNC, ARGS);
inline int get_id(mrb_value self) {
return ((Wrapper *)DATA_PTR(self))->id;
}
namespace Ruby {
inline mrb_state *mrb = mrb_open();
struct Block {
mrb_value proc;
Block(mrb_value proc) : proc(proc) {
mrb_gc_register(mrb, proc);
}
Block() : proc(mrb_nil_value()) {}
void set_proc(mrb_value new_proc) {
if (!mrb_nil_p(proc))
mrb_gc_unregister(mrb, proc);
proc = new_proc;
if (!mrb_nil_p(proc))
mrb_gc_register(mrb, proc);
}
Block(const Block &) = delete;
Block &operator=(const Block &) = delete;
mrb_value call(int argc = 0, mrb_value *argv = nullptr) const {
if (mrb_nil_p(proc))
return mrb_nil_value();
return mrb_funcall(mrb, proc, "call", argc, argv);
}
~Block() {
mrb_gc_unregister(mrb, proc);
}
};
inline void run_string(const char *code, size_t length) {
int ai = mrb_gc_arena_save(mrb);
mrb_load_nstring(mrb, code, length);
mrb_gc_arena_restore(mrb, ai);
}
}; // namespace Ruby
DEF_SYM(pixel_art)
DEF_SYM(bold)
DEF_SYM(italic)
DEF_SYM(underline)
DEF_SYM(position)
DEF_SYM(click_through)
DEF_SYM(x)
DEF_SYM(y)
DEF_SYM(w)
DEF_SYM(h)
DEF_SYM(z)
#endif