include/rucy/extension.h.erb in rucy-0.1.8 vs include/rucy/extension.h.erb in rucy-0.1.9

- old
+ new

@@ -84,14 +84,14 @@ } \ Value \ value (native_class* obj, Value klass) \ { \ if (!obj) return nil(); \ - ClassWrapper<native_class>* p = dynamic_cast<ClassWrapper<native_class>*>(obj); \ - if (!p) return new_ref(klass, obj); \ - if (p->value.is_nil()) p->value = new_wrapper(klass, obj); \ - return p->value; \ + Value* pval = (Value*) obj->rucy_value(); \ + if (!pval) return new_ref(klass, obj); \ + if (pval->is_nil()) *pval = new_wrapper(klass, obj); \ + return *pval; \ } \ } #define RUCY_DEFINE_WRAPPER_VALUE_TO(native_class) \ namespace Rucy \ @@ -126,21 +126,23 @@ #define RUCY_WRAPPER_VALUE_FROM_TO(native_class) \ RUCY_DECLARE_WRAPPER_VALUE_FROM_TO(native_class) \ RUCY_DEFINE_WRAPPER_VALUE_FROM_TO(native_class) -#define RUCY_OVERRIDE_BEGIN(wrapper_class) \ - typedef wrapper_class RucyWrapper; \ - typedef RucyWrapper Super; \ - enum { OVERRIDE_ID_FIRST = RucyWrapper::OVERRIDE_ID_LAST - 1, +#define RUCY_OVERRIDE_BEGIN(super_class) \ + typedef super_class Super; \ + enum { OVERRIDE_ID_FIRST = super_class::OVERRIDE_ID_LAST - 1, #define RUCY_OVERRIDE_END \ OVERRIDE_ID_LAST }; #define RUCY_OVERRIDE_ID(name) \ OID_##name, +#define RUCY_IS_OVERRIDABLE() \ + this->is_overridable() + #define RUCY_IS_OVERRIDDEN(name) \ this->is_overridden(name, OID_##name) #define RUCY_TRY \ @@ -253,11 +255,11 @@ if (!p || !*p) Rucy::invalid_object_error(__FILE__, __LINE__); \ } \ while(0) #define RUCY_WRAPPER_CALL(native_class, obj, fun) \ - ((obj)->rucy_wrapped() ? (obj)->native_class::fun : (obj)->fun) + ((obj)->rucy_disable_override() ? (obj)->fun : (obj)->fun) namespace Rucy { @@ -285,11 +287,11 @@ typedef T RucyWrapped; GlobalValue value; ClassWrapper () - : value(nil(), true) + : value(nil(), true), overridable(true) { } virtual void retain (void* by_ruby_value = NULL) const { @@ -316,15 +318,32 @@ virtual void clear_override_flags () { override_flags.reset(); } + virtual bool is_overridable () const + { + if (!overridable) + { + overridable = true; + return false; + } + + return true; + } + virtual bool is_overridden (const Symbol& name, uint id) const { if (id <= OVERRIDE_ID_UNKNOWN) return false; + if (!overridable) + { + overridable = true; + return false; + } + bool checked = false, overridden = false; get_override_flag(&checked, &overridden, id); if (checked) return overridden; overridden = check_overridden(name); @@ -332,12 +351,18 @@ return false; return overridden; } - virtual bool rucy_wrapped () const + virtual void* rucy_value () const { + return (void*) &value; + } + + virtual bool rucy_disable_override () const + { + overridable = false; return true; } protected: @@ -364,14 +389,23 @@ private: mutable boost::dynamic_bitset<> override_flags; + mutable bool overridable; + bool check_overridden (const Symbol& name) const { RUCY_SYM(method); RUCY_SYM(owner); - return value.call(method, name.value()).call(owner) != get_ruby_class<RucyWrapped>(); + RUCY_SYM(instance_methods); + RUCY_SYM_Q(include); + RUCY_SYM(clear_override_flags); + return !value + .call(method, name.value()) + .call(owner) + .call(instance_methods, false) + .call(include, clear_override_flags.value()); } void get_override_flag (bool* checked, bool* overridden, uint id) const { assert(checked || overridden);