"Simon Strandgaard" <0bz63fz3m1qt3001 / sneakemail.com> wrote in message news:<pan.2003.04.10.03.26.14.705399 / sneakemail.com>...
> On Wed, 09 Apr 2003 17:56:52 +0000, Steve Hart wrote:
> > 
> > int main()
> > {
> >         GMScript                *ptr = NULL;
> >         int                     state = 0;
> >         VALUE                   vTclass;
> >         VALUE                   tObj;
> >         vector<GMScript *>      stack;
> 
> Suggestion for improving your code-readability:
> Move your variable-declaration down to where they are
> being used for the first time.  
> 
>  
> >         ruby_init();
> >         ruby_script("embedded");
> >         ruby_init_loadpath();
> >         rb_require("gm.so");
> 
> Looks fine.
>  
> 
> >         for(;;)
> >         {
> >                 rb_load_protect(rb_str_new2("Class.rb"),0,&state);
> >                 vTclass = rb_const_get(rb_cObject,
> > rb_intern("MyClass"));
> >                 tObj = rb_funcall(vTclass, rb_intern("new"), 0);
> 
> Looks fine.
> The next 2 lines look interesting..
> 
> >                 Data_Get_Struct(tObj,GMScript,ptr);
> >                 ptr->scriptObj = tObj;
> 
> There is something odd about them.. try
> 
> tObj = new GMScript;
> tObj->scriptObj = tObj;
> 
> 
>  
> >                 // save on stack
> >                 stack.push_back(ptr);
> > 
> >                 // see what it does
> >                 rb_gc();
> > 
> >                 sleep(1);
> >                 cerr << "\n";
> >         }
> > 
> >         return 0;
> > }
> > 
> > and I get the following out put
> > [snip output]
> 
> Sorry I don't understand your output.
> 
> 
> > So, the mark is called - but so is free. I did find that if I use a
> > ruby array instead of vector, push tObj and call rb_global_variable on
> > this array the free never gets called. This leads me to ask if the
> > scriptObj returned from rb_funcall is the correct value to mark.
> > If not, then how do I obtain the correct corresponding ruby VALUE for
> > ptr . In fact, I need to do this to mark children held by
> > GMScript::MyClass?
> 
> I am very sleepy right now.. maybe I understand tomorrow :-)
> 
> 
> > Do I need to do both mark AND rb_global_variable?
> 
> No. They are mutual exlusive

My previous post has not appeared yet but I have a better solution
now. Forget the malloc - that was silly. If I now do the following in
the for loop

                rb_load_protect(rb_str_new2("Class.rb"),0,&state);
                VALUE vTclass = rb_const_get(rb_cObject,
rb_intern("MyClass"));
                VALUE tObj = rb_funcall(vTclass, rb_intern("new"), 0);
                Data_Get_Struct(tObj,GMScript,ptr);
                ptr->scriptObj = tObj;
                rb_gc_register_address(&(ptr->scriptObj));

                // see what it does
                cerr << "\n";
                sleep(1);
                rb_gc();

Its OK and I get:

GMScript::GMScript

MARK
GMScript::GMScript

MARK
MARK
GMScript::GMScript

MARK
MARK
MARK
GMScript::GMScript


which makes sense - each subsequent rb_funcall creates a new object
and the number of marks increase accordingly. But if I omit the call
to

      rb_gc_register_address(&(ptr->scriptObj));

I get:

GMScript::GMScript

FREE
GMScript::~GMScript
GMScript::GMScript

FREE
GMScript::~GMScript
GMScript::GMScript

The mark function in swig is never called. Why?. If I follow the code
through
rb_funcall --> _wrap_GMScript_allocate --> SWIG_NewClassInstance -->
Data_Wrap..
                                       --> rb_obj_call_init -->
initialize()
      self <---

So, does this mean that the only reference held to this ruby instance
is the one returned from rb_funcall and if I don't tell gc it can't
call the mark. And the only reason the free can be called is because
it exists in main's stack frame?

Sorry for being a bit anal here, I'm just trying to get my head round
what's going on.
If the above is true, then great. I would be happy to call
rb_gc_register_address when I create the instance, use the swig mark
func for any persistant children i create within MyClass, and then
call rb_gc_unregister_address when I'm done with it. I think I read
somewhere that there is no harm in marking an object twice so if child
objects created within GMScript are shared with other instances of
GMScript and they both mark the chhildren I can select which ones I
need to delete when I destroy an instance to GMScript.

Am I correct here?

I did read the Swig doc on this - could do with a bit more explaining
here, in particular sec 20.8.5 which refers to the imaginary
SWIG_RubyInstanceFor. any chance anyone might implement it!