Go to the documentation of this file.00001 #ifndef __RUBY_EXT_TYPELIB_HH__
00002 #define __RUBY_EXT_TYPELIB_HH__
00003
00004 #include <ruby.h>
00005 #include <typelib/typemodel.hh>
00006 #include <typelib/value.hh>
00007 #include <typelib/registry.hh>
00008
00009 #include "typelib_ruby.hh"
00010
00011 #undef VERBOSE
00012
00013 namespace typelib_ruby {
00014 extern VALUE cType;
00015 extern VALUE cIndirect;
00016 extern VALUE cPointer;
00017 extern VALUE cArray;
00018 extern VALUE cCompound;
00019 extern VALUE cNumeric;
00020 extern VALUE cEnum;
00021 extern VALUE cContainer;
00022 extern VALUE cOpaque;
00023 extern VALUE cNull;
00024 extern VALUE cRegistry;
00025 extern VALUE cMetaData;
00026
00027 extern VALUE eNotFound;
00028
00030 extern void Typelib_init_memory();
00031 extern void Typelib_init_values();
00032 extern void Typelib_init_strings();
00033 extern void Typelib_init_specialized_types();
00034 extern void Typelib_init_registry();
00035 extern void Typelib_init_metadata();
00036
00037 namespace cxx2rb {
00038 using namespace Typelib;
00039
00040 typedef std::map<Type const*, std::pair<bool, VALUE> > WrapperMap;
00041
00042 struct RbRegistry
00043 {
00044 boost::shared_ptr<Typelib::Registry> registry;
00055 cxx2rb::WrapperMap wrappers;
00056
00057 RbRegistry(Typelib::Registry* registry)
00058 : registry(registry) {}
00059 ~RbRegistry() {}
00060 };
00061
00062 VALUE class_of(Type const& type);
00063
00064 template<typename T> VALUE class_of();
00065 template<> inline VALUE class_of<Value>() { return cType; }
00066 template<> inline VALUE class_of<Type>() { return rb_cClass; }
00067 template<> inline VALUE class_of<RbRegistry>() { return cRegistry; }
00068 template<> inline VALUE class_of<MetaData>() { return cMetaData; }
00069
00070 VALUE type_wrap(Type const& type, VALUE registry);
00071 VALUE metadata_wrap(MetaData& metadata);
00072
00073
00074
00075
00076 inline VALUE enum_symbol(Enum::integral_type value, Enum const& e)
00077 {
00078 try {
00079 std::string symbol = e.get(value);
00080 return ID2SYM(rb_intern(symbol.c_str()));
00081 }
00082 catch(Enum::ValueNotFound) { return Qnil; }
00083 }
00084
00085 VALUE value_wrap(Value v, VALUE registry, VALUE parent = Qnil);
00086 }
00087
00088 namespace rb2cxx {
00089 using namespace Typelib;
00090
00091 inline void check_is_kind_of(VALUE self, VALUE expected)
00092 {
00093 if (! rb_obj_is_kind_of(self, expected))
00094 rb_raise(rb_eTypeError, "expected %s, got %s", rb_class2name(expected), rb_obj_classname(self));
00095 }
00096
00097 template<typename T>
00098 T& get_wrapped(VALUE self)
00099 {
00100 void* object = 0;
00101 Data_Get_Struct(self, void, object);
00102 return *reinterpret_cast<T*>(object);
00103 }
00104
00105 template<typename T>
00106 T& object(VALUE self)
00107 {
00108 check_is_kind_of(self, cxx2rb::class_of<T>());
00109 return get_wrapped<T>(self);
00110 }
00111
00112 template<> inline Registry& object(VALUE self)
00113 {
00114 return *object<cxx2rb::RbRegistry>(self).registry;
00115 }
00116
00117 template<>
00118 inline Type& object(VALUE self)
00119 {
00120 check_is_kind_of(self, rb_cClass);
00121 VALUE type = rb_iv_get(self, "@type");
00122 return get_wrapped<Type>(type);
00123 }
00124
00125 Enum::integral_type enum_value(VALUE rb_value, Enum const& e);
00126 }
00127
00128 class RubyGetter : public Typelib::ValueVisitor
00129 {
00130 protected:
00131 VALUE m_value;
00132 VALUE m_registry;
00133 VALUE m_parent;
00134
00135 bool visit_ (int8_t & value);
00136 bool visit_ (uint8_t & value);
00137 bool visit_ (int16_t & value);
00138 bool visit_ (uint16_t& value);
00139 bool visit_ (int32_t & value);
00140 bool visit_ (uint32_t& value);
00141 bool visit_ (int64_t & value);
00142 bool visit_ (uint64_t& value);
00143 bool visit_ (float & value);
00144 bool visit_ (double & value);
00145
00146 bool visit_(Typelib::Value const& v, Typelib::Pointer const& p);
00147 bool visit_(Typelib::Value const& v, Typelib::Array const& a);
00148 bool visit_(Typelib::Value const& v, Typelib::Compound const& c);
00149 bool visit_(Typelib::Value const& v, Typelib::Container const& c);
00150 bool visit_(Typelib::Value const& v, Typelib::OpaqueType const& c);
00151 bool visit_(Typelib::Enum::integral_type& v, Typelib::Enum const& e);
00152
00153 public:
00154 RubyGetter();
00155 ~RubyGetter();
00156
00157 VALUE apply(Typelib::Value value, VALUE registry, VALUE parent);
00158 };
00159
00160 class RubySetter : public Typelib::ValueVisitor
00161 {
00162 protected:
00163 VALUE m_value;
00164
00165 bool visit_ (int8_t & value);
00166 bool visit_ (uint8_t & value);
00167 bool visit_ (int16_t & value);
00168 bool visit_ (uint16_t& value);
00169 bool visit_ (int32_t & value);
00170 bool visit_ (uint32_t& value);
00171 bool visit_ (int64_t & value);
00172 bool visit_ (uint64_t& value);
00173 bool visit_ (float & value);
00174 bool visit_ (double & value);
00175
00176 bool visit_(Typelib::Value const& v, Typelib::Pointer const& p);
00177 bool visit_(Typelib::Value const& v, Typelib::Array const& a);
00178 bool visit_(Typelib::Value const& v, Typelib::Compound const& c);
00179 bool visit_(Typelib::Value const& v, Typelib::Container const& c);
00180 bool visit_(Typelib::Value const& v, Typelib::OpaqueType const& c);
00181 bool visit_(Typelib::Enum::integral_type& v, Typelib::Enum const& e);
00182
00183 public:
00184 RubySetter();
00185 ~RubySetter();
00186
00187 VALUE apply(Typelib::Value value, VALUE new_value);
00188 };
00189
00190 extern VALUE value_get_registry(VALUE self);
00191 extern VALUE type_get_registry(VALUE self);
00192 extern bool memory_ref(void* ptr);
00193 extern void memory_unref(void* ptr);
00194 extern void memory_delete(void* ptr);
00195 extern VALUE memory_wrap(void* ptr, bool take_ownership, void* root_ptr);
00196 extern VALUE memory_allocate(size_t size);
00197 extern void memory_init(VALUE ptr, VALUE type);
00198 extern void* memory_cptr(VALUE ptr);
00199 }
00200
00201 #endif
00202