void registerDataType(VALUE klass, RUBY_DATA_FUNC freefunc, size_t (*sizefunc)(const void *)) { if(!NIL_P(klass)) { rb_data_type_t *parent = NULL; if(rb_obj_is_kind_of(klass, rb_cClass)) { parent = unwrapDataType(rb_class_superclass(klass)); //if the class does include EvtHandler, // add it as a parent if class doesnt already have one if(!parent && rb_class_inherited_p(klass, rb_mWXEvtHandler) == Qtrue) { parent = unwrapDataType(rb_mWXEvtHandler); } } rb_data_type_t str = { rb_class2name(klass), {0, freefunc, sizefunc,}, parent, NULL, }; datatypeholder[klass] = str; if(freefunc) { rb_data_type_t str_const = { (std::string(rb_class2name(klass)) + "(const)").c_str(), {0, 0, sizefunc,}, &datatypeholder[klass], NULL, }; datatypeholder_const[klass] = str_const; }else { datatypeholder_const[klass] = str; } } }
VALUE wrapTypedPtr(void *arg,VALUE klass, bool allowNull) { if(arg || allowNull){ rb_data_type_t* datatype = unwrapDataType(klass); if(!datatype) rb_fatal("%" PRIsVALUE " unknown datatype", RB_CLASSNAME(klass)); return TypedData_Wrap_Struct(klass, datatype, arg); } return Qnil; }
T* unwrapTypedPtr(const VALUE &obj,const VALUE &klass, rb_data_type_t* rbdata = NULL) { if(NIL_P(obj)) return NULL; if(rb_obj_is_instance_of(obj,rb_cClass) && rb_class_inherited(obj,klass)) { return unwrapTypedPtr<T>(rb_class_new_instance(0,NULL,obj), klass, rbdata); }else if (check_class(obj, klass)){ return (T*)unwrapTypedPtr(obj, rbdata ? rbdata : unwrapDataType(klass)); }else{ return NULL; } }
rb_data_type_t* unwrapDataType(const VALUE& klass) { if(klass == rb_cObject) return NULL; datatypeholdertype::iterator it = datatypeholder.find(klass); if(it != datatypeholder.end()) return &it->second; for(it = datatypeholder.begin(); it != datatypeholder.end(); ++it) { if(wxString(rb_class2name(it->first)) == wxString(rb_class2name(klass))) { //rb_warn("compare broken for %s", rb_class2name(klass)); return &it->second; } } if(rb_obj_is_kind_of(klass, rb_cClass)) return unwrapDataType(rb_class_superclass(klass)); return NULL; }