2009-03-09 20 views
18

Espero utilizar Ruby como lenguaje de scripting para mi motor de juego. Encontré los artículos habituales que describen cómo llamar a las clases de Ruby desde el código C++ y viceversa (por ejemplo, here) pero no puedo ver cómo hacer lo que quiero con esa forma de trabajar ...Incrustar un intérprete de Ruby en una aplicación de C++

Mi motor Actualmente uso un pequeño lenguaje que escribí con Flex y Bison, y una pequeña máquina virtual basada en pila. Los scripts no siempre se ejecutan de principio a fin, por ejemplo, a veces incluyen comandos como "dormir durante 2 segundos" o "esperar hasta que el personaje haya terminado de caminar", por lo que el planificador controla el estado de cada script y una instrucción puntero, y sabe cuándo reanudarlos, y así sucesivamente.

Parece que realmente necesito algún tipo de intérprete de Ruby integrado sobre el que pueda ejercer un cierto grado de control, en lugar de simplemente llamar a los métodos de Ruby. ¿O solo estoy siendo obtuso y me estoy perdiendo algo?

Estoy trabajando en Microsoft Visual C++, por lo que idealmente cualquier solución se compilaría fácil y fácilmente.

Respuesta

4

Estás en el camino correcto. La clave es hacer algo similar a la sección en Embedding Concepts en el enlace que ha publicado. En términos simples, es poco más que:

ruby_init(); 
ruby_script("some_script"); 

Es posible que tenga que copiar todo el material de #ifdefmain.c a conseguir que todo funcione. A partir de entonces, se trata de crear una API para sus funciones de C++ que desea exponer, y dependiendo de su diseño, realizar múltiples subprocesos.

+0

Esto todavía no parece abordar la cuestión de cómo conseguir que uno de esos scripts pase al modo de suspensión, por ejemplo, el aspecto de la programación. – andygeers

4

Siempre podría rediseñar la forma en que funcionan los scripts para adaptarse al motor de scripts en lugar de intentar que el motor funcione con los paradigmas de scripts originales.

lo tanto, si usted ha tenido este:

proc: 
    action 1 
    action 2 
    sleep a bit 
    action 3 
end 

lo que requeriría el script para ser suspendido en la línea de sueño, hacer esto:

proc 
    action1 
    action2 
    set timer (time, callback_proc) 
end 

callback_proc 
    action3 
end 

que permite el acabado motor de scripting cada método cuidadosamente . No necesitaría muchos cambios en el lado del hosting: cada versión requiere alguna forma de sistema de eventos que pueda reiniciar el motor de script.

3

Hay un guide sobre cómo incrustar ruby ​​en una aplicación C++. Eso puede ser útil. De lo contrario, vaya al Ruby documentation. El artículo Embed Ruby in C también puede ser útil.

+2

Para futuros lectores, el sitio web con una guía C++ se ha reorganizado. La nueva url es: http://aeditor.rubyforge.org/ruby_cplusplus/index.html – Iain

+3

Lamentablemente, tanto Ruby Forge como mi ópera han sido cerradas, por lo que ni la guía ni el artículo están disponibles. –

0

Creo que lo que vas a querer hacer es usar los hilos de Ruby. He investigado un poco el código de subprocesamiento de Ruby y sé que (donde pthreads está disponible) sleep se implementa de forma no bloqueante usando pthread_cond_timedwait. Esto desbloquea el intérprete para que otros subprocesos puedan continuar la ejecución.

Su propio código tendrá que respetar los hilos de Ruby cuando se trata de interactuar con el intérprete de Ruby. Todavía tienen un Global VM Lock en Ruby, lo que significa que debes tener cuidado al modificar cualquier cosa en el intérprete sin tener el bloqueo tú mismo.

28

Aquí hay un ejemplo que incluye el manejo de errores.

#include <iostream> 
#include <ruby.h> 

using namespace std; 

int main(void) 
{ 
    ruby_init(); 
    ruby_init_loadpath(); 
    int status; 
    rb_load_protect(rb_str_new2("./test.rb"), 0, &status); 
    if (status) { 
    VALUE rbError = rb_funcall(rb_gv_get("$!"), rb_intern("message"), 0); 
    cerr << StringValuePtr(rbError) << endl; 
    }; 
    ruby_finalize(); 
    return status; 
} 
+0

gracias, la mejor respuesta aquí :) – Cynede

+1

Es una respuesta parcial, pero hasta donde yo sé, esto todavía no se relaciona con la cuestión de los scripts suspendidos. – andygeers

Cuestiones relacionadas