From: ggarramuno@... (GGarramuno) Date: 2004-03-16T13:24:35+09:00 Subject: Embedding Ruby into Maya, part 3 All is going well. I have the basic functionality up and running of having ruby inside maya. However, I have some minor issues/questions pending. 1) Cleaning/Starting afresh Ruby. MEL is a persistant language. That is, there is no way to clean up the global namespace during the whole time maya is open. This tends to work fine for the type of application it is designed for. I've set my plugin for ruby to work in a similar way. However, I would like to also have the ability to "restart" a ruby session and clean up everything. What's the proper method? ruby_cleanup(), ruby_finalize()? Difference of both? I've tried using ruby_cleanup(), but once I do, I cannot get any other See end of message for sample code. 2) FOX problems, likely related to 1) I am having problems running scripts with FOX. FOX runs fine and the window pops up, but once the window is closed, it remains around. Re-starting a new or same script will give out all sort of weird errors (Thread error on a simple put). Is it possible that FOX assumes that ruby is running stand-alone and it ends up calling some ruby_cleanup() function incorrectly? Or the opposite, that I am not calling the right functions that will trash all the FOX widgets properly? 3) New IO Stream I would also like to have a new IO stream to redirect ruby's $stderr/$stdout or print statements. Basically, besides stderr/stdout, Maya has another log window for reporting issues. What I would like to do is something similar to what can be done with C++ streams. Something along the lines of: class MayaLog << IO def sync() MELLog( @buffer ) @buffer = nil end end That is, everytime the stream reaches a newline and gets sync'ed, the buffer of the stream would get sent out to a C command of my own(MELLog) and would then be cleared. Sadly, I am unable to find any docs describing inheriting from IO. Anyone can help out? ------------------------- sample code (extracts) void rubyMEL::initRuby() { ruby_init(); ruby_init_loadpath(); // require_libraries(); int result; rb_eval_string_protect( "require \"math3d.so\"", &result ); if ( result != 0 ) { MWARN("math3d.so ruby library not found. vector and matrix not valid."); } rb_define_global_function("MEL", RUBY_METHOD_FUNC(MELevaluate), -1); rb_define_method(rb_cObject,"toMEL", RUBY_METHOD_FUNC(toMEL), 0); } void rubyMEL::startRuby() { char* argv[] = { "ruby", "-e", 0 }; #if defined(NT) int argc = 2; NtInitialize(&argc, (char***)&argv); #endif #if defined(__MACOS__) && defined(__MWERKS__) argc = ccommand(&argv); #endif initRuby(); } void rubyMEL::endRuby() { // Get rid of the ruby interpreter, garbage collect everything, etc. ruby_cleanup(0); } /// By the time we call doIt(), startRuby() has already been called at least once MStatus rubyMEL::doIt() { VALUE ret = rb_eval_string_protect( command.asChar(), &result ); if ( result != 0 ) { VALUE bang = rb_gv_get("$!"); MFATAL("RUBY ERROR: " << STR2CSTR(bang)); } rb_eval_string( "$stdout.flush; $stderr.flush" ); //////////////////////////// code does not really go here, just as a test.... // end and restart ruby afresh after each command. endRuby(); startRuby(); return MStatus::kSuccess; }