* use cell for tables!!


glEnable(GL_LINE_SMOOTH)

* use PhysFS instead of direct file loading


FIXME: 
* mGLMode should be set correctly
* STUBS must be filled
* AGSurfacePainter should be tested in gl and sdl-mode

* Window fails correct drawing

ComboBox
Menu(Item)
List(Item)
ScrollArea (without Scrollers)
Scroller
ScrollWidget (Widget with Scroller & scrollarea)
RadioButton
CheckButton
Window
MessageBox/Dialog
RichEdit


* interface.i exception for all subclasses of widget!!!
* through include-file generated by makefile


=============================================================

garbage collection for RUBY (is already implemented):
see ag_widget.cc // mark-function



and interface.i // make reference

a solution could be:
[Swig] ruby mark 

lyle@knology.net lyle@knology.net 
 8 May 2003 13:40:04 -0000 

Previous message: [Swig] You are hot! 
Next message: [Swig] ruby mark 
Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] 
 
On 08 May 2003 05:14:42 -0400, Steve Hart <stevehart@beeb.net> wrote :

> I have a question relating to ruby and garbage collection. I am wrapping
> up a c++ API and would like to know how to obtain a VALUE reference for
> a previously created ruby instance variable. Specifically, I need to
> mark this VALUE to prevent ruby's GC'ing it. I guess what I really need
> is an idea of how to implement the  'SWIG_RubyInstanceFor' function
> outlined at the end of section 20.8.5 of the swig ruby doc.

I have thought about adding this facility to SWIG's Ruby module, because I
think it would be generally useful. Maybe I can work something up before the
SWIG 1.3.20 release.

> I could pass the VALUE created back into the c++ code but this would
> require an extra call within the ruby script i.e. 
> 
> class Test1 < Gm::GMScript 
> 
>         def initialize() 
>               super() 
>               nodeVal = Gm::GMTransformNode.new("trsNode") 
>               nodeVal.storeVal(nodeVal) 
>       end 
>       . 
>       . 
> end

No, we can do better than that ;)
 
> I could then mark this value in the swig define mark function. What
> would be nicer though, would to be able to obtain the VALUE
> automatically from the Test1 Script instance (which I do store c++ side)
> I looked through FXRuby and it looks like this creates it's own st_table
> which is a bit overkill for my app. Is there a way of using rb_iv_get to
> retrieve VALUE's. 

The problem that you have is that Ruby's garbage collector is going to be
calling rb_gc_mark() and passing in pointers to your C++ objects; it does
not tell you which Ruby instance triggered the call. And so, for a given C++
object, you need some way to find the Ruby instance (i.e. the VALUE)
associated with that C++ object.

If you have the option of modifying the source code, the easiest way (I
think) is to just add an extra member variable (of type VALUE) to the class
that stores the Ruby instance, e.g.

    class GMTransformNode
    {
    public:
        VALUE rubyInstance;
    public:
        GMTransformNode(const char *name);
    };

    class GMScript
    {
    public:
        VALUE rubyInstance;
    public:
        GMScript();
    };

You can then initialize these values by using SWIG's %exception directive to
attach some code to the wrapped class constructors:

    %exception GMTransformNode::GMTransformNode {
        $action
        result->rubyInstance = self;
    }

    %exception GMScript::GMScript {
        $action
        result->rubyInstance = self;
    }

Now, in your mark function, you can get to the Ruby objects directly from
their C++ brethren. The relationship between GMScript and GMTransformNode
objects wasn't clear from your example, but for argument's sake let's say
that a script maintains an array of nodes, e.g.

    class GMScript
    {
    public:
        VALUE rubyInstance;
        int numNodes;
        GMTransformNode *nodes;
    public:
        GMScript();
    };

and you want to make sure that Ruby's garbage collector knows that those
GMNode instances (on the Ruby side) are still reachable. In this case, the
"mark" function for your GMScript would look something like this:

    void mark_GMScript(GMScript *script)
    {
        int i;
        for (i = 0; i < script->numNodes; i++) {
            rb_gc_mark( script->nodes[i].rubyInstance );
        }
    }

Now, I can't use this technique with FXRuby, because I can't (or rather,
don't want to) modify the sources. So in my case, it is a little more
complicated -- as you said, I store the C++-to-Ruby mapping in a hash table
instead. [And I think that's what a general purpose SWIG_RubyInstanceFor()
function would have to do as well, store this mapping in some data structure
outside of the C++ objects themselves.] But the basic principle's the same.

Hope this helps,

Lyle


