MRI-Binding: Reduce number of object allocations

Previously, wrapped instances of mkxp core classes were
stored as RData ivars inside the actual object. This turned
out to be pointless as RData objects themselves are perfectly
valid objects that can carry ivars and have parent classes.
Therefore, the RData objects are now exposed directly to
the user scripts, effectively halving the amount of object
allocations.
This commit is contained in:
Jonas Kulla 2013-10-30 10:06:24 +01:00
parent 8dd6b63fc4
commit f067e0eff8
11 changed files with 37 additions and 25 deletions

View File

@ -24,8 +24,6 @@
#include "./ruby/ruby.h"
#define PRIV_IV "priv"
enum RbException
{
RGSS = 0,
@ -68,6 +66,12 @@ void initType(rb_data_type_struct &type,
const char *name,
void (*freeInst)(void*));
template<rb_data_type_t *rbType>
static VALUE classAllocate(VALUE klass)
{
return rb_data_typed_object_alloc(klass, 0, rbType);
}
template<class C>
static void freeInstance(void *inst)
{
@ -80,24 +84,21 @@ template<class C>
static inline C *
getPrivateData(VALUE self)
{
VALUE priv = rb_iv_get(self, PRIV_IV);
return static_cast<C*>(RTYPEDDATA_DATA(priv));
return static_cast<C*>(RTYPEDDATA_DATA(self));
}
template<class C>
static inline C *
getPrivateDataCheck(VALUE self, const rb_data_type_struct &type)
{
VALUE priv = rb_iv_get(self, PRIV_IV);
void *obj = rb_check_typeddata(priv, &type);
void *obj = rb_check_typeddata(self, &type);
return static_cast<C*>(obj);
}
static inline void
setPrivateData(VALUE self, void *p, const rb_data_type_struct &type)
setPrivateData(VALUE self, void *p)
{
VALUE priv = rb_data_typed_object_alloc(rb_cData, p, &type);
rb_iv_set(self, PRIV_IV, priv);
RTYPEDDATA_DATA(self) = p;
}
inline VALUE
@ -106,7 +107,7 @@ wrapObject(void *p, const rb_data_type_struct &type)
VALUE klass = rb_const_get(rb_cObject, rb_intern(type.wrap_struct_name));
VALUE obj = rb_obj_alloc(klass);
setPrivateData(obj, p, type);
setPrivateData(obj, p);
return obj;
}
@ -160,7 +161,7 @@ _rb_define_module_function(VALUE module, const char *name, RubyMethod func)
template<class C>
static inline VALUE
objectLoad(int argc, VALUE *argv, VALUE self, rb_data_type_struct &type)
objectLoad(int argc, VALUE *argv, VALUE self)
{
const char *data;
int dataLen;
@ -172,7 +173,7 @@ objectLoad(int argc, VALUE *argv, VALUE self, rb_data_type_struct &type)
GUARD_EXC( c = C::deserialize(data, dataLen); );
setPrivateData(obj, c, type);
setPrivateData(obj, c);
return obj;
}
@ -192,7 +193,7 @@ rb_bool_new(bool value)
#define MARSH_LOAD_FUN(Typ) \
RB_METHOD(Typ##Load) \
{ \
return objectLoad<Typ>(argc, argv, self, Typ##Type); \
return objectLoad<Typ>(argc, argv, self); \
}
#define CLONE_FUNC(Klass) \
@ -213,7 +214,7 @@ rb_bool_new(bool value)
Klass *k = getPrivateData<Klass>(self); \
VALUE dupObj = rb_obj_clone(self); \
Klass *dupK = new Klass(*k); \
setPrivateData(dupObj, dupK, Klass##Type); \
setPrivateData(dupObj, dupK); \
return dupObj; \
}

View File

@ -51,7 +51,7 @@ RB_METHOD(bitmapInitialize)
GUARD_EXC( b = new Bitmap(width, height); )
}
setPrivateData(self, b, BitmapType);
setPrivateData(self, b);
/* Wrap properties */
Font *font = new Font();
@ -300,6 +300,7 @@ bitmapBindingInit()
INIT_TYPE(Bitmap);
VALUE klass = rb_define_class("Bitmap", rb_cObject);
rb_define_alloc_func(klass, classAllocate<&BitmapType>);
disposableBindingInit<Bitmap>(klass);

View File

@ -84,7 +84,7 @@ EQUAL_FUN(Rect)
param_type p1, p2, p3, p4 = last_param_def; \
rb_get_args(argc, argv, param_t_s, &p1, &p2, &p3, &p4, RB_ARG_END); \
Klass *k = new Klass(p1, p2, p3, p4); \
setPrivateData(self, k, Klass##Type); \
setPrivateData(self, k); \
return self; \
}
@ -156,6 +156,7 @@ CLONE_FUN(Rect)
{ \
INIT_TYPE(Klass); \
klass = rb_define_class(#Klass, rb_cObject); \
rb_define_alloc_func(klass, classAllocate<&Klass##Type>); \
rb_define_class_method(klass, "_load", Klass##Load); \
serializableBindingInit<Klass>(klass); \
_rb_define_method(klass, "initialize", Klass##Initialize); \

View File

@ -41,7 +41,7 @@ fileIntForPath(const char *path)
VALUE obj = rb_obj_alloc(klass);
setPrivateData(obj, ops, FileIntType);
setPrivateData(obj, ops);
return obj;
}
@ -198,6 +198,7 @@ fileIntBindingInit()
initType(FileIntType, "FileInt", fileIntFreeInstance);
VALUE klass = rb_define_class("FileInt", rb_cIO);
rb_define_alloc_func(klass, classAllocate<&FileIntType>);
_rb_define_method(klass, "read", fileIntRead);
_rb_define_method(klass, "getbyte", fileIntGetByte);

View File

@ -45,7 +45,7 @@ RB_METHOD(fontInitialize)
Font *f = new Font(name, size);
setPrivateData(self, f, FontType);
setPrivateData(self, f);
/* Wrap property objects */
f->setColor(new Color(*f->getColor()));
@ -151,6 +151,7 @@ fontBindingInit()
INIT_TYPE(Font);
VALUE klass = rb_define_class("Font", rb_cObject);
rb_define_alloc_func(klass, classAllocate<&FontType>);
Font::setDefaultColor(new Color(*Font::getDefaultColor()));
wrapProperty(klass, Font::getDefaultColor(), "default_color", ColorType);

View File

@ -31,7 +31,7 @@ RB_METHOD(planeInitialize)
{
Plane *p = viewportElementInitialize<Plane>(argc, argv, self);
setPrivateData(self, p, PlaneType);
setPrivateData(self, p);
p->setColor(new Color);
p->setTone(new Tone);
@ -64,6 +64,7 @@ planeBindingInit()
INIT_TYPE(Plane);
VALUE klass = rb_define_class("Plane", rb_cObject);
rb_define_alloc_func(klass, classAllocate<&PlaneType>);
disposableBindingInit<Plane> (klass);
viewportElementBindingInit<Plane>(klass);

View File

@ -33,7 +33,7 @@ RB_METHOD(spriteInitialize)
{
Sprite *s = viewportElementInitialize<Sprite>(argc, argv, self);
setPrivateData(self, s, SpriteType);
setPrivateData(self, s);
/* Wrap property objects */
s->setSrcRect(new Rect);
@ -75,6 +75,7 @@ spriteBindingInit()
INIT_TYPE(Sprite);
VALUE klass = rb_define_class("Sprite", rb_cObject);
rb_define_alloc_func(klass, classAllocate<&SpriteType>);
disposableBindingInit <Sprite>(klass);
flashableBindingInit <Sprite>(klass);

View File

@ -34,7 +34,7 @@ RB_METHOD(tableInitialize)
Table *t = new Table(x, y, z);
setPrivateData(self, t, TableType);
setPrivateData(self, t);
return self;
}
@ -146,6 +146,7 @@ tableBindingInit()
INIT_TYPE(Table);
VALUE klass = rb_define_class("Table", rb_cObject);
rb_define_alloc_func(klass, classAllocate<&TableType>);
serializableBindingInit<Table>(klass);

View File

@ -28,7 +28,7 @@
#include "binding-util.h"
#include "binding-types.h"
static rb_data_type_struct TilemapAutotilesType;
rb_data_type_struct TilemapAutotilesType;
RB_METHOD(tilemapAutotilesSet)
{
@ -80,7 +80,7 @@ RB_METHOD(tilemapInitialize)
/* Construct object */
t = new Tilemap(viewport);
setPrivateData(self, t, TilemapType);
setPrivateData(self, t);
rb_iv_set(self, "viewport", viewportObj);
@ -144,6 +144,7 @@ tilemapBindingInit()
initType(TilemapAutotilesType, "TilemapAutotiles", 0);
VALUE klass = rb_define_class("TilemapAutotiles", rb_cObject);
rb_define_alloc_func(klass, classAllocate<&TilemapAutotilesType>);
_rb_define_method(klass, "[]=", tilemapAutotilesSet);
_rb_define_method(klass, "[]", tilemapAutotilesGet);
@ -151,6 +152,7 @@ tilemapBindingInit()
INIT_TYPE(Tilemap);
klass = rb_define_class("Tilemap", rb_cObject);
rb_define_alloc_func(klass, classAllocate<&TilemapType>);
disposableBindingInit<Tilemap>(klass);

View File

@ -54,7 +54,7 @@ RB_METHOD(viewportInitialize)
v = new Viewport(x, y, width, height);
}
setPrivateData(self, v, ViewportType);
setPrivateData(self, v);
/* Wrap property objects */
v->setRect(new Rect(*v->getRect()));
@ -84,6 +84,7 @@ viewportBindingInit()
INIT_TYPE(Viewport);
VALUE klass = rb_define_class("Viewport", rb_cObject);
rb_define_alloc_func(klass, classAllocate<&ViewportType>);
disposableBindingInit <Viewport>(klass);
flashableBindingInit <Viewport>(klass);

View File

@ -30,7 +30,7 @@ RB_METHOD(windowInitialize)
{
Window *w = viewportElementInitialize<Window>(argc, argv, self);
setPrivateData(self, w, WindowType);
setPrivateData(self, w);
w->setCursorRect(new Rect);
wrapNilProperty(self, "windowskin");
@ -78,6 +78,7 @@ windowBindingInit()
INIT_TYPE(Window);
VALUE klass = rb_define_class("Window", rb_cObject);
rb_define_alloc_func(klass, classAllocate<&WindowType>);
disposableBindingInit <Window>(klass);
viewportElementBindingInit<Window>(klass);