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);