Unlock ruby global lock during graphics ops
Unlock the ruby global lock during potentially blocking graphics ops. This enables using multithreading using ruby's `thread` extension.
This commit is contained in:
parent
ac8f4b1594
commit
41e3662bec
1 changed files with 60 additions and 18 deletions
|
@ -25,11 +25,19 @@
|
||||||
#include "binding-types.h"
|
#include "binding-types.h"
|
||||||
#include "exception.h"
|
#include "exception.h"
|
||||||
|
|
||||||
|
#include <ruby/thread.h>
|
||||||
|
|
||||||
|
static void *graphicsUpdate_internal(void*)
|
||||||
|
{
|
||||||
|
shState->graphics().update();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
RB_METHOD(graphicsUpdate)
|
RB_METHOD(graphicsUpdate)
|
||||||
{
|
{
|
||||||
RB_UNUSED_PARAM;
|
RB_UNUSED_PARAM;
|
||||||
|
|
||||||
shState->graphics().update();
|
rb_thread_call_without_gvl(&graphicsUpdate_internal, NULL, NULL, NULL);
|
||||||
|
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
@ -43,17 +51,33 @@ RB_METHOD(graphicsFreeze)
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Argument structure used to pass arguments to various blocking calls,
|
||||||
|
* meanwhile releasing the ruby interpreter lock. */
|
||||||
|
struct transition_args {
|
||||||
|
int duration;
|
||||||
|
const char *filename;
|
||||||
|
int vague;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void *graphicsTransition_internal(void* args_in)
|
||||||
|
{
|
||||||
|
struct transition_args *args = static_cast<transition_args*>(args_in);
|
||||||
|
GUARD_EXC( shState->graphics().transition(args->duration, args->filename, args->vague); )
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
RB_METHOD(graphicsTransition)
|
RB_METHOD(graphicsTransition)
|
||||||
{
|
{
|
||||||
RB_UNUSED_PARAM;
|
RB_UNUSED_PARAM;
|
||||||
|
|
||||||
int duration = 8;
|
struct transition_args args;
|
||||||
const char *filename = "";
|
args.duration = 8;
|
||||||
int vague = 40;
|
args.filename = "";
|
||||||
|
args.vague = 40;
|
||||||
|
|
||||||
rb_get_args(argc, argv, "|izi", &duration, &filename, &vague RB_ARG_END);
|
rb_get_args(argc, argv, "|izi", &args.duration, &args.filename, &args.vague RB_ARG_END);
|
||||||
|
|
||||||
GUARD_EXC( shState->graphics().transition(duration, filename, vague); )
|
rb_thread_call_without_gvl(&graphicsTransition_internal, &args, NULL, NULL);
|
||||||
|
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
@ -111,38 +135,56 @@ RB_METHOD(graphicsHeight)
|
||||||
return rb_fix_new(shState->graphics().height());
|
return rb_fix_new(shState->graphics().height());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *graphicsWait_internal(void* args_in)
|
||||||
|
{
|
||||||
|
struct transition_args *args = static_cast<transition_args*>(args_in);
|
||||||
|
shState->graphics().wait(args->duration);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
RB_METHOD(graphicsWait)
|
RB_METHOD(graphicsWait)
|
||||||
{
|
{
|
||||||
RB_UNUSED_PARAM;
|
RB_UNUSED_PARAM;
|
||||||
|
|
||||||
int duration;
|
struct transition_args args;
|
||||||
rb_get_args(argc, argv, "i", &duration RB_ARG_END);
|
rb_get_args(argc, argv, "i", &args.duration RB_ARG_END);
|
||||||
|
rb_thread_call_without_gvl(&graphicsWait_internal, &args, NULL, NULL);
|
||||||
shState->graphics().wait(duration);
|
|
||||||
|
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *graphicsFadeout_internal(void* args_in)
|
||||||
|
{
|
||||||
|
struct transition_args *args = static_cast<transition_args*>(args_in);
|
||||||
|
shState->graphics().fadeout(args->duration);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
RB_METHOD(graphicsFadeout)
|
RB_METHOD(graphicsFadeout)
|
||||||
{
|
{
|
||||||
RB_UNUSED_PARAM;
|
RB_UNUSED_PARAM;
|
||||||
|
|
||||||
int duration;
|
struct transition_args args;
|
||||||
rb_get_args(argc, argv, "i", &duration RB_ARG_END);
|
rb_get_args(argc, argv, "i", &args.duration RB_ARG_END);
|
||||||
|
rb_thread_call_without_gvl(&graphicsFadeout_internal, &args, NULL, NULL);
|
||||||
shState->graphics().fadeout(duration);
|
|
||||||
|
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *graphicsFadein_internal(void* args_in)
|
||||||
|
{
|
||||||
|
struct transition_args *args = static_cast<transition_args*>(args_in);
|
||||||
|
shState->graphics().fadein(args->duration);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
RB_METHOD(graphicsFadein)
|
RB_METHOD(graphicsFadein)
|
||||||
{
|
{
|
||||||
RB_UNUSED_PARAM;
|
RB_UNUSED_PARAM;
|
||||||
|
|
||||||
int duration;
|
struct transition_args args;
|
||||||
rb_get_args(argc, argv, "i", &duration RB_ARG_END);
|
rb_get_args(argc, argv, "i", &args.duration RB_ARG_END);
|
||||||
|
rb_thread_call_without_gvl(&graphicsFadein_internal, &args, NULL, NULL);
|
||||||
shState->graphics().fadein(duration);
|
|
||||||
|
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue