我希望将Ruby用作我的游戏引擎的脚本语言。我找到了通常的文章,描述了如何从C ++代码调用Ruby类,反之亦然(例如here),但我不太明白如何用这种工作方式做我想做的事......
我的引擎目前使用的是我用Flex和Bison编写的一种语言,以及一个基于小堆栈的虚拟机。脚本并不总是从头到尾运行,例如它们有时包括“睡2秒”或“等到角色走完”等命令,因此调度程序会密切关注每个脚本的状态和指令指针,并知道何时恢复它们,等等。
所以我似乎真的需要某种嵌入式Ruby解释器,我可以对它进行一定程度的控制,而不是简单地调用Ruby方法。或者我只是迟钝而错过了什么?
我正在使用Microsoft Visual C ++,所以理想情况下,任何解决方案都可以轻松编译。
答案 0 :(得分:29)
这是一个包含错误处理的例子。
#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;
}
答案 1 :(得分:4)
你走在正确的轨道上。关键是要做一些类似于您发布的链接中Embedding Concepts部分的内容。简单来说,它只不过是:
ruby_init();
ruby_script("some_script");
您可能需要复制main.c中的所有#ifdef
内容以使所有内容正常运行。从那时起,您需要为要公开的C ++函数构建API,并根据您的设计,多线程化。
答案 2 :(得分:4)
您可以随时重新设计脚本的工作方式以适应脚本引擎,而不是试图让引擎与原始脚本范例一起使用。
所以,如果你有这个:
proc:
action 1
action 2
sleep a bit
action 3
end
这将要求脚本在睡眠线上暂停,请执行以下操作:
proc
action1
action2
set timer (time, callback_proc)
end
callback_proc
action3
end
让脚本引擎整齐地完成每个方法。它不需要对主机端进行很多更改 - 每个版本都需要某种形式的事件系统来重启脚本引擎。
答案 3 :(得分:3)
关于如何将ruby嵌入到C ++应用程序中有一个guide。这可能会有所帮助。否则请转到Ruby documentation。 Embed Ruby in C文章也可能会有所帮助。
答案 4 :(得分:1)
我认为你想要做的是使用Ruby的线程。我已经完成了一些挖掘Ruby线程代码的工作,我知道(pthreads可用的地方)sleep是使用pthread_cond_timedwait以非阻塞方式实现的。这会解除对解释器的阻塞,以便其他线程可以继续执行。
在与Ruby解释器交互时,您自己的代码必须尊重Ruby的线程。他们仍然使用Ruby中的全局虚拟机锁定,这意味着你应该小心修改解释器中的任何内容,而无需自己锁定。