forked from mia/Aegisub
Separate thread for Ruby
Originally committed to SVN as r939.
This commit is contained in:
parent
bfa2edbe04
commit
9dcae98180
3 changed files with 137 additions and 125 deletions
|
@ -68,9 +68,12 @@ namespace Automation4 {
|
||||||
RubyObjects *RubyObjects::inst = NULL;
|
RubyObjects *RubyObjects::inst = NULL;
|
||||||
RubyScript * RubyScript::inst = NULL; // current Ruby Script
|
RubyScript * RubyScript::inst = NULL; // current Ruby Script
|
||||||
RubyProgressSink* RubyProgressSink::inst = NULL;
|
RubyProgressSink* RubyProgressSink::inst = NULL;
|
||||||
VALUE RubyScript::RubyAegisub = Qfalse;
|
RubyThread* ruby_thread = NULL;
|
||||||
wxString RubyScript::backtrace = _T("");
|
wxSemaphore* ruby_thread_sem = NULL;
|
||||||
wxString RubyScript::error = _T("");
|
wxSemaphore* ruby_script_sem = NULL;
|
||||||
|
VALUE RubyAegisub = Qfalse;
|
||||||
|
wxString backtrace = _T("");
|
||||||
|
wxString error = _T("");
|
||||||
|
|
||||||
// RubyScript
|
// RubyScript
|
||||||
|
|
||||||
|
@ -87,6 +90,19 @@ namespace Automation4 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RubyThread::CallFunction(RubyCallArguments* arg, VALUE *res)
|
||||||
|
{
|
||||||
|
args = arg;
|
||||||
|
result = res;
|
||||||
|
action = CALL_FUNCTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RubyThread::LoadFile(const char *f)
|
||||||
|
{
|
||||||
|
file = f;
|
||||||
|
action = LOAD_FILE;
|
||||||
|
}
|
||||||
|
|
||||||
RubyScript::~RubyScript()
|
RubyScript::~RubyScript()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -94,53 +110,25 @@ namespace Automation4 {
|
||||||
void RubyScript::Create()
|
void RubyScript::Create()
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy();
|
||||||
|
RubyScript::inst = this;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
#if defined(NT)
|
if(ruby_thread == NULL)
|
||||||
int argc = 0;
|
|
||||||
char **argv = 0;
|
|
||||||
NtInitialize(&argc, &argv);
|
|
||||||
#endif
|
|
||||||
char **opt = new char*[4];
|
|
||||||
opt[0] = "-d";
|
|
||||||
ruby_init();
|
|
||||||
//ruby_options(1, opt);
|
|
||||||
ruby_init_loadpath();
|
|
||||||
RubyScript::inst = this;
|
|
||||||
error = _T("");
|
|
||||||
backtrace = _T("");
|
|
||||||
if(!RubyAegisub) {
|
|
||||||
RubyAegisub = rb_define_module("Aegisub");
|
|
||||||
rb_define_module_function(RubyAegisub, "register_macro",reinterpret_cast<RB_HOOK>(&RubyFeatureMacro::RubyRegister), 4);
|
|
||||||
rb_define_module_function(RubyAegisub, "register_filter",reinterpret_cast<RB_HOOK>(&RubyFeatureFilter::RubyRegister), 5);
|
|
||||||
rb_define_module_function(RubyAegisub, "text_extents",reinterpret_cast<RB_HOOK>(&RubyTextExtents), 2);
|
|
||||||
rb_define_module_function(RubyAegisub, "frame_to_time",reinterpret_cast<RB_HOOK>(&RubyFrameToTime), 1);
|
|
||||||
rb_define_module_function(RubyAegisub, "time_to_frame",reinterpret_cast<RB_HOOK>(&RubyTimeToFrame), 1);
|
|
||||||
rb_define_module_function(RubyAegisub, "key_frames",reinterpret_cast<RB_HOOK>(&RubyKeyFrames), 0);
|
|
||||||
rb_define_module_function(rb_eException, "set_backtrace",reinterpret_cast<RB_HOOK>(&backtrace_hook), 1);
|
|
||||||
rb_define_module_function(RubyScript::RubyAegisub, "progress_set",reinterpret_cast<RB_HOOK>(&RubyProgressSink::RubySetProgress), 1);
|
|
||||||
rb_define_module_function(RubyScript::RubyAegisub, "progress_task",reinterpret_cast<RB_HOOK>(&RubyProgressSink::RubySetTask), 1);
|
|
||||||
rb_define_module_function(RubyScript::RubyAegisub, "progress_title",reinterpret_cast<RB_HOOK>(&RubyProgressSink::RubySetTitle), 1);
|
|
||||||
rb_define_module_function(RubyScript::RubyAegisub, "debug_out",reinterpret_cast<RB_HOOK>(&RubyProgressSink::RubyDebugOut), -1);
|
|
||||||
rb_define_module_function(RubyScript::RubyAegisub, "get_cancelled",reinterpret_cast<RB_HOOK>(&RubyProgressSink::RubyGetCancelled), 0);
|
|
||||||
rb_define_module_function(RubyScript::RubyAegisub, "display_dialog",reinterpret_cast<RB_HOOK>(&RubyProgressSink::RubyDisplayDialog), 2);
|
|
||||||
}
|
|
||||||
VALUE paths = rb_gv_get("$:");
|
|
||||||
for(int i = 0; i < include_path.GetCount(); i++)
|
|
||||||
{
|
{
|
||||||
rb_ary_push(paths, rb_str_new2(include_path[i].mb_str(wxConvISO8859_1)));
|
ruby_thread_sem = new wxSemaphore(0, 1);
|
||||||
|
ruby_script_sem = new wxSemaphore(0, 1);
|
||||||
|
ruby_thread = new RubyThread(include_path);
|
||||||
|
ruby_script_sem->Wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
int status = 0;
|
int status = 0;
|
||||||
wxCharBuffer buf = GetFilename().mb_str(wxConvISO8859_1);
|
wxCharBuffer buf = GetFilename().mb_str(wxConvISO8859_1);
|
||||||
const char *t = buf.data();
|
const char *t = buf.data();
|
||||||
|
ruby_thread->LoadFile(t);
|
||||||
rb_protect(rbLoadWrapper, rb_str_new2(t), &status);
|
ruby_thread_sem->Post();
|
||||||
if(status > 0) // something bad happened (probably parsing error)
|
ruby_script_sem->Wait();
|
||||||
{
|
if(ruby_thread->GetStatus())
|
||||||
wxString *err = new wxString(_T("An error occurred initialising the script file \"") + GetFilename() + _T("\":\n\n") + GetError());
|
RubyScript::RubyError();
|
||||||
throw err->c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
VALUE global_var = rb_gv_get("$script_name");
|
VALUE global_var = rb_gv_get("$script_name");
|
||||||
if(TYPE(global_var) == T_STRING)
|
if(TYPE(global_var) == T_STRING)
|
||||||
|
@ -165,9 +153,6 @@ namespace Automation4 {
|
||||||
|
|
||||||
void RubyScript::Destroy()
|
void RubyScript::Destroy()
|
||||||
{
|
{
|
||||||
if(loaded) {
|
|
||||||
// ruby_finalize(); // broken in 1.9 ?_?
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove features
|
// remove features
|
||||||
for (int i = 0; i < (int)features.size(); i++) {
|
for (int i = 0; i < (int)features.size(); i++) {
|
||||||
|
@ -265,6 +250,8 @@ namespace Automation4 {
|
||||||
void RubyScript::RubyError()
|
void RubyScript::RubyError()
|
||||||
{
|
{
|
||||||
wxMessageBox(RubyScript::inst->GetError(), _T("Error"),wxICON_ERROR | wxOK);
|
wxMessageBox(RubyScript::inst->GetError(), _T("Error"),wxICON_ERROR | wxOK);
|
||||||
|
error = _T("");
|
||||||
|
backtrace = _T("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -335,13 +322,12 @@ namespace Automation4 {
|
||||||
argv[2] = INT2FIX(active);
|
argv[2] = INT2FIX(active);
|
||||||
RubyCallArguments arg(rb_mKernel, rb_to_id(validation_fun), 3, argv);
|
RubyCallArguments arg(rb_mKernel, rb_to_id(validation_fun), 3, argv);
|
||||||
VALUE result;
|
VALUE result;
|
||||||
RubyThreadedCall call(&arg, &result);
|
ruby_thread->CallFunction(&arg, &result);
|
||||||
wxThread::ExitCode code = call.Wait();
|
ruby_thread_sem->Post();
|
||||||
if(code)
|
ruby_script_sem->Wait();
|
||||||
{
|
if(ruby_thread->GetStatus())
|
||||||
wxMessageBox(RubyScript::GetError(), _T("Error running validation function"),wxICON_ERROR | wxOK);
|
RubyScript::RubyError();
|
||||||
|
if(result != Qnil && result != Qfalse) {
|
||||||
} else if(result != Qnil && result != Qfalse) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,7 +336,6 @@ namespace Automation4 {
|
||||||
|
|
||||||
void RubyFeatureMacro::Process(AssFile *subs, const std::vector<int> &selected, int active, wxWindow * const progress_parent)
|
void RubyFeatureMacro::Process(AssFile *subs, const std::vector<int> &selected, int active, wxWindow * const progress_parent)
|
||||||
{
|
{
|
||||||
rb_gc_disable();
|
|
||||||
delete RubyProgressSink::inst;
|
delete RubyProgressSink::inst;
|
||||||
RubyProgressSink::inst = new RubyProgressSink(progress_parent, false);
|
RubyProgressSink::inst = new RubyProgressSink(progress_parent, false);
|
||||||
RubyProgressSink::inst->SetTitle(GetName());
|
RubyProgressSink::inst->SetTitle(GetName());
|
||||||
|
@ -363,13 +348,17 @@ namespace Automation4 {
|
||||||
argv[2] = INT2FIX(active);
|
argv[2] = INT2FIX(active);
|
||||||
RubyCallArguments arg(rb_mKernel, rb_to_id(macro_fun), 3, argv);
|
RubyCallArguments arg(rb_mKernel, rb_to_id(macro_fun), 3, argv);
|
||||||
VALUE result;
|
VALUE result;
|
||||||
RubyThreadedCall call(&arg, &result);
|
ruby_thread->CallFunction(&arg, &result);
|
||||||
|
ruby_thread_sem->Post();
|
||||||
RubyProgressSink::inst->ShowModal();
|
RubyProgressSink::inst->ShowModal();
|
||||||
wxThread::ExitCode code = call.Wait();
|
ruby_script_sem->Wait();
|
||||||
delete RubyProgressSink::inst;
|
delete RubyProgressSink::inst;
|
||||||
RubyProgressSink::inst = NULL;
|
RubyProgressSink::inst = NULL;
|
||||||
if(TYPE(result) == T_ARRAY)
|
if(ruby_thread->GetStatus())
|
||||||
|
RubyScript::RubyError();
|
||||||
|
else if(TYPE(result) == T_ARRAY)
|
||||||
{
|
{
|
||||||
|
rb_gc_disable();
|
||||||
bool end = false;
|
bool end = false;
|
||||||
for(int i = 0; i < RARRAY(result)->len && !end; ++i)
|
for(int i = 0; i < RARRAY(result)->len && !end; ++i)
|
||||||
{
|
{
|
||||||
|
@ -397,16 +386,51 @@ namespace Automation4 {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
rb_gc_enable();
|
||||||
}
|
}
|
||||||
delete subsobj;
|
delete subsobj;
|
||||||
rb_gc_enable();
|
}
|
||||||
rb_gc_start();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// RubyThread
|
||||||
|
void RubyThread::InitRuby()
|
||||||
|
{
|
||||||
|
#if defined(NT)
|
||||||
|
int argc = 0;
|
||||||
|
char **argv = 0;
|
||||||
|
NtInitialize(&argc, &argv);
|
||||||
|
#endif
|
||||||
|
ruby_init();
|
||||||
|
ruby_init_loadpath();
|
||||||
|
error = _T("");
|
||||||
|
backtrace = _T("");
|
||||||
|
if(!RubyAegisub) {
|
||||||
|
RubyAegisub = rb_define_module("Aegisub");
|
||||||
|
rb_define_module_function(RubyAegisub, "register_macro",reinterpret_cast<RB_HOOK>(&RubyFeatureMacro::RubyRegister), 4);
|
||||||
|
rb_define_module_function(RubyAegisub, "register_filter",reinterpret_cast<RB_HOOK>(&RubyFeatureFilter::RubyRegister), 5);
|
||||||
|
rb_define_module_function(RubyAegisub, "text_extents",reinterpret_cast<RB_HOOK>(&RubyScript::RubyTextExtents), 2);
|
||||||
|
rb_define_module_function(RubyAegisub, "frame_to_time",reinterpret_cast<RB_HOOK>(&RubyScript::RubyFrameToTime), 1);
|
||||||
|
rb_define_module_function(RubyAegisub, "time_to_frame",reinterpret_cast<RB_HOOK>(&RubyScript::RubyTimeToFrame), 1);
|
||||||
|
rb_define_module_function(RubyAegisub, "key_frames",reinterpret_cast<RB_HOOK>(&RubyScript::RubyKeyFrames), 0);
|
||||||
|
rb_define_module_function(rb_eException, "set_backtrace",reinterpret_cast<RB_HOOK>(&RubyScript::backtrace_hook), 1);
|
||||||
|
rb_define_module_function(RubyAegisub, "progress_set",reinterpret_cast<RB_HOOK>(&RubyProgressSink::RubySetProgress), 1);
|
||||||
|
rb_define_module_function(RubyAegisub, "progress_task",reinterpret_cast<RB_HOOK>(&RubyProgressSink::RubySetTask), 1);
|
||||||
|
rb_define_module_function(RubyAegisub, "progress_title",reinterpret_cast<RB_HOOK>(&RubyProgressSink::RubySetTitle), 1);
|
||||||
|
rb_define_module_function(RubyAegisub, "debug_out",reinterpret_cast<RB_HOOK>(&RubyProgressSink::RubyDebugOut), -1);
|
||||||
|
rb_define_module_function(RubyAegisub, "get_cancelled",reinterpret_cast<RB_HOOK>(&RubyProgressSink::RubyGetCancelled), 0);
|
||||||
|
rb_define_module_function(RubyAegisub, "display_dialog",reinterpret_cast<RB_HOOK>(&RubyProgressSink::RubyDisplayDialog), 2);
|
||||||
|
}
|
||||||
|
VALUE paths = rb_gv_get("$:");
|
||||||
|
for(int i = 0; i < include_path.GetCount(); i++)
|
||||||
|
{
|
||||||
|
rb_ary_push(paths, rb_str_new2(include_path[i].mb_str(wxConvISO8859_1)));
|
||||||
|
}
|
||||||
|
|
||||||
RubyThreadedCall::RubyThreadedCall(RubyCallArguments *a, VALUE *res)
|
}
|
||||||
|
|
||||||
|
RubyThread::RubyThread(wxPathList paths)
|
||||||
: wxThread(wxTHREAD_JOINABLE)
|
: wxThread(wxTHREAD_JOINABLE)
|
||||||
,args(a), result(res)
|
,include_path(paths)
|
||||||
|
,action(NOTHING)
|
||||||
{
|
{
|
||||||
int prio = Options.AsInt(_T("Automation Thread Priority"));
|
int prio = Options.AsInt(_T("Automation Thread Priority"));
|
||||||
if (prio == 0) prio = 50; // normal
|
if (prio == 0) prio = 50; // normal
|
||||||
|
@ -418,20 +442,29 @@ namespace Automation4 {
|
||||||
Run();
|
Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
wxThread::ExitCode RubyThreadedCall::Entry()
|
wxThread::ExitCode RubyThread::Entry()
|
||||||
{
|
{
|
||||||
int error = 0;
|
InitRuby();
|
||||||
*result = rb_protect(rbCallWrapper, reinterpret_cast<VALUE>(args), &error);
|
ruby_script_sem->Post();
|
||||||
if(RubyProgressSink::inst)
|
do {
|
||||||
{
|
ruby_thread_sem->Wait();
|
||||||
RubyProgressSink::inst->script_finished = true;
|
status = 0;
|
||||||
wxWakeUpIdle();
|
switch(action)
|
||||||
}
|
{
|
||||||
if(error) {
|
case LOAD_FILE:
|
||||||
RubyScript::RubyError();
|
rb_protect(rbLoadWrapper, rb_str_new2(file), &status);
|
||||||
return (wxThread::ExitCode)1;
|
break;
|
||||||
}
|
case CALL_FUNCTION:
|
||||||
return (wxThread::ExitCode)0;
|
*result = rb_protect(rbCallWrapper, reinterpret_cast<VALUE>(args), &status);
|
||||||
|
if(RubyProgressSink::inst)
|
||||||
|
{
|
||||||
|
RubyProgressSink::inst->script_finished = true;
|
||||||
|
wxWakeUpIdle();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ruby_script_sem->Post();
|
||||||
|
}while(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// RubyFeatureFilter
|
// RubyFeatureFilter
|
||||||
|
@ -466,7 +499,6 @@ namespace Automation4 {
|
||||||
{
|
{
|
||||||
|
|
||||||
try {
|
try {
|
||||||
rb_gc_disable();
|
|
||||||
VALUE cfg;
|
VALUE cfg;
|
||||||
if (has_config && config_dialog) {
|
if (has_config && config_dialog) {
|
||||||
cfg = config_dialog->RubyReadBack();
|
cfg = config_dialog->RubyReadBack();
|
||||||
|
@ -481,28 +513,25 @@ namespace Automation4 {
|
||||||
argv[1] = cfg; // config
|
argv[1] = cfg; // config
|
||||||
RubyCallArguments arg(rb_mKernel, rb_to_id(filter_fun), 2, argv);
|
RubyCallArguments arg(rb_mKernel, rb_to_id(filter_fun), 2, argv);
|
||||||
VALUE result;
|
VALUE result;
|
||||||
RubyThreadedCall call(&arg, &result);
|
ruby_thread->CallFunction(&arg, &result);
|
||||||
|
ruby_thread_sem->Post();
|
||||||
RubyProgressSink::inst->ShowModal();
|
RubyProgressSink::inst->ShowModal();
|
||||||
|
ruby_script_sem->Wait();
|
||||||
|
if(ruby_thread->GetStatus())
|
||||||
|
RubyScript::RubyError();
|
||||||
RubyProgressSink::inst = NULL;
|
RubyProgressSink::inst = NULL;
|
||||||
wxThread::ExitCode code = call.Wait();
|
|
||||||
delete RubyProgressSink::inst;
|
delete RubyProgressSink::inst;
|
||||||
/*if(code) // error reporting doesn't work in ruby 1.9
|
if(TYPE(result) == T_ARRAY)
|
||||||
{
|
|
||||||
if(TYPE(result) == T_STRING)
|
|
||||||
throw StringValueCStr(result);
|
|
||||||
else throw "Unknown Error";
|
|
||||||
}
|
|
||||||
else*/ if(TYPE(result) == T_ARRAY)
|
|
||||||
{
|
{
|
||||||
|
rb_gc_disable();
|
||||||
subsobj->RubyUpdateAssFile(result);
|
subsobj->RubyUpdateAssFile(result);
|
||||||
|
rb_gc_enable();
|
||||||
}
|
}
|
||||||
delete subsobj;
|
delete subsobj;
|
||||||
} catch (const char* e) {
|
} catch (const char* e) {
|
||||||
wxString *err = new wxString(e, wxConvUTF8);
|
wxString *err = new wxString(e, wxConvUTF8);
|
||||||
wxMessageBox(*err, _T("Error running filter"),wxICON_ERROR | wxOK);
|
wxMessageBox(*err, _T("Error running filter"),wxICON_ERROR | wxOK);
|
||||||
}
|
}
|
||||||
rb_gc_enable();
|
|
||||||
rb_gc_start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptConfigDialog* RubyFeatureFilter::GenerateConfigDialog(wxWindow *parent)
|
ScriptConfigDialog* RubyFeatureFilter::GenerateConfigDialog(wxWindow *parent)
|
||||||
|
@ -523,9 +552,12 @@ namespace Automation4 {
|
||||||
argv[1] = Qnil; // TODO: stored options
|
argv[1] = Qnil; // TODO: stored options
|
||||||
RubyCallArguments arg(rb_mKernel, rb_to_id(dialog_fun), 2, argv);
|
RubyCallArguments arg(rb_mKernel, rb_to_id(dialog_fun), 2, argv);
|
||||||
VALUE dialog_data;
|
VALUE dialog_data;
|
||||||
RubyThreadedCall call(&arg, &dialog_data);
|
ruby_thread->CallFunction(&arg, &dialog_data);
|
||||||
|
ruby_thread_sem->Post();
|
||||||
RubyProgressSink::inst->ShowModal();
|
RubyProgressSink::inst->ShowModal();
|
||||||
wxThread::ExitCode code = call.Wait();
|
ruby_script_sem->Wait();
|
||||||
|
if(ruby_thread->GetStatus())
|
||||||
|
RubyScript::RubyError();
|
||||||
delete RubyProgressSink::inst;
|
delete RubyProgressSink::inst;
|
||||||
RubyProgressSink::inst = NULL;
|
RubyProgressSink::inst = NULL;
|
||||||
|
|
||||||
|
@ -677,12 +709,12 @@ namespace Automation4 {
|
||||||
|
|
||||||
VALUE RubyScript::backtrace_hook(VALUE self, VALUE backtr)
|
VALUE RubyScript::backtrace_hook(VALUE self, VALUE backtr)
|
||||||
{
|
{
|
||||||
int len = RARRAY_LEN(backtr);
|
int len = RARRAY(backtr)->len;
|
||||||
VALUE err = rb_funcall(self, rb_intern("to_s"), 0);
|
VALUE err = rb_funcall(self, rb_intern("to_s"), 0);
|
||||||
error = wxString(StringValueCStr(err), wxConvUTF8);
|
error = wxString(StringValueCStr(err), wxConvUTF8);
|
||||||
for(int i = 0; i < len; ++i)
|
for(int i = 0; i < len; ++i)
|
||||||
{
|
{
|
||||||
VALUE str = RARRAY_PTR(backtr)[i];
|
VALUE str = RARRAY(backtr)->ptr[i];
|
||||||
wxString line(StringValueCStr(str), wxConvUTF8);
|
wxString line(StringValueCStr(str), wxConvUTF8);
|
||||||
backtrace.Append(line + _T("\n"));
|
backtrace.Append(line + _T("\n"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,26 +158,23 @@ namespace Automation4 {
|
||||||
friend class RubyProgressSink;
|
friend class RubyProgressSink;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static wxString error;
|
|
||||||
static wxString backtrace;
|
|
||||||
|
|
||||||
void Create(); // load script and create internal structures etc.
|
void Create(); // load script and create internal structures etc.
|
||||||
void Destroy(); // destroy internal structures, unreg features and delete environment
|
void Destroy(); // destroy internal structures, unreg features and delete environment
|
||||||
|
|
||||||
static RubyScript* GetScriptObject();
|
static RubyScript* GetScriptObject();
|
||||||
|
public:
|
||||||
static VALUE RubyTextExtents(VALUE self, VALUE style, VALUE text);
|
static VALUE RubyTextExtents(VALUE self, VALUE style, VALUE text);
|
||||||
static VALUE RubyFrameToTime(VALUE self, VALUE frame);
|
static VALUE RubyFrameToTime(VALUE self, VALUE frame);
|
||||||
static VALUE RubyTimeToFrame(VALUE self, VALUE time);
|
static VALUE RubyTimeToFrame(VALUE self, VALUE time);
|
||||||
static VALUE RubyKeyFrames(VALUE self);
|
static VALUE RubyKeyFrames(VALUE self);
|
||||||
static VALUE backtrace_hook(VALUE self, VALUE backtr);
|
static VALUE backtrace_hook(VALUE self, VALUE backtr);
|
||||||
|
|
||||||
public:
|
|
||||||
RubyScript(const wxString &filename);
|
RubyScript(const wxString &filename);
|
||||||
static void RubyError();
|
static void RubyError();
|
||||||
static wxString GetError();
|
static wxString GetError();
|
||||||
virtual ~RubyScript();
|
virtual ~RubyScript();
|
||||||
virtual void Reload();
|
virtual void Reload();
|
||||||
static VALUE RubyAegisub;
|
|
||||||
static RubyScript* inst;
|
static RubyScript* inst;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -243,14 +240,22 @@ namespace Automation4 {
|
||||||
RubyCallArguments(VALUE _recv, ID _id, int _n, VALUE *_argv);
|
RubyCallArguments(VALUE _recv, ID _id, int _n, VALUE *_argv);
|
||||||
};
|
};
|
||||||
|
|
||||||
// A single call to a Ruby function, run inside a separate thread.
|
// Separate thread for ruby interpreter
|
||||||
// This object should be created on the stack in the function that does the call.
|
class RubyThread : public wxThread {
|
||||||
class RubyThreadedCall : public wxThread {
|
|
||||||
private:
|
private:
|
||||||
|
enum {NOTHING, CALL_FUNCTION, LOAD_FILE};
|
||||||
|
int action;
|
||||||
|
int status;
|
||||||
RubyCallArguments *args;
|
RubyCallArguments *args;
|
||||||
|
const char* file;
|
||||||
VALUE *result;
|
VALUE *result;
|
||||||
|
void InitRuby();
|
||||||
|
wxPathList include_path;
|
||||||
public:
|
public:
|
||||||
RubyThreadedCall(RubyCallArguments *args, VALUE *result);
|
RubyThread(wxPathList include_path);
|
||||||
|
void CallFunction(RubyCallArguments* arg, VALUE *res);
|
||||||
|
void LoadFile(const char* file);
|
||||||
|
int GetStatus() {return status;};
|
||||||
virtual ExitCode Entry();
|
virtual ExitCode Entry();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -351,7 +351,6 @@ namespace Automation4 {
|
||||||
new_entry = reinterpret_cast<AssEntry*>(rb_protect(rb2AssWrapper, rbEntry, &status));
|
new_entry = reinterpret_cast<AssEntry*>(rb_protect(rb2AssWrapper, rbEntry, &status));
|
||||||
--size;
|
--size;
|
||||||
}while(status != 0); // broken lines at the beginning?
|
}while(status != 0); // broken lines at the beginning?
|
||||||
rb_set_errinfo(Qnil);; // just in case
|
|
||||||
|
|
||||||
entryIter e = ass->Line.begin();
|
entryIter e = ass->Line.begin();
|
||||||
if(new_entry->GetType() == ENTRY_DIALOGUE) // check if the first line is a dialogue
|
if(new_entry->GetType() == ENTRY_DIALOGUE) // check if the first line is a dialogue
|
||||||
|
@ -369,15 +368,6 @@ namespace Automation4 {
|
||||||
rbEntry = rb_ary_shift(subtitles);
|
rbEntry = rb_ary_shift(subtitles);
|
||||||
new_entry = reinterpret_cast<AssEntry*>(rb_protect(rb2AssWrapper, rbEntry, &status));
|
new_entry = reinterpret_cast<AssEntry*>(rb_protect(rb2AssWrapper, rbEntry, &status));
|
||||||
if(status == 0) ass->Line.push_back(new_entry);
|
if(status == 0) ass->Line.push_back(new_entry);
|
||||||
else
|
|
||||||
{
|
|
||||||
if(RubyProgressSink::inst)
|
|
||||||
{
|
|
||||||
VALUE err = rb_errinfo();
|
|
||||||
RubyProgressSink::inst->RubyDebugOut(1, &err, Qnil);
|
|
||||||
}
|
|
||||||
rb_set_errinfo(Qnil);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (can_set_undo) {
|
if (can_set_undo) {
|
||||||
|
@ -411,12 +401,6 @@ namespace Automation4 {
|
||||||
RubyAssFile::~RubyAssFile()
|
RubyAssFile::~RubyAssFile()
|
||||||
{
|
{
|
||||||
RubyObjects::Get()->Unregister(rbAssFile);
|
RubyObjects::Get()->Unregister(rbAssFile);
|
||||||
int status;
|
|
||||||
rb_protect(rbGcWrapper, Qnil, &status); // run the gc
|
|
||||||
if(status != 0)
|
|
||||||
{
|
|
||||||
wxMessageBox(_T("Error"), _T("Error while running Ruby garbage collection"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RubyAssFile::RubyAssFile(AssFile *_ass, bool _can_modify, bool _can_set_undo)
|
RubyAssFile::RubyAssFile(AssFile *_ass, bool _can_modify, bool _can_set_undo)
|
||||||
|
@ -424,7 +408,7 @@ namespace Automation4 {
|
||||||
, can_modify(_can_modify)
|
, can_modify(_can_modify)
|
||||||
, can_set_undo(_can_set_undo)
|
, can_set_undo(_can_set_undo)
|
||||||
{
|
{
|
||||||
|
rb_gc_disable();
|
||||||
rbAssFile = rb_ary_new2(ass->Line.size());
|
rbAssFile = rb_ary_new2(ass->Line.size());
|
||||||
RubyObjects::Get()->Register(rbAssFile);
|
RubyObjects::Get()->Register(rbAssFile);
|
||||||
|
|
||||||
|
@ -434,17 +418,8 @@ namespace Automation4 {
|
||||||
{
|
{
|
||||||
VALUE res = rb_protect(rbAss2RbWrapper, reinterpret_cast<VALUE>(*entry), &status);
|
VALUE res = rb_protect(rbAss2RbWrapper, reinterpret_cast<VALUE>(*entry), &status);
|
||||||
if(status == 0) rb_ary_push(rbAssFile, res);
|
if(status == 0) rb_ary_push(rbAssFile, res);
|
||||||
else
|
|
||||||
{
|
|
||||||
if(RubyProgressSink::inst)
|
|
||||||
{
|
|
||||||
VALUE err = rb_errinfo();
|
|
||||||
RubyProgressSink::inst->RubyDebugOut(1, &err, Qnil);
|
|
||||||
}
|
|
||||||
rb_set_errinfo(Qnil);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
rb_gc_enable();
|
||||||
// TODO
|
// TODO
|
||||||
//rb_define_module_function(RubyScript::RubyAegisub, "parse_tag_data",reinterpret_cast<RB_HOOK>(&RubyParseTagData), 1);
|
//rb_define_module_function(RubyScript::RubyAegisub, "parse_tag_data",reinterpret_cast<RB_HOOK>(&RubyParseTagData), 1);
|
||||||
//rb_define_module_function(RubyScript::RubyAegisub, "unparse_tag_data",reinterpret_cast<RB_HOOK>(&RubyUnparseTagData), 1);
|
//rb_define_module_function(RubyScript::RubyAegisub, "unparse_tag_data",reinterpret_cast<RB_HOOK>(&RubyUnparseTagData), 1);
|
||||||
|
|
Loading…
Reference in a new issue