#include "class.h" #include #include "defs.h" using namespace Rucy; static Class cBase, cSub, cSimpleObj; namespace Rucy { template <> inline Class get_ruby_class () {return cBase;} template <> inline Class get_ruby_class () {return cSub;} template <> inline Class get_ruby_class () {return cSimpleObj;} }// Rucy RUCY_WRAPPER_VALUE_FROM_TO(RUCY_EXPORT, Base) RUCY_WRAPPER_VALUE_FROM_TO(RUCY_EXPORT, Sub) RUCY_WRAPPER_VALUE_FROM_TO(RUCY_EXPORT, SimpleObj) template class RubyBase : public ClassWrapper { typedef ClassWrapper Super; public: virtual const char* name_overridable () const { RUCY_SYM(name_overridable); if (this->is_overridable()) return this->value.call(name_overridable).c_str(); else return Super::name_overridable(); } };// RubyBase #define THIS(type) to(self) #define CHECK(type) RUCY_CHECK_OBJ(type, self) #define CALL(obj, fun) RUCY_CALL_SUPER(obj, fun) /* alloc function. */ static VALUE base_alloc(VALUE klass) { return value(new RubyBase, klass); } static VALUE name(VALUE self) { CHECK(Base); return value(THIS(Base)->name()); } static VALUE call_name(VALUE self) { CHECK(Base); return value(THIS(Base)->name()); } static VALUE base_name_overridable(VALUE self) { CHECK(Base); return value(CALL(THIS(Base), name_overridable())); } static VALUE call_name_overridable(VALUE self) { CHECK(Base); return value(THIS(Base)->name_overridable()); } static VALUE base_new_raw(VALUE self) { return value(new Base); } /* alloc function. */ static VALUE sub_alloc(VALUE klass) { return value(new RubyBase, klass); } static VALUE sub_name_overridable(VALUE self) { CHECK(Sub); return value(CALL(THIS(Sub), name_overridable())); } static VALUE sub_new_raw(VALUE self) { return value(new Sub); } /* alloc function. */ static VALUE simpleobj_alloc(VALUE klass) { return value(new ClassWrapper, klass); } static VALUE simpleobj_initialize(VALUE self, VALUE name) { CHECK(SimpleObj); THIS(SimpleObj)->init(name.c_str()); } static std::vector> simpleobj_refs; static VALUE simpleobj_set_refs(VALUE self, VALUE objs) { int size = objs.size(); for (int i = 0; i < size; ++i) simpleobj_refs.push_back(to(objs[i])); return objs; } static VALUE simpleobj_clear_refs(VALUE self) { simpleobj_refs.clear(); } void Init_class () { Module mRucy = rb_define_module("Rucy"); Module mTester = rb_define_module_under(mRucy, "Tester"); cBase = rb_define_class_under(mTester, "Base", rb_cObject); rb_define_alloc_func(cBase, base_alloc); rb_define_method(cBase, "name", RUBY_METHOD_FUNC(name), 0); rb_define_method(cBase, "name_overridable", RUBY_METHOD_FUNC(base_name_overridable), 0); rb_define_method(cBase, "call_name", RUBY_METHOD_FUNC(call_name), 0); rb_define_method(cBase, "call_name_overridable", RUBY_METHOD_FUNC(call_name_overridable), 0); rb_define_singleton_method(cBase, "new_raw", RUBY_METHOD_FUNC(base_new_raw), 0); cSub = rb_define_class_under(mTester, "Sub", cBase); rb_define_alloc_func(cSub, sub_alloc); rb_define_method(cSub, "name_overridable", RUBY_METHOD_FUNC(sub_name_overridable), 0); rb_define_singleton_method(cSub, "new_raw", RUBY_METHOD_FUNC(sub_new_raw), 0); cSimpleObj = rb_define_class_under(mTester, "SimpleObj", rb_cObject); rb_define_alloc_func(cSimpleObj, simpleobj_alloc); rb_define_private_method(cSimpleObj, "initialize", RUBY_METHOD_FUNC(simpleobj_initialize), 1); rb_define_module_function(cSimpleObj, "set_refs", RUBY_METHOD_FUNC(simpleobj_set_refs), 1); rb_define_module_function(cSimpleObj, "clear_refs", RUBY_METHOD_FUNC(simpleobj_clear_refs), 0); }