1 /***************************************************************************
3 * This file is part of the KDE project
4 * copyright (C)2005 by Cyrille Berger (cberger@cberger.net)
5 * copyright (C)2006 by Sebastian Sauer (mail@dipe.org)
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public License
16 * along with this program; see the file COPYING. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 ***************************************************************************/
21 #include "rubymodule.h"
22 #include "rubyextension.h"
26 using namespace Kross
;
31 class RubyModulePrivate
{
32 friend class RubyModule
;
34 /// The name the module has.
37 /// The \a RubyExtension instance that implements this \a RubyModule .
38 RubyExtension
* extension
;
43 RubyModule::RubyModule(QObject
* parent
, QObject
* object
, const QString
& modname
)
45 , d(new RubyModulePrivate())
49 d
->modulename
= modname
.left(1).toUpper() + modname
.right(modname
.length() - 1 );
50 #ifdef KROSS_RUBY_MODULE_CTORDTOR_DEBUG
51 krossdebug(QString("RubyModule Ctor: %1").arg(d
->modulename
));
54 d
->extension
= new RubyExtension(object
);
55 VALUE rmodule
= rb_define_module(d
->modulename
.toAscii());
56 rb_define_module_function(rmodule
,"method_missing", (VALUE (*)(...))RubyModule::method_missing
, -1);
57 VALUE extension
= RubyExtension::toVALUE(d
->extension
, /*owner*/ false);
58 rb_define_const(rmodule
, "MODULEOBJ", extension
);
61 RubyModule::~RubyModule()
63 #ifdef KROSS_RUBY_MODULE_CTORDTOR_DEBUG
64 krossdebug(QString("RubyModule Dtor: %1").arg(d
->modulename
));
71 RubyExtension
* RubyModule::extension() const
76 VALUE
RubyModule::method_missing(int argc
, VALUE
*argv
, VALUE self
)
78 #ifdef KROSS_RUBY_MODULE_DEBUG
79 QString funcname
= rb_id2name(SYM2ID(argv
[0]));
80 krossdebug(QString("RubyModule::method_missing \"%1\" missing, redirect to RubyExtension").arg(funcname
));
83 //old kde3/kross1 code
85 VALUE rubyObjectModule = rb_funcall( self, rb_intern("const_get"), 1, ID2SYM(rb_intern("MODULEOBJ")) );
86 RubyModule* objectModule;
87 Data_Get_Struct(rubyObjectModule, RubyModule, objectModule);
88 //QObject* object = objectModule->d->object; //dynamic_cast<QObject*>(objectModule->d->object);
89 //return RubyExtension::call_method(object, argc, argv);
90 RubyExtension* extension = objectModule->d->extension;
92 return RubyExtension::call_method(extension, argc, argv);
95 //the following solution works quit well, but does not take e.g. the connect() call into account
97 VALUE extensionvalue = rb_funcall( self, rb_intern("const_get"), 1, ID2SYM(rb_intern("MODULEOBJ")) );
98 RubyExtension* extension;
99 Data_Get_Struct(extensionvalue, RubyExtension, extension);
101 return RubyExtension::call_method_missing(extension, argc, argv, self);
104 //fetch the RubyExtension instance this module uses
105 VALUE extensionvalue
= rb_funcall( self
, rb_intern("const_get"), 1, ID2SYM(rb_intern("MODULEOBJ")) );
106 //redirect the call to our RubyExtension instance
107 return rb_funcall2(extensionvalue
, SYM2ID(argv
[0]), argc
-1, argc
> 0 ? &argv
[1] : 0);