programación - Incrustar un intérprete de Ruby en una aplicación de C++
ruby descargar (5)
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;
}
Espero utilizar Ruby como lenguaje de scripting para mi motor de juego. He encontrado 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 ...
Actualmente, mi motor utiliza 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 "reposo durante 2 segundos" o "esperar hasta que el personaje haya terminado de caminar", por lo que el programador mantiene un registro del estado de cada script y una instrucción. puntero, y sabe cuándo reanudarlos, y así sucesivamente.
Así que parece que realmente necesito algún tipo de intérprete de Ruby integrado sobre el que pueda ejercer cierto grado de control, en lugar de simplemente llamar a los métodos de Ruby. ¿O simplemente estoy siendo obtuso y me estoy perdiendo algo?
Estoy trabajando en Microsoft Visual C ++, así que idealmente cualquier solución compilaría bien y fácilmente en eso.
Creo que lo que vas a querer hacer es usar los hilos de Ruby. He investigado un poco el código de subprocesos de Ruby y sé que (donde pthreads está disponible) el sueño se implementa de manera no bloqueante usando pthread_cond_timedwait. Esto desbloquea el intérprete para que otros hilos puedan continuar su ejecución.
Tu 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 que bloquearte.
Estás en el camino correcto. La clave es hacer algo similar a la sección sobre Conceptos de incrustación en el enlace que publicaste. En términos simples es poco más que:
ruby_init();
ruby_script("some_script");
Es posible que deba copiar todas las cosas main.c de main.c para que todo funcione. A partir de ese momento, se trata de crear una API para las funciones de C ++ que desea exponer y, en función de su diseño, realizar múltiples subprocesos.
Hay una guide sobre cómo incrustar ruby en una aplicación de C ++. Eso puede ser útil. De lo contrario vaya a la documentación de Ruby . El artículo de Incrustar Ruby en C también puede ser útil.
Siempre se puede 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.
Así que, si tuvieras esto:
proc:
action 1
action 2
sleep a bit
action 3
end
lo que requeriría que el script se suspenda en la línea de suspensión, haga esto:
proc
action1
action2
set timer (time, callback_proc)
end
callback_proc
action3
end
lo que permite al motor de scripting terminar cada método de forma ordenada. No necesitaría muchos cambios en el lado del alojamiento: cada versión requiere algún tipo de sistema de eventos que pueda reiniciar el motor de script.