* Added an implicit type conversion operator so that a PlasmaScripting.Applet
[kdebindings.git] / ruby / krossruby / rubyobject.cpp
blob22323116054ce120cae5301cd8a86a50c8c8f2a2
1 /***************************************************************************
2 * rubyobject.cpp
3 * This file is part of the KDE project
4 * copyright (C)2004-2005 by Sebastian Sauer (mail@dipe.org)
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public License
15 * along with this program; see the file COPYING. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 ***************************************************************************/
20 #include "rubyobject.h"
21 #include "rubyvariant.h"
23 using namespace Kross;
25 static VALUE callExecuteException(VALUE self, VALUE error)
27 #ifdef KROSS_RUBY_OBJECT_DEBUG
28 krossdebug( QString("RubyScript::callExecuteException script=%1 error=%2")
29 .arg( STR2CSTR(rb_inspect(self)) ).arg( STR2CSTR(rb_inspect(error)) ) );
30 #else
31 Q_UNUSED(self);
32 Q_UNUSED(error);
33 #endif
35 VALUE info = rb_gv_get("$!");
36 VALUE bt = rb_funcall(info, rb_intern("backtrace"), 0);
37 VALUE message = RARRAY(bt)->ptr[0];
39 QString errormessage = QString("%1: %2 (%3)")
40 .arg( STR2CSTR(message) )
41 .arg( STR2CSTR(rb_obj_as_string(info)) )
42 .arg( rb_class2name(CLASS_OF(info)) );
43 fprintf(stderr, "%s\n", errormessage.toLatin1().data());
45 QString tracemessage;
46 for(int i = 1; i < RARRAY(bt)->len; ++i) {
47 if( TYPE(RARRAY(bt)->ptr[i]) == T_STRING ) {
48 QString s = QString("%1\n").arg( STR2CSTR(RARRAY(bt)->ptr[i]) );
49 Q_ASSERT( ! s.isNull() );
50 tracemessage += s;
51 fprintf(stderr, "\t%s", s.toLatin1().data());
55 ruby_nerrs++;
57 VALUE rubyscriptvalue = rb_funcall(self, rb_intern("const_get"), 1, ID2SYM(rb_intern("RUBYSCRIPTOBJ")));
58 RubyScript* rubyscript;
59 Data_Get_Struct(rubyscriptvalue, RubyScript, rubyscript);
60 Q_ASSERT(rubyscript);
61 rubyscript->setError(errormessage, tracemessage);
63 return Qnil;
66 static VALUE callFunction2(VALUE args)
68 #ifdef KROSS_RUBY_OBJECT_DEBUG
69 krossdebug( QString("RubyObject::callFunction2 args=%1").arg( STR2CSTR(rb_inspect(args)) ) );
70 #endif
71 Q_ASSERT( TYPE(args) == T_ARRAY );
72 VALUE self = rb_ary_entry(args, 0);
73 Q_ASSERT( ! NIL_P(self) );
74 ID functionId = rb_ary_entry(args, 1);
75 VALUE arguments = rb_ary_entry(args, 2);
76 Q_ASSERT( TYPE(arguments) == T_ARRAY );
77 return rb_funcall2(self, functionId, RARRAY(arguments)->len, RARRAY(arguments)->ptr);
80 class RubyObject::Private
82 public:
83 Private() : rbobject(0) {};
84 Private(const VALUE& object) : rbobject(object) {};
85 const VALUE rbobject;
86 QStringList calls;
87 #ifdef KROSS_RUBY_OBJECT_DEBUG
88 QString debug;
89 #endif
92 RubyObject::RubyObject()
93 : Kross::Object()
94 , d(new Private)
96 #ifdef KROSS_RUBY_OBJECT_DEBUG
97 d->debug = QString("type=NIL");
98 krossdebug( QString("RubyObject::RubyObject() constructor: %1").arg(d->debug) );
99 #endif
102 RubyObject::RubyObject(const VALUE& object)
103 : Kross::Object()
104 , d(new Private(object))
106 #ifdef KROSS_RUBY_OBJECT_DEBUG
107 d->debug = QString("type=%1 value=%2").arg(TYPE(object)).arg(STR2CSTR(rb_inspect(object)));
108 krossdebug( QString("RubyObject::RubyObject(const VALUE& object) constructor: %1").arg(d->debug) );
109 #endif
111 VALUE args[] = { Qfalse };
112 VALUE methods;
113 const char* method;
114 methods = rb_class_instance_methods(1, args, CLASS_OF(object));
115 for (int i = 0; i < RARRAY(methods)->len; i++) {
116 method = StringValuePtr(RARRAY(methods)->ptr[i]);
117 krossdebug( QString("RubyObject::RubyObject() method=%1").arg( method ));
118 d->calls << method;
122 RubyObject::~RubyObject()
124 #ifdef KROSS_RUBY_OBJECT_DEBUG
125 krossdebug( QString("RubyObject::~RubyObject() destructor: %1").arg(d->debug) );
126 #endif
127 delete d;
130 QVariant RubyObject::callMethod(const QString& name, const QVariantList& args)
132 #ifdef KROSS_RUBY_OBJECT_DEBUG
133 krossdebug( QString("RubyObject::call(%1): %2").arg(name).arg(d->debug) );
134 #endif
136 QVariant result;
137 const int rnargs = args.size();
138 VALUE *rargs = new VALUE[rnargs];
139 for(int i = 0; i < rnargs; ++i) {
140 rargs[i] = RubyType<QVariant>::toVALUE( args[i] );
143 VALUE vargs = rb_ary_new2(3);
144 rb_ary_store(vargs, 0, d->rbobject); //self
145 rb_ary_store(vargs, 1, rb_intern(name.toLatin1()));
146 rb_ary_store(vargs, 2, rb_ary_new4(rnargs, rargs));
147 VALUE v = rb_rescue2((VALUE(*)(...))callFunction2, vargs, (VALUE(*)(...))callExecuteException, d->rbobject, rb_eException, 0);
148 result = RubyType<QVariant>::toVariant(v);
150 delete[] rargs;
151 return result;
154 QStringList RubyObject::methodNames()
156 return d->calls;
159 VALUE RubyObject::rbObject()
161 return d->rbobject;