mirror of
https://github.com/mkxp-z/mkxp-z.git
synced 2025-04-21 21:52:04 +02:00
Prevent memory leaks from rb_raise
rb_raise calls longjmp, which bypasses C++ destructors, and also keeps the error for catch blocks from being unallocated if passed by reference, which we do for exceptions. Some of the calls I left can still jump out of try blocks, which you're not supposed to do, but there shouldn't be any objects with destructors initialized at those points so it's probably fine.
This commit is contained in:
parent
1462dc9623
commit
a73f9ccc1f
18 changed files with 529 additions and 390 deletions
|
@ -25,17 +25,18 @@
|
|||
#include "exception.h"
|
||||
|
||||
#define DEF_PLAY_STOP_POS(entity) \
|
||||
RB_METHOD(audio_##entity##Play) \
|
||||
RB_METHOD_GUARD(audio_##entity##Play) \
|
||||
{ \
|
||||
RB_UNUSED_PARAM; \
|
||||
const char *filename; \
|
||||
int volume = 100; \
|
||||
int pitch = 100; \
|
||||
double pos = 0.0; \
|
||||
rb_get_args(argc, argv, "z|iif", &filename, &volume, &pitch, &pos RB_ARG_END); \
|
||||
GUARD_EXC( shState->audio().entity##Play(filename, volume, pitch, pos); ) \
|
||||
rb_get_args(argc, argv, "z|iif", &filename, &volume, &pitch, &pos RB_ARG_END); \
|
||||
shState->audio().entity##Play(filename, volume, pitch, pos); \
|
||||
return Qnil; \
|
||||
} \
|
||||
RB_METHOD_GUARD_END \
|
||||
RB_METHOD(audio_##entity##Stop) \
|
||||
{ \
|
||||
RB_UNUSED_PARAM; \
|
||||
|
@ -49,16 +50,17 @@
|
|||
}
|
||||
|
||||
#define DEF_PLAY_STOP(entity) \
|
||||
RB_METHOD(audio_##entity##Play) \
|
||||
RB_METHOD_GUARD(audio_##entity##Play) \
|
||||
{ \
|
||||
RB_UNUSED_PARAM; \
|
||||
const char *filename; \
|
||||
int volume = 100; \
|
||||
int pitch = 100; \
|
||||
rb_get_args(argc, argv, "z|ii", &filename, &volume, &pitch RB_ARG_END); \
|
||||
GUARD_EXC( shState->audio().entity##Play(filename, volume, pitch); ) \
|
||||
shState->audio().entity##Play(filename, volume, pitch); \
|
||||
return Qnil; \
|
||||
} \
|
||||
RB_METHOD_GUARD_END \
|
||||
RB_METHOD(audio_##entity##Stop) \
|
||||
{ \
|
||||
RB_UNUSED_PARAM; \
|
||||
|
@ -87,7 +89,7 @@ RB_METHOD(audio_##entity##Fade) \
|
|||
|
||||
#define MAYBE_NIL_TRACK(t) t == Qnil ? -127 : NUM2INT(t)
|
||||
|
||||
RB_METHOD(audio_bgmPlay)
|
||||
RB_METHOD_GUARD(audio_bgmPlay)
|
||||
{
|
||||
RB_UNUSED_PARAM;
|
||||
const char *filename;
|
||||
|
@ -96,9 +98,10 @@ RB_METHOD(audio_bgmPlay)
|
|||
double pos = 0.0;
|
||||
VALUE track = Qnil;
|
||||
rb_get_args(argc, argv, "z|iifo", &filename, &volume, &pitch, &pos, &track RB_ARG_END);
|
||||
GUARD_EXC( shState->audio().bgmPlay(filename, volume, pitch, pos, MAYBE_NIL_TRACK(track)); )
|
||||
shState->audio().bgmPlay(filename, volume, pitch, pos, MAYBE_NIL_TRACK(track));
|
||||
return Qnil;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(audio_bgmStop)
|
||||
{
|
||||
|
@ -117,25 +120,27 @@ RB_METHOD(audio_bgmPos)
|
|||
return rb_float_new(shState->audio().bgmPos(MAYBE_NIL_TRACK(track)));
|
||||
}
|
||||
|
||||
RB_METHOD(audio_bgmGetVolume)
|
||||
RB_METHOD_GUARD(audio_bgmGetVolume)
|
||||
{
|
||||
RB_UNUSED_PARAM;
|
||||
VALUE track = Qnil;
|
||||
rb_get_args(argc, argv, "|o", &track RB_ARG_END);
|
||||
int ret = 0;
|
||||
GUARD_EXC( ret = shState->audio().bgmGetVolume(MAYBE_NIL_TRACK(track)); )
|
||||
ret = shState->audio().bgmGetVolume(MAYBE_NIL_TRACK(track));
|
||||
return rb_fix_new(ret);
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(audio_bgmSetVolume)
|
||||
RB_METHOD_GUARD(audio_bgmSetVolume)
|
||||
{
|
||||
RB_UNUSED_PARAM;
|
||||
int volume;
|
||||
VALUE track = Qnil;
|
||||
rb_get_args(argc, argv, "i|o", &volume, &track RB_ARG_END);
|
||||
GUARD_EXC( shState->audio().bgmSetVolume(volume, MAYBE_NIL_TRACK(track)); )
|
||||
shState->audio().bgmSetVolume(volume, MAYBE_NIL_TRACK(track));
|
||||
return Qnil;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
DEF_PLAY_STOP_POS( bgs )
|
||||
|
||||
|
|
|
@ -528,14 +528,15 @@ RB_METHOD(mkxpSystemMemory) {
|
|||
return INT2NUM(SDL_GetSystemRAM());
|
||||
}
|
||||
|
||||
RB_METHOD(mkxpReloadPathCache) {
|
||||
RB_METHOD_GUARD(mkxpReloadPathCache) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
GUARD_EXC(shState->fileSystem().reloadPathCache(););
|
||||
shState->fileSystem().reloadPathCache();
|
||||
return Qnil;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(mkxpAddPath) {
|
||||
RB_METHOD_GUARD(mkxpAddPath) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE path, mountpoint, reload;
|
||||
|
@ -545,36 +546,32 @@ RB_METHOD(mkxpAddPath) {
|
|||
|
||||
const char *mp = (mountpoint == Qnil) ? 0 : RSTRING_PTR(mountpoint);
|
||||
|
||||
try {
|
||||
bool rl = true;
|
||||
if (reload != Qnil)
|
||||
rb_bool_arg(reload, &rl);
|
||||
bool rl = true;
|
||||
if (reload != Qnil)
|
||||
rb_bool_arg(reload, &rl);
|
||||
|
||||
shState->fileSystem().addPath(RSTRING_PTR(path), mp, rl);
|
||||
|
||||
shState->fileSystem().addPath(RSTRING_PTR(path), mp, rl);
|
||||
} catch (Exception &e) {
|
||||
raiseRbExc(e);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(mkxpRemovePath) {
|
||||
RB_METHOD_GUARD(mkxpRemovePath) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE path, reload;
|
||||
rb_scan_args(argc, argv, "11", &path, &reload);
|
||||
SafeStringValue(path);
|
||||
|
||||
try {
|
||||
bool rl = true;
|
||||
if (reload != Qnil)
|
||||
rb_bool_arg(reload, &rl);
|
||||
bool rl = true;
|
||||
if (reload != Qnil)
|
||||
rb_bool_arg(reload, &rl);
|
||||
|
||||
shState->fileSystem().removePath(RSTRING_PTR(path), rl);
|
||||
|
||||
shState->fileSystem().removePath(RSTRING_PTR(path), rl);
|
||||
} catch (Exception &e) {
|
||||
raiseRbExc(e);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(mkxpFileExists) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
@ -601,24 +598,25 @@ RB_METHOD(mkxpSetDefaultFontFamily) {
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
RB_METHOD(mkxpStringToUTF8) {
|
||||
RB_METHOD_GUARD(mkxpStringToUTF8) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
rb_check_argc(argc, 0);
|
||||
|
||||
std::string ret(RSTRING_PTR(self), RSTRING_LEN(self));
|
||||
GUARD_EXC(ret = Encoding::convertString(ret); );
|
||||
ret = Encoding::convertString(ret);
|
||||
|
||||
return rb_utf8_str_new(ret.c_str(), ret.length());
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(mkxpStringToUTF8Bang) {
|
||||
RB_METHOD_GUARD(mkxpStringToUTF8Bang) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
rb_check_argc(argc, 0);
|
||||
|
||||
std::string ret(RSTRING_PTR(self), RSTRING_LEN(self));
|
||||
GUARD_EXC(ret = Encoding::convertString(ret); );
|
||||
ret = Encoding::convertString(ret);
|
||||
|
||||
rb_str_resize(self, ret.length());
|
||||
memcpy(RSTRING_PTR(self), ret.c_str(), RSTRING_LEN(self));
|
||||
|
@ -629,6 +627,7 @@ RB_METHOD(mkxpStringToUTF8Bang) {
|
|||
|
||||
return self;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define OPENCMD "open "
|
||||
|
@ -641,7 +640,7 @@ RB_METHOD(mkxpStringToUTF8Bang) {
|
|||
#define OPENARGS ""
|
||||
#endif
|
||||
|
||||
RB_METHOD(mkxpLaunch) {
|
||||
RB_METHOD_GUARD(mkxpLaunch) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE cmdname, args;
|
||||
|
@ -674,11 +673,12 @@ RB_METHOD(mkxpLaunch) {
|
|||
}
|
||||
|
||||
if (std::system(command.c_str()) != 0) {
|
||||
raiseRbExc(Exception(Exception::MKXPError, "Failed to launch \"%s\"", RSTRING_PTR(cmdname)));
|
||||
throw Exception(Exception::MKXPError, "Failed to launch \"%s\"", RSTRING_PTR(cmdname));
|
||||
}
|
||||
|
||||
return RUBY_Qnil;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
json5pp::value loadUserSettings() {
|
||||
json5pp::value ret;
|
||||
|
@ -722,7 +722,7 @@ RB_METHOD(mkxpGetJSONSetting) {
|
|||
|
||||
}
|
||||
|
||||
RB_METHOD(mkxpSetJSONSetting) {
|
||||
RB_METHOD_GUARD(mkxpSetJSONSetting) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE sname, svalue;
|
||||
|
@ -736,6 +736,7 @@ RB_METHOD(mkxpSetJSONSetting) {
|
|||
|
||||
return Qnil;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(mkxpGetAllJSONSettings) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
|
|
@ -50,28 +50,35 @@ RbData::RbData() {
|
|||
exc[IOError] = rb_eIOError;
|
||||
exc[TypeError] = rb_eTypeError;
|
||||
exc[ArgumentError] = rb_eArgError;
|
||||
exc[SystemExit] = rb_eSystemExit;
|
||||
exc[RuntimeError] = rb_eRuntimeError;
|
||||
}
|
||||
|
||||
RbData::~RbData() {}
|
||||
|
||||
/* Indexed with Exception::Type */
|
||||
static const RbException excToRbExc[] = {
|
||||
const RbException excToRbExc[] = {
|
||||
RGSS, /* RGSSError */
|
||||
ErrnoENOENT, /* NoFileError */
|
||||
IOError,
|
||||
|
||||
TypeError, ArgumentError,
|
||||
TypeError, ArgumentError, SystemExit, RuntimeError,
|
||||
|
||||
PHYSFS, /* PHYSFSError */
|
||||
SDL, /* SDLError */
|
||||
MKXP /* MKXPError */
|
||||
};
|
||||
|
||||
void raiseRbExc(const Exception &exc) {
|
||||
VALUE excToRbClass(const Exception &exc) {
|
||||
RbData *data = getRbData();
|
||||
return data->exc[excToRbExc[exc.type]];
|
||||
}
|
||||
|
||||
void raiseRbExc(Exception exc) {
|
||||
RbData *data = getRbData();
|
||||
VALUE excClass = data->exc[excToRbExc[exc.type]];
|
||||
|
||||
rb_raise(excClass, "%s", exc.msg.c_str());
|
||||
rb_raise(excClass, "%s", exc.msg);
|
||||
}
|
||||
|
||||
void raiseDisposedAccess(VALUE self) {
|
||||
|
@ -89,207 +96,224 @@ void raiseDisposedAccess(VALUE self) {
|
|||
}
|
||||
|
||||
int rb_get_args(int argc, VALUE *argv, const char *format, ...) {
|
||||
char c;
|
||||
VALUE *arg = argv;
|
||||
va_list ap;
|
||||
bool opt = false;
|
||||
int argI = 0;
|
||||
Exception *exc = 0;
|
||||
try{
|
||||
char c;
|
||||
VALUE *arg = argv;
|
||||
va_list ap;
|
||||
bool opt = false;
|
||||
int argI = 0;
|
||||
|
||||
va_start(ap, format);
|
||||
va_start(ap, format);
|
||||
|
||||
while ((c = *format++)) {
|
||||
switch (c) {
|
||||
case '|':
|
||||
break;
|
||||
default:
|
||||
// FIXME print num of needed args vs provided
|
||||
if (argc <= argI && !opt)
|
||||
rb_raise(rb_eArgError, "wrong number of arguments");
|
||||
while ((c = *format++)) {
|
||||
switch (c) {
|
||||
case '|':
|
||||
break;
|
||||
default:
|
||||
// FIXME print num of needed args vs provided
|
||||
if (argc <= argI && !opt)
|
||||
rb_raise(rb_eArgError, "wrong number of arguments");
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (argI >= argc)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 'o': {
|
||||
if (argI >= argc)
|
||||
break;
|
||||
|
||||
VALUE *obj = va_arg(ap, VALUE *);
|
||||
switch (c) {
|
||||
case 'o': {
|
||||
if (argI >= argc)
|
||||
break;
|
||||
|
||||
*obj = *arg++;
|
||||
++argI;
|
||||
VALUE *obj = va_arg(ap, VALUE *);
|
||||
|
||||
break;
|
||||
}
|
||||
*obj = *arg++;
|
||||
++argI;
|
||||
|
||||
case 'S': {
|
||||
if (argI >= argc)
|
||||
break;
|
||||
}
|
||||
|
||||
case 'S': {
|
||||
if (argI >= argc)
|
||||
break;
|
||||
|
||||
VALUE *str = va_arg(ap, VALUE *);
|
||||
VALUE tmp = *arg;
|
||||
|
||||
if (!RB_TYPE_P(tmp, RUBY_T_STRING))
|
||||
rb_raise(rb_eTypeError, "Argument %d: Expected string", argI);
|
||||
|
||||
*str = tmp;
|
||||
++argI;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 's': {
|
||||
if (argI >= argc)
|
||||
break;
|
||||
|
||||
const char **s = va_arg(ap, const char **);
|
||||
int *len = va_arg(ap, int *);
|
||||
|
||||
VALUE tmp = *arg;
|
||||
|
||||
if (!RB_TYPE_P(tmp, RUBY_T_STRING))
|
||||
rb_raise(rb_eTypeError, "Argument %d: Expected string", argI);
|
||||
|
||||
*s = RSTRING_PTR(tmp);
|
||||
*len = RSTRING_LEN(tmp);
|
||||
++argI;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'z': {
|
||||
if (argI >= argc)
|
||||
break;
|
||||
|
||||
const char **s = va_arg(ap, const char **);
|
||||
|
||||
VALUE tmp = *arg++;
|
||||
|
||||
if (!RB_TYPE_P(tmp, RUBY_T_STRING))
|
||||
rb_raise(rb_eTypeError, "Argument %d: Expected string", argI);
|
||||
|
||||
*s = RSTRING_PTR(tmp);
|
||||
++argI;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'f': {
|
||||
if (argI >= argc)
|
||||
break;
|
||||
|
||||
double *f = va_arg(ap, double *);
|
||||
VALUE fVal = *arg++;
|
||||
|
||||
rb_float_arg(fVal, f, argI);
|
||||
|
||||
++argI;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'i': {
|
||||
if (argI >= argc)
|
||||
break;
|
||||
|
||||
int *i = va_arg(ap, int *);
|
||||
VALUE iVal = *arg++;
|
||||
|
||||
rb_int_arg(iVal, i, argI);
|
||||
|
||||
++argI;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'b': {
|
||||
if (argI >= argc)
|
||||
break;
|
||||
|
||||
bool *b = va_arg(ap, bool *);
|
||||
VALUE bVal = *arg++;
|
||||
|
||||
rb_bool_arg(bVal, b, argI);
|
||||
|
||||
++argI;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'n': {
|
||||
if (argI >= argc)
|
||||
break;
|
||||
|
||||
ID *sym = va_arg(ap, ID *);
|
||||
|
||||
VALUE symVal = *arg++;
|
||||
|
||||
if (!SYMBOL_P(symVal))
|
||||
rb_raise(rb_eTypeError, "Argument %d: Expected symbol", argI);
|
||||
|
||||
*sym = SYM2ID(symVal);
|
||||
++argI;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case '|':
|
||||
opt = true;
|
||||
break;
|
||||
|
||||
VALUE *str = va_arg(ap, VALUE *);
|
||||
VALUE tmp = *arg;
|
||||
|
||||
if (!RB_TYPE_P(tmp, RUBY_T_STRING))
|
||||
rb_raise(rb_eTypeError, "Argument %d: Expected string", argI);
|
||||
|
||||
*str = tmp;
|
||||
++argI;
|
||||
|
||||
break;
|
||||
default:
|
||||
rb_raise(rb_eFatal, "invalid argument specifier %c", c);
|
||||
}
|
||||
}
|
||||
|
||||
case 's': {
|
||||
if (argI >= argc)
|
||||
break;
|
||||
|
||||
const char **s = va_arg(ap, const char **);
|
||||
int *len = va_arg(ap, int *);
|
||||
|
||||
VALUE tmp = *arg;
|
||||
|
||||
if (!RB_TYPE_P(tmp, RUBY_T_STRING))
|
||||
rb_raise(rb_eTypeError, "Argument %d: Expected string", argI);
|
||||
|
||||
*s = RSTRING_PTR(tmp);
|
||||
*len = RSTRING_LEN(tmp);
|
||||
++argI;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'z': {
|
||||
if (argI >= argc)
|
||||
break;
|
||||
|
||||
const char **s = va_arg(ap, const char **);
|
||||
|
||||
VALUE tmp = *arg++;
|
||||
|
||||
if (!RB_TYPE_P(tmp, RUBY_T_STRING))
|
||||
rb_raise(rb_eTypeError, "Argument %d: Expected string", argI);
|
||||
|
||||
*s = RSTRING_PTR(tmp);
|
||||
++argI;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'f': {
|
||||
if (argI >= argc)
|
||||
break;
|
||||
|
||||
double *f = va_arg(ap, double *);
|
||||
VALUE fVal = *arg++;
|
||||
|
||||
rb_float_arg(fVal, f, argI);
|
||||
|
||||
++argI;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'i': {
|
||||
if (argI >= argc)
|
||||
break;
|
||||
|
||||
int *i = va_arg(ap, int *);
|
||||
VALUE iVal = *arg++;
|
||||
|
||||
rb_int_arg(iVal, i, argI);
|
||||
|
||||
++argI;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'b': {
|
||||
if (argI >= argc)
|
||||
break;
|
||||
|
||||
bool *b = va_arg(ap, bool *);
|
||||
VALUE bVal = *arg++;
|
||||
|
||||
rb_bool_arg(bVal, b, argI);
|
||||
|
||||
++argI;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'n': {
|
||||
if (argI >= argc)
|
||||
break;
|
||||
|
||||
ID *sym = va_arg(ap, ID *);
|
||||
|
||||
VALUE symVal = *arg++;
|
||||
|
||||
if (!SYMBOL_P(symVal))
|
||||
rb_raise(rb_eTypeError, "Argument %d: Expected symbol", argI);
|
||||
|
||||
*sym = SYM2ID(symVal);
|
||||
++argI;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case '|':
|
||||
opt = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
rb_raise(rb_eFatal, "invalid argument specifier %c", c);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
||||
/* Pop remaining arg pointers off
|
||||
* the stack to check for RB_ARG_END */
|
||||
format--;
|
||||
/* Pop remaining arg pointers off
|
||||
* the stack to check for RB_ARG_END */
|
||||
format--;
|
||||
|
||||
while ((c = *format++)) {
|
||||
switch (c) {
|
||||
case 'o':
|
||||
case 'S':
|
||||
va_arg(ap, VALUE *);
|
||||
break;
|
||||
while ((c = *format++)) {
|
||||
switch (c) {
|
||||
case 'o':
|
||||
case 'S':
|
||||
va_arg(ap, VALUE *);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
va_arg(ap, const char **);
|
||||
va_arg(ap, int *);
|
||||
break;
|
||||
case 's':
|
||||
va_arg(ap, const char **);
|
||||
va_arg(ap, int *);
|
||||
break;
|
||||
|
||||
case 'z':
|
||||
va_arg(ap, const char **);
|
||||
break;
|
||||
case 'z':
|
||||
va_arg(ap, const char **);
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
va_arg(ap, double *);
|
||||
break;
|
||||
case 'f':
|
||||
va_arg(ap, double *);
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
va_arg(ap, int *);
|
||||
break;
|
||||
case 'i':
|
||||
va_arg(ap, int *);
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
va_arg(ap, bool *);
|
||||
break;
|
||||
case 'b':
|
||||
va_arg(ap, bool *);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME print num of needed args vs provided
|
||||
if (!c && argc > argI)
|
||||
rb_raise(rb_eArgError, "wrong number of arguments");
|
||||
// FIXME print num of needed args vs provided
|
||||
if (!c && argc > argI)
|
||||
rb_raise(rb_eArgError, "wrong number of arguments");
|
||||
|
||||
/* Verify correct termination */
|
||||
void *argEnd = va_arg(ap, void *);
|
||||
(void)argEnd;
|
||||
assert(argEnd == RB_ARG_END_VAL);
|
||||
/* Verify correct termination */
|
||||
void *argEnd = va_arg(ap, void *);
|
||||
(void)argEnd;
|
||||
assert(argEnd == RB_ARG_END_VAL);
|
||||
|
||||
#endif
|
||||
|
||||
va_end(ap);
|
||||
va_end(ap);
|
||||
|
||||
return argI;
|
||||
return argI;
|
||||
} catch (const Exception &e) {
|
||||
exc = new Exception(e);
|
||||
}
|
||||
|
||||
/* This should always be true if we reach here */
|
||||
if (exc) {
|
||||
/* Raising here is probably fine, right?
|
||||
* If any methods allocate something with a destructor before
|
||||
* calling this then they can probably be fixed to not do that. */
|
||||
Exception e(*exc);
|
||||
delete exc;
|
||||
rb_raise(excToRbClass(e), "%s", e.msg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -55,6 +55,8 @@ enum RbException {
|
|||
|
||||
TypeError,
|
||||
ArgumentError,
|
||||
SystemExit,
|
||||
RuntimeError,
|
||||
|
||||
RbExceptionsMax
|
||||
};
|
||||
|
@ -73,7 +75,8 @@ RbData *getRbData();
|
|||
|
||||
struct Exception;
|
||||
|
||||
void raiseRbExc(const Exception &exc);
|
||||
VALUE excToRbClass(const Exception &exc);
|
||||
void raiseRbExc(Exception exc);
|
||||
|
||||
#if RAPI_FULL > 187
|
||||
#define DECL_TYPE(Klass) extern rb_data_type_t Klass##Type
|
||||
|
@ -315,16 +318,16 @@ raiseRbExc(exc); \
|
|||
} \
|
||||
}
|
||||
|
||||
#define GFX_GUARD_EXC(exp) \
|
||||
{\
|
||||
GFX_LOCK; \
|
||||
try {\
|
||||
#define GFX_GUARD_EXC(exp) \
|
||||
{ \
|
||||
GFX_LOCK; \
|
||||
try { \
|
||||
exp \
|
||||
} catch (const Exception &exc) {\
|
||||
GFX_UNLOCK; \
|
||||
raiseRbExc(exc); \
|
||||
}\
|
||||
GFX_UNLOCK;\
|
||||
} catch (const Exception &exc) { \
|
||||
GFX_UNLOCK; \
|
||||
throw exc; \
|
||||
} \
|
||||
GFX_UNLOCK; \
|
||||
}
|
||||
|
||||
|
||||
|
@ -338,7 +341,7 @@ static inline VALUE objectLoad(int argc, VALUE *argv, VALUE self) {
|
|||
|
||||
C *c = 0;
|
||||
|
||||
GUARD_EXC(c = C::deserialize(data, dataLen););
|
||||
c = C::deserialize(data, dataLen);
|
||||
|
||||
setPrivateData(obj, c);
|
||||
|
||||
|
@ -358,7 +361,7 @@ inline void rb_float_arg(VALUE arg, double *out, int argPos = 0) {
|
|||
break;
|
||||
|
||||
default:
|
||||
rb_raise(rb_eTypeError, "Argument %d: Expected float", argPos);
|
||||
throw Exception(Exception::TypeError, "Argument %d: Expected float", argPos);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -374,7 +377,7 @@ inline void rb_int_arg(VALUE arg, int *out, int argPos = 0) {
|
|||
break;
|
||||
|
||||
default:
|
||||
rb_raise(rb_eTypeError, "Argument %d: Expected fixnum", argPos);
|
||||
throw Exception(Exception::TypeError, "Argument %d: Expected fixnum", argPos);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -390,10 +393,13 @@ inline void rb_bool_arg(VALUE arg, bool *out, int argPos = 0) {
|
|||
break;
|
||||
|
||||
default:
|
||||
rb_raise(rb_eTypeError, "Argument %d: Expected bool", argPos);
|
||||
throw Exception(Exception::TypeError, "Argument %d: Expected bool", argPos);
|
||||
}
|
||||
}
|
||||
|
||||
/* rb_check_argc and rb_error_arity are both
|
||||
* consistently called before any C++ objects are allocated,
|
||||
* so we can just call rb_raise directly in them */
|
||||
inline void rb_check_argc(int actual, int expected) {
|
||||
if (actual != expected)
|
||||
rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", actual,
|
||||
|
@ -431,21 +437,41 @@ static inline VALUE rb_file_open_str(VALUE filename, const char *mode) {
|
|||
(void)self; \
|
||||
}
|
||||
|
||||
/* Calling rb_raise inside the catch block
|
||||
* leaks memory even if we catch by value */
|
||||
#define RB_METHOD_GUARD(name) RB_METHOD(name) \
|
||||
{ \
|
||||
Exception *exc = 0; \
|
||||
try{ \
|
||||
|
||||
#define RB_METHOD_GUARD_END \
|
||||
} catch (const Exception &e) { \
|
||||
exc = new Exception(e); \
|
||||
} \
|
||||
if (exc) { \
|
||||
Exception e(*exc); \
|
||||
delete exc; \
|
||||
rb_raise(excToRbClass(e), "%s", e.msg); \
|
||||
} \
|
||||
return Qnil; \
|
||||
}
|
||||
|
||||
#define MARSH_LOAD_FUN(Typ) \
|
||||
RB_METHOD(Typ##Load) { return objectLoad<Typ>(argc, argv, self); }
|
||||
RB_METHOD_GUARD(Typ##Load) { return objectLoad<Typ>(argc, argv, self); } RB_METHOD_GUARD_END
|
||||
|
||||
#define INITCOPY_FUN(Klass) \
|
||||
RB_METHOD(Klass##InitializeCopy) { \
|
||||
RB_METHOD_GUARD(Klass##InitializeCopy) { \
|
||||
VALUE origObj; \
|
||||
rb_get_args(argc, argv, "o", &origObj RB_ARG_END); \
|
||||
if (!OBJ_INIT_COPY(self, origObj)) /* When would this fail??*/ \
|
||||
return self; \
|
||||
Klass *orig = getPrivateData<Klass>(origObj); \
|
||||
Klass *k = 0; \
|
||||
GUARD_EXC(k = new Klass(*orig);) \
|
||||
k = new Klass(*orig); \
|
||||
setPrivateData(self, k); \
|
||||
return self; \
|
||||
}
|
||||
} \
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
/* Object property which is copied by reference, with allowed NIL
|
||||
* FIXME: Getter assumes prop is disposable,
|
||||
|
@ -461,7 +487,7 @@ RB_METHOD(Klass##Get##PropName) { \
|
|||
RB_UNUSED_PARAM; \
|
||||
return rb_iv_get(self, prop_iv); \
|
||||
} \
|
||||
RB_METHOD(Klass##Set##PropName) { \
|
||||
RB_METHOD_GUARD(Klass##Set##PropName) { \
|
||||
RB_UNUSED_PARAM; \
|
||||
rb_check_argc(argc, 1); \
|
||||
Klass *k = getPrivateData<Klass>(self); \
|
||||
|
@ -471,17 +497,18 @@ if (NIL_P(propObj)) \
|
|||
prop = 0; \
|
||||
else \
|
||||
prop = getPrivateDataCheck<PropKlass>(propObj, PropKlass##Type); \
|
||||
GUARD_EXC(k->set##PropName(prop);) \
|
||||
k->set##PropName(prop) \
|
||||
rb_iv_set(self, prop_iv, propObj); \
|
||||
return propObj; \
|
||||
}
|
||||
} \
|
||||
RB_METHOD_GUARD_END
|
||||
#else
|
||||
#define DEF_PROP_OBJ_REF(Klass, PropKlass, PropName, prop_iv) \
|
||||
RB_METHOD(Klass##Get##PropName) { \
|
||||
RB_UNUSED_PARAM; \
|
||||
return rb_iv_get(self, prop_iv); \
|
||||
} \
|
||||
RB_METHOD(Klass##Set##PropName) { \
|
||||
RB_METHOD_GUARD(Klass##Set##PropName) { \
|
||||
RB_UNUSED_PARAM; \
|
||||
rb_check_argc(argc, 1); \
|
||||
Klass *k = getPrivateData<Klass>(self); \
|
||||
|
@ -491,10 +518,11 @@ if (NIL_P(propObj)) \
|
|||
prop = 0; \
|
||||
else \
|
||||
prop = getPrivateDataCheck<PropKlass>(propObj, #PropKlass); \
|
||||
GUARD_EXC(k->set##PropName(prop);) \
|
||||
k->set##PropName(prop) \
|
||||
rb_iv_set(self, prop_iv, propObj); \
|
||||
return propObj; \
|
||||
}
|
||||
} \
|
||||
RB_METHOD_GUARD_END
|
||||
#endif
|
||||
|
||||
/* Object property which is copied by value, not reference */
|
||||
|
@ -505,15 +533,16 @@ RB_UNUSED_PARAM; \
|
|||
checkDisposed<Klass>(self); \
|
||||
return rb_iv_get(self, prop_iv); \
|
||||
} \
|
||||
RB_METHOD(Klass##Set##PropName) { \
|
||||
RB_METHOD_GUARD(Klass##Set##PropName) { \
|
||||
rb_check_argc(argc, 1); \
|
||||
Klass *k = getPrivateData<Klass>(self); \
|
||||
VALUE propObj = *argv; \
|
||||
PropKlass *prop; \
|
||||
prop = getPrivateDataCheck<PropKlass>(propObj, PropKlass##Type); \
|
||||
GUARD_EXC(k->set##PropName(*prop);) \
|
||||
k->set##PropName(*prop); \
|
||||
return propObj; \
|
||||
}
|
||||
} \
|
||||
RB_METHOD_GUARD_END
|
||||
#else
|
||||
#define DEF_PROP_OBJ_VAL(Klass, PropKlass, PropName, prop_iv) \
|
||||
RB_METHOD(Klass##Get##PropName) { \
|
||||
|
@ -521,33 +550,36 @@ RB_UNUSED_PARAM; \
|
|||
checkDisposed<Klass>(self); \
|
||||
return rb_iv_get(self, prop_iv); \
|
||||
} \
|
||||
RB_METHOD(Klass##Set##PropName) { \
|
||||
RB_METHOD_GUARD(Klass##Set##PropName) { \
|
||||
rb_check_argc(argc, 1); \
|
||||
Klass *k = getPrivateData<Klass>(self); \
|
||||
VALUE propObj = *argv; \
|
||||
PropKlass *prop; \
|
||||
prop = getPrivateDataCheck<PropKlass>(propObj, #PropKlass); \
|
||||
GUARD_EXC(k->set##PropName(*prop);) \
|
||||
k->set##PropName(*prop); \
|
||||
return propObj; \
|
||||
}
|
||||
} \
|
||||
RB_METHOD_GUARD_END
|
||||
#endif
|
||||
|
||||
#define DEF_PROP(Klass, type, PropName, arg_fun, value_fun) \
|
||||
RB_METHOD(Klass##Get##PropName) { \
|
||||
#define DEF_PROP(Klass, type, PropName, arg_fun, value_fun) \
|
||||
RB_METHOD_GUARD(Klass##Get##PropName) { \
|
||||
RB_UNUSED_PARAM; \
|
||||
Klass *k = getPrivateData<Klass>(self); \
|
||||
type value = 0; \
|
||||
GUARD_EXC(value = k->get##PropName();) \
|
||||
value = k->get##PropName(); \
|
||||
return value_fun(value); \
|
||||
} \
|
||||
RB_METHOD(Klass##Set##PropName) { \
|
||||
} \
|
||||
RB_METHOD_GUARD_END \
|
||||
RB_METHOD_GUARD(Klass##Set##PropName) { \
|
||||
rb_check_argc(argc, 1); \
|
||||
Klass *k = getPrivateData<Klass>(self); \
|
||||
type value; \
|
||||
rb_##arg_fun##_arg(*argv, &value); \
|
||||
GUARD_EXC(k->set##PropName(value);) \
|
||||
k->set##PropName(value); \
|
||||
return *argv; \
|
||||
}
|
||||
} \
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
#define DEF_PROP_I(Klass, PropName) \
|
||||
DEF_PROP(Klass, int, PropName, int, rb_fix_new)
|
||||
|
@ -573,7 +605,7 @@ RB_METHOD(Klass##Get##PropName) { \
|
|||
RB_UNUSED_PARAM; \
|
||||
return rb_iv_get(self, prop_iv); \
|
||||
} \
|
||||
RB_METHOD(Klass##Set##PropName) { \
|
||||
RB_METHOD_GUARD(Klass##Set##PropName) { \
|
||||
RB_UNUSED_PARAM; \
|
||||
rb_check_argc(argc, 1); \
|
||||
Klass *k = getPrivateData<Klass>(self); \
|
||||
|
@ -586,7 +618,8 @@ prop = getPrivateDataCheck<PropKlass>(propObj, PropKlass##Type); \
|
|||
GFX_GUARD_EXC(k->set##PropName(prop);) \
|
||||
rb_iv_set(self, prop_iv, propObj); \
|
||||
return propObj; \
|
||||
}
|
||||
} \
|
||||
RB_METHOD_GUARD_END
|
||||
#else
|
||||
#define DEF_GFX_PROP_OBJ_REF(Klass, PropKlass, PropName, prop_iv) \
|
||||
DEF_PROP_OBJ_REF(Klass, PropKlass, PropName, prop_iv)
|
||||
|
@ -600,7 +633,7 @@ RB_UNUSED_PARAM; \
|
|||
checkDisposed<Klass>(self); \
|
||||
return rb_iv_get(self, prop_iv); \
|
||||
} \
|
||||
RB_METHOD(Klass##Set##PropName) { \
|
||||
RB_METHOD_GUARD(Klass##Set##PropName) { \
|
||||
rb_check_argc(argc, 1); \
|
||||
Klass *k = getPrivateData<Klass>(self); \
|
||||
VALUE propObj = *argv; \
|
||||
|
@ -608,28 +641,31 @@ PropKlass *prop; \
|
|||
prop = getPrivateDataCheck<PropKlass>(propObj, PropKlass##Type); \
|
||||
GFX_GUARD_EXC(k->set##PropName(*prop);) \
|
||||
return propObj; \
|
||||
}
|
||||
} \
|
||||
RB_METHOD_GUARD_END
|
||||
#else
|
||||
#define DEF_GFX_PROP_OBJ_VAL(Klass, PropKlass, PropName, prop_iv) \
|
||||
DEF_PROP_OBJ_VAL(Klass, PropKlass, PropName, prop_iv)
|
||||
#endif
|
||||
|
||||
#define DEF_GFX_PROP(Klass, type, PropName, arg_fun, value_fun) \
|
||||
RB_METHOD(Klass##Get##PropName) { \
|
||||
#define DEF_GFX_PROP(Klass, type, PropName, arg_fun, value_fun) \
|
||||
RB_METHOD_GUARD(Klass##Get##PropName) { \
|
||||
RB_UNUSED_PARAM; \
|
||||
Klass *k = getPrivateData<Klass>(self); \
|
||||
type value = 0; \
|
||||
GUARD_EXC(value = k->get##PropName();) \
|
||||
value = k->get##PropName(); \
|
||||
return value_fun(value); \
|
||||
} \
|
||||
RB_METHOD(Klass##Set##PropName) { \
|
||||
RB_METHOD_GUARD_END \
|
||||
RB_METHOD_GUARD(Klass##Set##PropName) { \
|
||||
rb_check_argc(argc, 1); \
|
||||
Klass *k = getPrivateData<Klass>(self); \
|
||||
type value; \
|
||||
rb_##arg_fun##_arg(*argv, &value); \
|
||||
GFX_GUARD_EXC(k->set##PropName(value);) \
|
||||
return *argv; \
|
||||
}
|
||||
} \
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
#define DEF_GFX_PROP_I(Klass, PropName) \
|
||||
DEF_GFX_PROP(Klass, int, PropName, int, rb_fix_new)
|
||||
|
|
|
@ -64,7 +64,7 @@ void bitmapInitProps(Bitmap *b, VALUE self) {
|
|||
b->setInitFont(font);
|
||||
}
|
||||
|
||||
RB_METHOD(bitmapInitialize) {
|
||||
RB_METHOD_GUARD(bitmapInitialize) {
|
||||
Bitmap *b = 0;
|
||||
|
||||
if (argc == 1) {
|
||||
|
@ -84,45 +84,49 @@ RB_METHOD(bitmapInitialize) {
|
|||
|
||||
return self;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapWidth) {
|
||||
RB_METHOD_GUARD(bitmapWidth) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
Bitmap *b = getPrivateData<Bitmap>(self);
|
||||
|
||||
int value = 0;
|
||||
GUARD_EXC(value = b->width(););
|
||||
value = b->width();
|
||||
|
||||
return INT2FIX(value);
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapHeight) {
|
||||
RB_METHOD_GUARD(bitmapHeight) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
Bitmap *b = getPrivateData<Bitmap>(self);
|
||||
|
||||
int value = 0;
|
||||
GUARD_EXC(value = b->height(););
|
||||
value = b->height();
|
||||
|
||||
return INT2FIX(value);
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
DEF_GFX_PROP_OBJ_REF(Bitmap, Bitmap, Hires, "hires")
|
||||
|
||||
RB_METHOD(bitmapRect) {
|
||||
RB_METHOD_GUARD(bitmapRect) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
Bitmap *b = getPrivateData<Bitmap>(self);
|
||||
|
||||
IntRect rect;
|
||||
GUARD_EXC(rect = b->rect(););
|
||||
rect = b->rect();
|
||||
|
||||
Rect *r = new Rect(rect);
|
||||
|
||||
return wrapObject(r, RectType);
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapBlt) {
|
||||
RB_METHOD_GUARD(bitmapBlt) {
|
||||
Bitmap *b = getPrivateData<Bitmap>(self);
|
||||
|
||||
int x, y;
|
||||
|
@ -143,8 +147,9 @@ RB_METHOD(bitmapBlt) {
|
|||
|
||||
return self;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapStretchBlt) {
|
||||
RB_METHOD_GUARD(bitmapStretchBlt) {
|
||||
Bitmap *b = getPrivateData<Bitmap>(self);
|
||||
|
||||
VALUE destRectObj;
|
||||
|
@ -167,8 +172,9 @@ RB_METHOD(bitmapStretchBlt) {
|
|||
|
||||
return self;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapFillRect) {
|
||||
RB_METHOD_GUARD(bitmapFillRect) {
|
||||
Bitmap *b = getPrivateData<Bitmap>(self);
|
||||
|
||||
VALUE colorObj;
|
||||
|
@ -197,8 +203,9 @@ RB_METHOD(bitmapFillRect) {
|
|||
|
||||
return self;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapClear) {
|
||||
RB_METHOD_GUARD(bitmapClear) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
Bitmap *b = getPrivateData<Bitmap>(self);
|
||||
|
@ -207,8 +214,9 @@ RB_METHOD(bitmapClear) {
|
|||
|
||||
return self;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapGetPixel) {
|
||||
RB_METHOD_GUARD(bitmapGetPixel) {
|
||||
Bitmap *b = getPrivateData<Bitmap>(self);
|
||||
|
||||
int x, y;
|
||||
|
@ -216,14 +224,18 @@ RB_METHOD(bitmapGetPixel) {
|
|||
rb_get_args(argc, argv, "ii", &x, &y RB_ARG_END);
|
||||
|
||||
Color value;
|
||||
GUARD_EXC(value = b->getPixel(x, y););
|
||||
if (b->surface() || b->megaSurface())
|
||||
value = b->getPixel(x, y);
|
||||
else
|
||||
GFX_GUARD_EXC(value = b->getPixel(x, y););
|
||||
|
||||
Color *color = new Color(value);
|
||||
|
||||
return wrapObject(color, ColorType);
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapSetPixel) {
|
||||
RB_METHOD_GUARD(bitmapSetPixel) {
|
||||
Bitmap *b = getPrivateData<Bitmap>(self);
|
||||
|
||||
int x, y;
|
||||
|
@ -239,8 +251,9 @@ RB_METHOD(bitmapSetPixel) {
|
|||
|
||||
return self;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapHueChange) {
|
||||
RB_METHOD_GUARD(bitmapHueChange) {
|
||||
Bitmap *b = getPrivateData<Bitmap>(self);
|
||||
|
||||
int hue;
|
||||
|
@ -251,8 +264,9 @@ RB_METHOD(bitmapHueChange) {
|
|||
|
||||
return self;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapDrawText) {
|
||||
RB_METHOD_GUARD(bitmapDrawText) {
|
||||
Bitmap *b = getPrivateData<Bitmap>(self);
|
||||
|
||||
const char *str;
|
||||
|
@ -293,8 +307,9 @@ RB_METHOD(bitmapDrawText) {
|
|||
|
||||
return self;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapTextSize) {
|
||||
RB_METHOD_GUARD(bitmapTextSize) {
|
||||
Bitmap *b = getPrivateData<Bitmap>(self);
|
||||
|
||||
const char *str;
|
||||
|
@ -309,16 +324,17 @@ RB_METHOD(bitmapTextSize) {
|
|||
}
|
||||
|
||||
IntRect value;
|
||||
GUARD_EXC(value = b->textSize(str););
|
||||
value = b->textSize(str);
|
||||
|
||||
Rect *rect = new Rect(value);
|
||||
|
||||
return wrapObject(rect, RectType);
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
DEF_GFX_PROP_OBJ_VAL(Bitmap, Font, Font, "font")
|
||||
|
||||
RB_METHOD(bitmapGradientFillRect) {
|
||||
RB_METHOD_GUARD(bitmapGradientFillRect) {
|
||||
Bitmap *b = getPrivateData<Bitmap>(self);
|
||||
|
||||
VALUE color1Obj, color2Obj;
|
||||
|
@ -353,8 +369,9 @@ RB_METHOD(bitmapGradientFillRect) {
|
|||
|
||||
return self;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapClearRect) {
|
||||
RB_METHOD_GUARD(bitmapClearRect) {
|
||||
Bitmap *b = getPrivateData<Bitmap>(self);
|
||||
|
||||
if (argc == 1) {
|
||||
|
@ -376,33 +393,32 @@ RB_METHOD(bitmapClearRect) {
|
|||
|
||||
return self;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapBlur) {
|
||||
RB_METHOD_GUARD(bitmapBlur) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
Bitmap *b = getPrivateData<Bitmap>(self);
|
||||
|
||||
GFX_LOCK;
|
||||
b->blur();
|
||||
GFX_UNLOCK;
|
||||
GFX_GUARD_EXC( b->blur(); );
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapRadialBlur) {
|
||||
RB_METHOD_GUARD(bitmapRadialBlur) {
|
||||
Bitmap *b = getPrivateData<Bitmap>(self);
|
||||
|
||||
int angle, divisions;
|
||||
rb_get_args(argc, argv, "ii", &angle, &divisions RB_ARG_END);
|
||||
|
||||
GFX_LOCK;
|
||||
b->radialBlur(angle, divisions);
|
||||
GFX_UNLOCK;
|
||||
GFX_GUARD_EXC( b->radialBlur(angle, divisions); );
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapGetRawData) {
|
||||
RB_METHOD_GUARD(bitmapGetRawData) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
Bitmap *b = getPrivateData<Bitmap>(self);
|
||||
|
@ -413,8 +429,9 @@ RB_METHOD(bitmapGetRawData) {
|
|||
|
||||
return ret;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapSetRawData) {
|
||||
RB_METHOD_GUARD(bitmapSetRawData) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE str;
|
||||
|
@ -427,8 +444,9 @@ RB_METHOD(bitmapSetRawData) {
|
|||
|
||||
return self;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapSaveToFile) {
|
||||
RB_METHOD_GUARD(bitmapSaveToFile) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE str;
|
||||
|
@ -441,8 +459,9 @@ RB_METHOD(bitmapSaveToFile) {
|
|||
|
||||
return RUBY_Qnil;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapGetMega){
|
||||
RB_METHOD_GUARD(bitmapGetMega){
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
rb_check_argc(argc, 0);
|
||||
|
@ -455,8 +474,9 @@ RB_METHOD(bitmapGetMega){
|
|||
|
||||
return ret;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapGetAnimated){
|
||||
RB_METHOD_GUARD(bitmapGetAnimated){
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
rb_check_argc(argc, 0);
|
||||
|
@ -469,8 +489,9 @@ RB_METHOD(bitmapGetAnimated){
|
|||
|
||||
return ret;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapGetPlaying){
|
||||
RB_METHOD_GUARD(bitmapGetPlaying){
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
rb_check_argc(argc, 0);
|
||||
|
@ -479,8 +500,9 @@ RB_METHOD(bitmapGetPlaying){
|
|||
|
||||
return rb_bool_new(b->isPlaying());
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapSetPlaying){
|
||||
RB_METHOD_GUARD(bitmapSetPlaying){
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
bool play;
|
||||
|
@ -493,8 +515,9 @@ RB_METHOD(bitmapSetPlaying){
|
|||
|
||||
return RUBY_Qnil;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapPlay){
|
||||
RB_METHOD_GUARD(bitmapPlay){
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
rb_check_argc(argc, 0);
|
||||
|
@ -504,8 +527,9 @@ RB_METHOD(bitmapPlay){
|
|||
|
||||
return RUBY_Qnil;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapStop){
|
||||
RB_METHOD_GUARD(bitmapStop){
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
rb_check_argc(argc, 0);
|
||||
|
@ -515,8 +539,9 @@ RB_METHOD(bitmapStop){
|
|||
|
||||
return RUBY_Qnil;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapGotoStop){
|
||||
RB_METHOD_GUARD(bitmapGotoStop){
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
int frame;
|
||||
|
@ -529,8 +554,9 @@ RB_METHOD(bitmapGotoStop){
|
|||
|
||||
return RUBY_Qnil;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapGotoPlay){
|
||||
RB_METHOD_GUARD(bitmapGotoPlay){
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
int frame;
|
||||
|
@ -543,8 +569,9 @@ RB_METHOD(bitmapGotoPlay){
|
|||
|
||||
return RUBY_Qnil;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapFrames){
|
||||
RB_METHOD_GUARD(bitmapFrames){
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
rb_check_argc(argc, 0);
|
||||
|
@ -553,8 +580,9 @@ RB_METHOD(bitmapFrames){
|
|||
|
||||
return INT2NUM(b->numFrames());
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapCurrentFrame){
|
||||
RB_METHOD_GUARD(bitmapCurrentFrame){
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
rb_check_argc(argc, 0);
|
||||
|
@ -563,8 +591,9 @@ RB_METHOD(bitmapCurrentFrame){
|
|||
|
||||
return INT2NUM(b->currentFrameI());
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapAddFrame){
|
||||
RB_METHOD_GUARD(bitmapAddFrame){
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE srcBitmap;
|
||||
|
@ -588,8 +617,9 @@ RB_METHOD(bitmapAddFrame){
|
|||
|
||||
return INT2NUM(ret);
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapRemoveFrame){
|
||||
RB_METHOD_GUARD(bitmapRemoveFrame){
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE position;
|
||||
|
@ -608,8 +638,9 @@ RB_METHOD(bitmapRemoveFrame){
|
|||
|
||||
return RUBY_Qnil;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapNextFrame){
|
||||
RB_METHOD_GUARD(bitmapNextFrame){
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
rb_check_argc(argc, 0);
|
||||
|
@ -620,8 +651,9 @@ RB_METHOD(bitmapNextFrame){
|
|||
|
||||
return INT2NUM(b->currentFrameI());
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapPreviousFrame){
|
||||
RB_METHOD_GUARD(bitmapPreviousFrame){
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
rb_check_argc(argc, 0);
|
||||
|
@ -632,8 +664,9 @@ RB_METHOD(bitmapPreviousFrame){
|
|||
|
||||
return INT2NUM(b->currentFrameI());
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapSetFPS){
|
||||
RB_METHOD_GUARD(bitmapSetFPS){
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE fps;
|
||||
|
@ -652,8 +685,9 @@ RB_METHOD(bitmapSetFPS){
|
|||
|
||||
return RUBY_Qnil;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapGetFPS){
|
||||
RB_METHOD_GUARD(bitmapGetFPS){
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
rb_check_argc(argc, 0);
|
||||
|
@ -662,12 +696,13 @@ RB_METHOD(bitmapGetFPS){
|
|||
|
||||
float ret;
|
||||
|
||||
GUARD_EXC(ret = b->getAnimationFPS(););
|
||||
ret = b->getAnimationFPS();
|
||||
|
||||
return rb_float_new(ret);
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapSetLooping){
|
||||
RB_METHOD_GUARD(bitmapSetLooping){
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
bool loop;
|
||||
|
@ -679,8 +714,9 @@ RB_METHOD(bitmapSetLooping){
|
|||
|
||||
return rb_bool_new(loop);
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapGetLooping){
|
||||
RB_METHOD_GUARD(bitmapGetLooping){
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
rb_check_argc(argc, 0);
|
||||
|
@ -688,12 +724,13 @@ RB_METHOD(bitmapGetLooping){
|
|||
Bitmap *b = getPrivateData<Bitmap>(self);
|
||||
|
||||
bool ret;
|
||||
GUARD_EXC(ret = b->getLooping(););
|
||||
ret = b->getLooping();
|
||||
return rb_bool_new(ret);
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
// Captures the Bitmap's current frame data to a new Bitmap
|
||||
RB_METHOD(bitmapSnapToBitmap) {
|
||||
RB_METHOD_GUARD(bitmapSnapToBitmap) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE position;
|
||||
|
@ -713,6 +750,7 @@ RB_METHOD(bitmapSnapToBitmap) {
|
|||
|
||||
return ret;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(bitmapGetMaxSize){
|
||||
RB_UNUSED_PARAM;
|
||||
|
@ -722,7 +760,7 @@ RB_METHOD(bitmapGetMaxSize){
|
|||
return INT2NUM(Bitmap::maxSize());
|
||||
}
|
||||
|
||||
RB_METHOD(bitmapInitializeCopy) {
|
||||
RB_METHOD_GUARD(bitmapInitializeCopy) {
|
||||
rb_check_argc(argc, 1);
|
||||
VALUE origObj = argv[0];
|
||||
|
||||
|
@ -740,6 +778,7 @@ RB_METHOD(bitmapInitializeCopy) {
|
|||
|
||||
return self;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
void bitmapBindingInit() {
|
||||
VALUE klass = rb_define_class("Bitmap", rb_cObject);
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
} \
|
||||
}
|
||||
|
||||
RB_METHOD(CUSLSetStat) {
|
||||
RB_METHOD_GUARD(CUSLSetStat) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE name, stat;
|
||||
|
@ -47,11 +47,12 @@ RB_METHOD(CUSLSetStat) {
|
|||
STEAMSHIM_setStatI(RSTRING_PTR(name), (int)NUM2INT(stat));
|
||||
STEAMSHIM_GET_OK(SHIMEVENT_SETSTATI, ret);
|
||||
} else {
|
||||
rb_raise(rb_eTypeError,
|
||||
throw Exception(Exception::TypeError,
|
||||
"Statistic value must be either an integer or float.");
|
||||
}
|
||||
return rb_bool_new(ret);
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(CUSLGetStatI) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
|
|
@ -52,6 +52,10 @@ DEF_ALLOCFUNC_CUSTOMFREE(FileInt, fileIntFreeInstance);
|
|||
#endif
|
||||
|
||||
static VALUE fileIntForPath(const char *path, bool rubyExc) {
|
||||
VALUE klass = rb_const_get(rb_cObject, rb_intern("FileInt"));
|
||||
|
||||
VALUE obj = rb_obj_alloc(klass);
|
||||
|
||||
SDL_RWops *ops = SDL_AllocRW();
|
||||
|
||||
try {
|
||||
|
@ -59,16 +63,9 @@ static VALUE fileIntForPath(const char *path, bool rubyExc) {
|
|||
} catch (const Exception &e) {
|
||||
SDL_FreeRW(ops);
|
||||
|
||||
if (rubyExc)
|
||||
raiseRbExc(e);
|
||||
else
|
||||
throw e;
|
||||
throw e;
|
||||
}
|
||||
|
||||
VALUE klass = rb_const_get(rb_cObject, rb_intern("FileInt"));
|
||||
|
||||
VALUE obj = rb_obj_alloc(klass);
|
||||
|
||||
setPrivateData(obj, ops);
|
||||
|
||||
return obj;
|
||||
|
@ -183,7 +180,7 @@ kernelLoadDataInt(const char *filename, bool rubyExc, bool raw) {
|
|||
return result;
|
||||
}
|
||||
|
||||
RB_METHOD(kernelLoadData) {
|
||||
RB_METHOD_GUARD(kernelLoadData) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE filename;
|
||||
|
@ -195,6 +192,7 @@ RB_METHOD(kernelLoadData) {
|
|||
rb_bool_arg(raw, &rawv);
|
||||
return kernelLoadDataInt(RSTRING_PTR(filename), true, rawv);
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(kernelSaveData) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
|
|
@ -74,7 +74,7 @@ RB_METHOD(graphicsFreeze)
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
RB_METHOD(graphicsTransition)
|
||||
RB_METHOD_GUARD(graphicsTransition)
|
||||
{
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
|
@ -88,6 +88,7 @@ RB_METHOD(graphicsTransition)
|
|||
|
||||
return Qnil;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(graphicsFrameReset)
|
||||
{
|
||||
|
@ -228,7 +229,7 @@ RB_METHOD(graphicsFadein)
|
|||
|
||||
void bitmapInitProps(Bitmap *b, VALUE self);
|
||||
|
||||
RB_METHOD(graphicsSnapToBitmap)
|
||||
RB_METHOD_GUARD(graphicsSnapToBitmap)
|
||||
{
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
|
@ -241,6 +242,7 @@ RB_METHOD(graphicsSnapToBitmap)
|
|||
|
||||
return obj;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(graphicsResizeScreen)
|
||||
{
|
||||
|
|
|
@ -87,7 +87,7 @@ void* httpGetInternal(void *req) {
|
|||
}
|
||||
#endif
|
||||
|
||||
RB_METHOD(httpGet) {
|
||||
RB_METHOD_GUARD(httpGet) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE path, rheaders, redirect;
|
||||
|
@ -107,6 +107,7 @@ RB_METHOD(httpGet) {
|
|||
return (VALUE)httpGetInternal(&req);
|
||||
#endif
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
#if RAPI_MAJOR >= 2
|
||||
|
||||
|
@ -130,7 +131,7 @@ void* httpPostInternal(void *args) {
|
|||
}
|
||||
#endif
|
||||
|
||||
RB_METHOD(httpPost) {
|
||||
RB_METHOD_GUARD(httpPost) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE path, postDataHash, rheaders, redirect;
|
||||
|
@ -153,6 +154,7 @@ RB_METHOD(httpPost) {
|
|||
return httpPostInternal(&args);
|
||||
#endif
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
#if RAPI_MAJOR >= 2
|
||||
typedef struct {
|
||||
|
@ -280,13 +282,13 @@ json5pp::value rb2json(VALUE v) {
|
|||
return ret_value;
|
||||
}
|
||||
|
||||
raiseRbExc(Exception(Exception::MKXPError, "Invalid value for JSON: %s", RSTRING_PTR(rb_inspect(v))));
|
||||
throw Exception(Exception::MKXPError, "Invalid value for JSON: %s", RSTRING_PTR(rb_inspect(v)));
|
||||
|
||||
// This should be unreachable
|
||||
return json5pp::value(0);
|
||||
}
|
||||
|
||||
RB_METHOD(httpJsonParse) {
|
||||
RB_METHOD_GUARD(httpJsonParse) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE jsonv;
|
||||
|
@ -298,13 +300,14 @@ RB_METHOD(httpJsonParse) {
|
|||
v = json5pp::parse5(RSTRING_PTR(jsonv));
|
||||
}
|
||||
catch (const std::exception &e) {
|
||||
raiseRbExc(Exception(Exception::MKXPError, "Failed to parse JSON: %s", e.what()));
|
||||
throw Exception(Exception::MKXPError, "Failed to parse JSON: %s", e.what());
|
||||
}
|
||||
|
||||
return json2rb(v);
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(httpJsonStringify) {
|
||||
RB_METHOD_GUARD(httpJsonStringify) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE obj;
|
||||
|
@ -313,6 +316,7 @@ RB_METHOD(httpJsonStringify) {
|
|||
json5pp::value v = rb2json(obj);
|
||||
return rb_utf8_str_new_cstr(v.stringify5(json5pp::rule::space_indent<>()).c_str());
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
void httpBindingInit() {
|
||||
VALUE mNet = rb_define_module("HTTPLite");
|
||||
|
|
|
@ -76,7 +76,7 @@ static int getScancodeArg(VALUE *argv) {
|
|||
try {
|
||||
code = strToScancode[scancode];
|
||||
} catch (...) {
|
||||
rb_raise(rb_eRuntimeError, "%s is not a valid name of an SDL scancode.", scancode);
|
||||
throw Exception(Exception::RuntimeError, "%s is not a valid name of an SDL scancode.", scancode);
|
||||
}
|
||||
|
||||
return code;
|
||||
|
@ -88,7 +88,7 @@ static int getControllerButtonArg(VALUE *argv) {
|
|||
try {
|
||||
btn = strToGCButton[button];
|
||||
} catch (...) {
|
||||
rb_raise(rb_eRuntimeError, "%s is not a valid name of an SDL Controller button.", button);
|
||||
throw Exception(Exception::RuntimeError, "%s is not a valid name of an SDL Controller button.", button);
|
||||
}
|
||||
|
||||
return btn;
|
||||
|
@ -172,7 +172,7 @@ RB_METHOD(inputRepeatTime) {
|
|||
return rb_float_new(shState->input().repeatTime(num));
|
||||
}
|
||||
|
||||
RB_METHOD(inputPressEx) {
|
||||
RB_METHOD_GUARD(inputPressEx) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE button;
|
||||
|
@ -185,8 +185,9 @@ RB_METHOD(inputPressEx) {
|
|||
|
||||
return rb_bool_new(shState->input().isPressedEx(NUM2INT(button), 1));
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(inputTriggerEx) {
|
||||
RB_METHOD_GUARD(inputTriggerEx) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE button;
|
||||
|
@ -199,8 +200,9 @@ RB_METHOD(inputTriggerEx) {
|
|||
|
||||
return rb_bool_new(shState->input().isTriggeredEx(NUM2INT(button), 1));
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(inputRepeatEx) {
|
||||
RB_METHOD_GUARD(inputRepeatEx) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE button;
|
||||
|
@ -213,8 +215,9 @@ RB_METHOD(inputRepeatEx) {
|
|||
|
||||
return rb_bool_new(shState->input().isRepeatedEx(NUM2INT(button), 1));
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(inputReleaseEx) {
|
||||
RB_METHOD_GUARD(inputReleaseEx) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE button;
|
||||
|
@ -227,8 +230,9 @@ RB_METHOD(inputReleaseEx) {
|
|||
|
||||
return rb_bool_new(shState->input().isReleasedEx(NUM2INT(button), 1));
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(inputCountEx) {
|
||||
RB_METHOD_GUARD(inputCountEx) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE button;
|
||||
|
@ -241,8 +245,9 @@ RB_METHOD(inputCountEx) {
|
|||
|
||||
return UINT2NUM(shState->input().repeatcount(NUM2INT(button), 1));
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(inputRepeatTimeEx) {
|
||||
RB_METHOD_GUARD(inputRepeatTimeEx) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE button;
|
||||
|
@ -255,6 +260,7 @@ RB_METHOD(inputRepeatTimeEx) {
|
|||
|
||||
return rb_float_new(shState->input().repeatTimeEx(NUM2INT(button), 1));
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(inputDir4) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
@ -370,7 +376,7 @@ AXISFUNC(Trigger, TRIGGERLEFT, TRIGGERRIGHT);
|
|||
#undef POWERCASE
|
||||
#undef M_SYMBOL
|
||||
|
||||
RB_METHOD(inputControllerPressEx) {
|
||||
RB_METHOD_GUARD(inputControllerPressEx) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE button;
|
||||
|
@ -383,8 +389,9 @@ RB_METHOD(inputControllerPressEx) {
|
|||
|
||||
return rb_bool_new(shState->input().controllerIsPressedEx(NUM2INT(button)));
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(inputControllerTriggerEx) {
|
||||
RB_METHOD_GUARD(inputControllerTriggerEx) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE button;
|
||||
|
@ -397,8 +404,9 @@ RB_METHOD(inputControllerTriggerEx) {
|
|||
|
||||
return rb_bool_new(shState->input().controllerIsTriggeredEx(NUM2INT(button)));
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(inputControllerRepeatEx) {
|
||||
RB_METHOD_GUARD(inputControllerRepeatEx) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE button;
|
||||
|
@ -411,8 +419,9 @@ RB_METHOD(inputControllerRepeatEx) {
|
|||
|
||||
return rb_bool_new(shState->input().controllerIsRepeatedEx(NUM2INT(button)));
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(inputControllerReleaseEx) {
|
||||
RB_METHOD_GUARD(inputControllerReleaseEx) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE button;
|
||||
|
@ -425,8 +434,9 @@ RB_METHOD(inputControllerReleaseEx) {
|
|||
|
||||
return rb_bool_new(shState->input().controllerIsReleasedEx(NUM2INT(button)));
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(inputControllerCountEx) {
|
||||
RB_METHOD_GUARD(inputControllerCountEx) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE button;
|
||||
|
@ -439,8 +449,9 @@ RB_METHOD(inputControllerCountEx) {
|
|||
|
||||
return rb_bool_new(shState->input().controllerRepeatcount(NUM2INT(button)));
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(inputControllerRepeatTimeEx) {
|
||||
RB_METHOD_GUARD(inputControllerRepeatTimeEx) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE button;
|
||||
|
@ -453,6 +464,7 @@ RB_METHOD(inputControllerRepeatTimeEx) {
|
|||
|
||||
return rb_float_new(shState->input().controllerRepeatTimeEx(NUM2INT(button)));
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(inputControllerRawButtonStates) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
@ -504,18 +516,13 @@ RB_METHOD(inputGets) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
RB_METHOD(inputGetClipboard) {
|
||||
RB_METHOD_GUARD(inputGetClipboard) {
|
||||
RB_UNUSED_PARAM;
|
||||
VALUE ret;
|
||||
try {
|
||||
ret = rb_utf8_str_new_cstr(shState->input().getClipboardText());
|
||||
} catch (const Exception &e) {
|
||||
raiseRbExc(e);
|
||||
}
|
||||
return ret;
|
||||
return rb_utf8_str_new_cstr(shState->input().getClipboardText());
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(inputSetClipboard) {
|
||||
RB_METHOD_GUARD(inputSetClipboard) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE str;
|
||||
|
@ -523,13 +530,11 @@ RB_METHOD(inputSetClipboard) {
|
|||
|
||||
SafeStringValue(str);
|
||||
|
||||
try {
|
||||
shState->input().setClipboardText(RSTRING_PTR(str));
|
||||
} catch (const Exception &e) {
|
||||
raiseRbExc(e);
|
||||
}
|
||||
shState->input().setClipboardText(RSTRING_PTR(str));
|
||||
|
||||
return str;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
struct {
|
||||
const char *str;
|
||||
|
|
|
@ -46,7 +46,7 @@ static void *MiniFFI_GetFunctionHandle(void *libhandle, const char *func) {
|
|||
// MiniFFI.new(library, function[, imports[, exports]])
|
||||
// Yields itself in blocks
|
||||
|
||||
RB_METHOD(MiniFFI_initialize) {
|
||||
RB_METHOD_GUARD(MiniFFI_initialize) {
|
||||
VALUE libname, func, imports, exports;
|
||||
rb_scan_args(argc, argv, "22", &libname, &func, &imports, &exports);
|
||||
SafeStringValue(libname);
|
||||
|
@ -66,7 +66,7 @@ RB_METHOD(MiniFFI_initialize) {
|
|||
}
|
||||
#endif
|
||||
if (!hfunc)
|
||||
rb_raise(rb_eRuntimeError, "%s", SDL_GetError());
|
||||
throw Exception(Exception::RuntimeError, "%s", SDL_GetError());
|
||||
|
||||
rb_iv_set(self, "_func", MVAL2RB((mffi_value)hfunc));
|
||||
rb_iv_set(self, "_funcname", func);
|
||||
|
@ -138,7 +138,7 @@ RB_METHOD(MiniFFI_initialize) {
|
|||
}
|
||||
|
||||
if (MINIFFI_MAX_ARGS < RARRAY_LEN(ary_imports))
|
||||
rb_raise(rb_eRuntimeError, "too many parameters: %ld/%ld\n",
|
||||
throw Exception(Exception::RuntimeError, "too many parameters: %ld/%ld\n",
|
||||
RARRAY_LEN(ary_imports), MINIFFI_MAX_ARGS);
|
||||
|
||||
rb_iv_set(self, "_imports", ary_imports);
|
||||
|
@ -181,6 +181,7 @@ RB_METHOD(MiniFFI_initialize) {
|
|||
rb_yield(self);
|
||||
return Qnil;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
#if RAPI_MAJOR >= 2
|
||||
typedef struct {
|
||||
|
@ -195,7 +196,7 @@ void* miniffi_call_cb(void *args) {
|
|||
}
|
||||
#endif
|
||||
|
||||
RB_METHOD(MiniFFI_call) {
|
||||
RB_METHOD_GUARD(MiniFFI_call) {
|
||||
MiniFFIFuncArgs param;
|
||||
#define params param.params
|
||||
VALUE func = rb_iv_get(self, "_func");
|
||||
|
@ -206,7 +207,7 @@ RB_METHOD(MiniFFI_call) {
|
|||
int items = rb_scan_args(argc, argv, "0*", &args);
|
||||
int nimport = RARRAY_LEN(own_imports);
|
||||
if (items != nimport)
|
||||
rb_raise(rb_eRuntimeError,
|
||||
throw Exception(Exception::RuntimeError,
|
||||
"wrong number of parameters: expected %d, got %d", nimport, items);
|
||||
|
||||
for (int i = 0; i < nimport; i++) {
|
||||
|
@ -264,6 +265,7 @@ RB_METHOD(MiniFFI_call) {
|
|||
return MVAL2RB(0);
|
||||
}
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
void MiniFFIBindingInit() {
|
||||
VALUE cMiniFFI = rb_define_class("MiniFFI", rb_cObject);
|
||||
|
|
|
@ -27,20 +27,21 @@
|
|||
#include "graphics.h"
|
||||
|
||||
template<class C>
|
||||
RB_METHOD(sceneElementGetZ)
|
||||
RB_METHOD_GUARD(sceneElementGetZ)
|
||||
{
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
SceneElement *se = getPrivateData<C>(self);
|
||||
|
||||
int value = 0;
|
||||
GUARD_EXC( value = se->getZ(); );
|
||||
value = se->getZ();
|
||||
|
||||
return rb_fix_new(value);
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
template<class C>
|
||||
RB_METHOD(sceneElementSetZ)
|
||||
RB_METHOD_GUARD(sceneElementSetZ)
|
||||
{
|
||||
SceneElement *se = getPrivateData<C>(self);
|
||||
|
||||
|
@ -51,22 +52,24 @@ RB_METHOD(sceneElementSetZ)
|
|||
|
||||
return rb_fix_new(z);
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
template<class C>
|
||||
RB_METHOD(sceneElementGetVisible)
|
||||
RB_METHOD_GUARD(sceneElementGetVisible)
|
||||
{
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
SceneElement *se = getPrivateData<C>(self);
|
||||
|
||||
bool value = false;
|
||||
GUARD_EXC( value = se->getVisible(); );
|
||||
value = se->getVisible();
|
||||
|
||||
return rb_bool_new(value);
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
template<class C>
|
||||
RB_METHOD(sceneElementSetVisible)
|
||||
RB_METHOD_GUARD(sceneElementSetVisible)
|
||||
{
|
||||
SceneElement *se = getPrivateData<C>(self);
|
||||
|
||||
|
@ -75,8 +78,9 @@ RB_METHOD(sceneElementSetVisible)
|
|||
|
||||
GFX_GUARD_EXC( se->setVisible(visible); );
|
||||
|
||||
return rb_bool_new(visible);
|
||||
return rb_bool_new(visible);
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
template<class C>
|
||||
void
|
||||
|
|
|
@ -36,7 +36,18 @@ serializableDump(int, VALUE *, VALUE self)
|
|||
|
||||
VALUE data = rb_str_new(0, dataSize);
|
||||
|
||||
GUARD_EXC( s->serialize(RSTRING_PTR(data)); );
|
||||
Exception *exc = 0;
|
||||
try{
|
||||
s->serialize(RSTRING_PTR(data));
|
||||
} catch (const Exception &e) {
|
||||
exc = new Exception(e);
|
||||
}
|
||||
|
||||
if (exc) {
|
||||
Exception e(exc->type, exc->msg);
|
||||
delete exc;
|
||||
rb_raise(excToRbClass(e), "%s", e.msg);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
|
|
@ -84,27 +84,29 @@ DEF_GFX_PROP_B(Sprite, Mirror)
|
|||
DEF_GFX_PROP_B(Sprite, PatternTile)
|
||||
DEF_GFX_PROP_B(Sprite, Invert)
|
||||
|
||||
RB_METHOD(spriteWidth) {
|
||||
RB_METHOD_GUARD(spriteWidth) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
Sprite *s = getPrivateData<Sprite>(self);
|
||||
|
||||
int value = 0;
|
||||
GUARD_EXC(value = s->getWidth();)
|
||||
value = s->getWidth();
|
||||
|
||||
return rb_fix_new(value);
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(spriteHeight) {
|
||||
RB_METHOD_GUARD(spriteHeight) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
Sprite *s = getPrivateData<Sprite>(self);
|
||||
|
||||
int value = 0;
|
||||
GUARD_EXC(value = s->getHeight();)
|
||||
value = s->getHeight();
|
||||
|
||||
return rb_fix_new(value);
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
void spriteBindingInit() {
|
||||
VALUE klass = rb_define_class("Sprite", rb_cObject);
|
||||
|
|
|
@ -86,7 +86,7 @@ TABLE_SIZE(x, X)
|
|||
TABLE_SIZE(y, Y)
|
||||
TABLE_SIZE(z, Z)
|
||||
|
||||
RB_METHOD(tableGetAt) {
|
||||
RB_METHOD_GUARD(tableGetAt) {
|
||||
Table *t = getPrivateData<Table>(self);
|
||||
|
||||
int x, y, z;
|
||||
|
@ -99,7 +99,7 @@ RB_METHOD(tableGetAt) {
|
|||
z = NUM2INT(argv[2]);
|
||||
|
||||
if (argc > 3)
|
||||
rb_raise(rb_eArgError, "wrong number of arguments");
|
||||
throw Exception(Exception::ArgumentError, "wrong number of arguments");
|
||||
|
||||
if (x < 0 || x >= t->xSize() || y < 0 || y >= t->ySize() || z < 0 ||
|
||||
z >= t->zSize()) {
|
||||
|
@ -110,15 +110,16 @@ RB_METHOD(tableGetAt) {
|
|||
|
||||
return INT2FIX(result); /* short always fits in a Fixnum */
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
RB_METHOD(tableSetAt) {
|
||||
RB_METHOD_GUARD(tableSetAt) {
|
||||
Table *t = getPrivateData<Table>(self);
|
||||
|
||||
int x, y, z, value;
|
||||
x = y = z = 0;
|
||||
|
||||
if (argc < 2)
|
||||
rb_raise(rb_eArgError, "wrong number of arguments");
|
||||
throw Exception(Exception::ArgumentError, "wrong number of arguments");
|
||||
|
||||
switch (argc) {
|
||||
default:
|
||||
|
@ -146,6 +147,7 @@ RB_METHOD(tableSetAt) {
|
|||
|
||||
return argv[argc - 1];
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
MARSH_LOAD_FUN(Table)
|
||||
INITCOPY_FUN(Table)
|
||||
|
|
|
@ -42,7 +42,7 @@ RB_METHOD(viewportElementGetViewport)
|
|||
}
|
||||
|
||||
template<class C>
|
||||
RB_METHOD(viewportElementSetViewport)
|
||||
RB_METHOD_GUARD(viewportElementSetViewport)
|
||||
{
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
|
@ -62,6 +62,7 @@ RB_METHOD(viewportElementSetViewport)
|
|||
|
||||
return viewportObj;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
template<class C>
|
||||
static C *
|
||||
|
|
|
@ -44,7 +44,7 @@ RB_METHOD(windowInitialize) {
|
|||
return self;
|
||||
}
|
||||
|
||||
RB_METHOD(windowUpdate) {
|
||||
RB_METHOD_GUARD(windowUpdate) {
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
Window *w = getPrivateData<Window>(self);
|
||||
|
@ -53,6 +53,7 @@ RB_METHOD(windowUpdate) {
|
|||
|
||||
return Qnil;
|
||||
}
|
||||
RB_METHOD_GUARD_END
|
||||
|
||||
DEF_GFX_PROP_OBJ_REF(Window, Bitmap, Windowskin, "windowskin")
|
||||
DEF_GFX_PROP_OBJ_REF(Window, Bitmap, Contents, "contents")
|
||||
|
|
|
@ -37,6 +37,8 @@ struct Exception
|
|||
/* Already defined by ruby */
|
||||
TypeError,
|
||||
ArgumentError,
|
||||
SystemExit,
|
||||
RuntimeError,
|
||||
|
||||
/* New types introduced in mkxp */
|
||||
PHYSFSError,
|
||||
|
@ -45,7 +47,7 @@ struct Exception
|
|||
};
|
||||
|
||||
Type type;
|
||||
std::string msg;
|
||||
char msg[512];
|
||||
|
||||
Exception(Type type, const char *format, ...)
|
||||
: type(type)
|
||||
|
@ -53,8 +55,7 @@ struct Exception
|
|||
va_list ap;
|
||||
va_start(ap, format);
|
||||
|
||||
msg.resize(512);
|
||||
vsnprintf(&msg[0], msg.size(), format, ap);
|
||||
vsnprintf(msg, sizeof(msg), format, ap);
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue