Core/MRI: Fix handling of Etc/Font properties

The gist of it is that for Etc and Font props, the assignment
operator (eg. 'sprite.color=') does not take a reference of the
right hand parameter and replaces its previous one with it (this
was the old behavior). Rather, it keeps its internal property
object and copies the parameter object into it by value.
The getter is unchanged; it still returns a reference to the
internal property object.

s = Sprite.new
c = Color.new
s.color = c
p s.color == c # => true
p s.color.object_id == c.object_id # => false (true before)
c = s.color
p s.color.object_id == c.object_id # => true
This commit is contained in:
Jonas Kulla 2014-09-05 01:26:03 +02:00
parent f665d8b41c
commit f8c26fc515
28 changed files with 337 additions and 243 deletions

View file

@ -316,30 +316,11 @@ rb_check_argc(int actual, int expected)
return self; \
}
#define DEF_PROP_OBJ(Klass, PropKlass, PropName, prop_iv) \
RB_METHOD(Klass##Get##PropName) \
{ \
RB_UNUSED_PARAM; \
checkDisposed(self); \
return rb_iv_get(self, prop_iv); \
} \
RB_METHOD(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); ) \
rb_iv_set(self, prop_iv, propObj); \
return propObj; \
}
/* Object property with allowed NIL
/* Object property which is copied by reference, with allowed NIL
* FIXME: Getter assumes prop is disposable,
* because self.disposed? is not checked in this case.
* Should make this more clear */
#define DEF_PROP_OBJ_NIL(Klass, PropKlass, PropName, prop_iv) \
#define DEF_PROP_OBJ_REF(Klass, PropKlass, PropName, prop_iv) \
RB_METHOD(Klass##Get##PropName) \
{ \
RB_UNUSED_PARAM; \
@ -361,6 +342,25 @@ rb_check_argc(int actual, int expected)
return propObj; \
}
/* Object property which is copied by value, not reference */
#define DEF_PROP_OBJ_VAL(Klass, PropKlass, PropName, prop_iv) \
RB_METHOD(Klass##Get##PropName) \
{ \
RB_UNUSED_PARAM; \
checkDisposed(self); \
return rb_iv_get(self, prop_iv); \
} \
RB_METHOD(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); ) \
return propObj; \
}
#define DEF_PROP(Klass, type, PropName, arg_fun, value_fun) \
RB_METHOD(Klass##Get##PropName) \
{ \

View file

@ -43,7 +43,7 @@ void bitmapInitProps(Bitmap *b, VALUE self)
rb_obj_call_init(fontObj, 0, 0);
Font *font = getPrivateData<Font>(fontObj);
b->setFont(font);
b->setInitFont(font);
rb_iv_set(self, "font", fontObj);
}
@ -323,7 +323,7 @@ RB_METHOD(bitmapTextSize)
return wrapObject(rect, RectType);
}
DEF_PROP_OBJ(Bitmap, Font, Font, "font")
DEF_PROP_OBJ_VAL(Bitmap, Font, Font, "font")
RB_METHOD(bitmapGradientFillRect)
{
@ -413,12 +413,25 @@ RB_METHOD(bitmapRadialBlur)
return Qnil;
}
// FIXME: This isn't entire correct as the cloned bitmap
// does not get a cloned version of the original bitmap's 'font'
// attribute (the internal font attrb is the default one, whereas
// the stored iv visible to ruby would still be the same as the original)
// Not sure if this needs fixing though
INITCOPY_FUN(Bitmap)
RB_METHOD(bitmapInitializeCopy)
{
rb_check_argc(argc, 1);
VALUE origObj = argv[0];
if (!OBJ_INIT_COPY(self, origObj))
return self;
Bitmap *orig = getPrivateData<Bitmap>(origObj);
Bitmap *b = 0;
GUARD_EXC( b = new Bitmap(*orig); );
bitmapInitProps(b, self);
b->setFont(orig->getFont());
setPrivateData(self, b);
return self;
}
void
@ -430,7 +443,7 @@ bitmapBindingInit()
disposableBindingInit<Bitmap>(klass);
_rb_define_method(klass, "initialize", bitmapInitialize);
_rb_define_method(klass, "initialize_copy", BitmapInitializeCopy);
_rb_define_method(klass, "initialize_copy", bitmapInitializeCopy);
_rb_define_method(klass, "width", bitmapWidth);
_rb_define_method(klass, "height", bitmapHeight);

View file

@ -110,7 +110,7 @@ INIT_FUN(Rect, int, "iiii", 0)
{ \
VALUE otherObj = argv[0]; \
Klass *other = getPrivateDataCheck<Klass>(otherObj, Klass##Type); \
k->set(*other); \
*k = *other; \
} \
else \
{ \

View file

@ -58,14 +58,12 @@ RB_METHOD(fontInitialize)
setPrivateData(self, f);
/* Wrap property objects */
f->setColor(new Color(*f->getColor()));
f->initDynAttribs();
wrapProperty(self, f->getColor(), "color", ColorType);
if (rgssVer >= 3)
{
f->setOutColor(new Color(*f->getOutColor()));
wrapProperty(self, f->getOutColor(), "out_color", ColorType);
}
wrapProperty(self, f->getOutColor(), "out_color", ColorType);
if (NIL_P(name))
name = rb_iv_get(rb_obj_class(self), "default_name");
@ -90,14 +88,12 @@ RB_METHOD(fontInitializeCopy)
setPrivateData(self, f);
/* Wrap property objects */
f->setColor(new Color(*f->getColor()));
f->initDynAttribs();
wrapProperty(self, f->getColor(), "color", ColorType);
if (rgssVer >= 3)
{
f->setOutColor(new Color(*f->getOutColor()));
wrapProperty(self, f->getOutColor(), "out_color", ColorType);
}
wrapProperty(self, f->getOutColor(), "out_color", ColorType);
return self;
}
@ -164,13 +160,15 @@ RB_METHOD(FontSetName)
return argv[0];
}
DEF_PROP_OBJ_VAL(Font, Color, Color, "color")
DEF_PROP_OBJ_VAL(Font, Color, OutColor, "out_color")
DEF_PROP_I(Font, Size)
DEF_PROP_B(Font, Bold)
DEF_PROP_B(Font, Italic)
DEF_PROP_B(Font, Shadow)
DEF_PROP_B(Font, Outline)
DEF_PROP_OBJ(Font, Color, Color, "color")
DEF_PROP_OBJ(Font, Color, OutColor, "out_color")
#define DEF_KLASS_PROP(Klass, type, PropName, param_t_s, value_fun) \
RB_METHOD(Klass##Get##PropName) \
@ -187,10 +185,10 @@ DEF_PROP_OBJ(Font, Color, OutColor, "out_color")
return value_fun(value); \
}
DEF_KLASS_PROP(Font, int, DefaultSize, "i", rb_fix_new)
DEF_KLASS_PROP(Font, bool, DefaultBold, "b", rb_bool_new)
DEF_KLASS_PROP(Font, bool, DefaultItalic, "b", rb_bool_new)
DEF_KLASS_PROP(Font, bool, DefaultShadow, "b", rb_bool_new)
DEF_KLASS_PROP(Font, int, DefaultSize, "i", rb_fix_new)
DEF_KLASS_PROP(Font, bool, DefaultBold, "b", rb_bool_new)
DEF_KLASS_PROP(Font, bool, DefaultItalic, "b", rb_bool_new)
DEF_KLASS_PROP(Font, bool, DefaultShadow, "b", rb_bool_new)
DEF_KLASS_PROP(Font, bool, DefaultOutline, "b", rb_bool_new)
RB_METHOD(FontGetDefaultOutColor)
@ -201,13 +199,14 @@ RB_METHOD(FontGetDefaultOutColor)
RB_METHOD(FontSetDefaultOutColor)
{
RB_UNUSED_PARAM;
VALUE colorObj;
rb_get_args(argc, argv, "o", &colorObj RB_ARG_END);
Color *c = getPrivateDataCheck<Color>(colorObj, ColorType);
Font::setDefaultOutColor(c);
rb_iv_set(self, "default_out_color", colorObj);
return colorObj;
}
@ -239,13 +238,14 @@ RB_METHOD(FontGetDefaultColor)
RB_METHOD(FontSetDefaultColor)
{
RB_UNUSED_PARAM;
VALUE colorObj;
rb_get_args(argc, argv, "o", &colorObj RB_ARG_END);
Color *c = getPrivateDataCheck<Color>(colorObj, ColorType);
Font::setDefaultColor(c);
rb_iv_set(self, "default_color", colorObj);
return colorObj;
}
@ -262,10 +262,13 @@ fontBindingInit()
VALUE klass = rb_define_class("Font", rb_cObject);
rb_define_alloc_func(klass, classAllocate<&FontType>);
Font::setDefaultColor(new Color(*Font::getDefaultColor()));
Font::initDefaultDynAttribs();
wrapProperty(klass, Font::getDefaultColor(), "default_color", ColorType);
rb_iv_set(klass, "default_name", rb_str_new_cstr(Font::getDefaultName()));
if (rgssVer >= 3)
wrapProperty(klass, Font::getDefaultOutColor(), "default_out_color", ColorType);
INIT_KLASS_PROP_BIND(Font, DefaultName, "default_name");
INIT_KLASS_PROP_BIND(Font, DefaultSize, "default_size");
INIT_KLASS_PROP_BIND(Font, DefaultBold, "default_bold");

View file

@ -33,8 +33,7 @@ RB_METHOD(planeInitialize)
setPrivateData(self, p);
p->setColor(new Color);
p->setTone(new Tone);
p->initDynAttribs();
wrapNilProperty(self, "bitmap");
wrapProperty(self, p->getColor(), "color", ColorType);
@ -43,9 +42,9 @@ RB_METHOD(planeInitialize)
return self;
}
DEF_PROP_OBJ_NIL(Plane, Bitmap, Bitmap, "bitmap")
DEF_PROP_OBJ(Plane, Color, Color, "color")
DEF_PROP_OBJ(Plane, Tone, Tone, "tone")
DEF_PROP_OBJ_REF(Plane, Bitmap, Bitmap, "bitmap")
DEF_PROP_OBJ_VAL(Plane, Color, Color, "color")
DEF_PROP_OBJ_VAL(Plane, Tone, Tone, "tone")
DEF_PROP_I(Plane, OX)
DEF_PROP_I(Plane, OY)

View file

@ -37,9 +37,7 @@ RB_METHOD(spriteInitialize)
setPrivateData(self, s);
/* Wrap property objects */
s->setSrcRect(new Rect);
s->setColor(new Color);
s->setTone(new Tone);
s->initDynAttribs();
wrapNilProperty(self, "bitmap");
wrapProperty(self, s->getSrcRect(), "src_rect", RectType);
@ -49,10 +47,10 @@ RB_METHOD(spriteInitialize)
return self;
}
DEF_PROP_OBJ_NIL(Sprite, Bitmap, Bitmap, "bitmap")
DEF_PROP_OBJ(Sprite, Rect, SrcRect, "src_rect")
DEF_PROP_OBJ(Sprite, Color, Color, "color")
DEF_PROP_OBJ(Sprite, Tone, Tone, "tone")
DEF_PROP_OBJ_REF(Sprite, Bitmap, Bitmap, "bitmap")
DEF_PROP_OBJ_VAL(Sprite, Rect, SrcRect, "src_rect")
DEF_PROP_OBJ_VAL(Sprite, Color, Color, "color")
DEF_PROP_OBJ_VAL(Sprite, Tone, Tone, "tone")
DEF_PROP_I(Sprite, X)
DEF_PROP_I(Sprite, Y)

View file

@ -124,10 +124,10 @@ RB_METHOD(tilemapGetViewport)
return rb_iv_get(self, "viewport");
}
DEF_PROP_OBJ(Tilemap, Bitmap, Tileset, "tileset")
DEF_PROP_OBJ(Tilemap, Table, MapData, "map_data")
DEF_PROP_OBJ(Tilemap, Table, FlashData, "flash_data")
DEF_PROP_OBJ(Tilemap, Table, Priorities, "priorities")
DEF_PROP_OBJ_REF(Tilemap, Bitmap, Tileset, "tileset")
DEF_PROP_OBJ_REF(Tilemap, Table, MapData, "map_data")
DEF_PROP_OBJ_REF(Tilemap, Table, FlashData, "flash_data")
DEF_PROP_OBJ_REF(Tilemap, Table, Priorities, "priorities")
DEF_PROP_B(Tilemap, Visible)

View file

@ -85,11 +85,10 @@ RB_METHOD(tilemapVXUpdate)
return Qnil;
}
DEF_PROP_OBJ_NIL(TilemapVX, Viewport, Viewport, "viewport")
DEF_PROP_OBJ(TilemapVX, Table, MapData, "map_data")
DEF_PROP_OBJ(TilemapVX, Table, FlashData, "flash_data")
DEF_PROP_OBJ(TilemapVX, Table, Flags, "flags")
DEF_PROP_OBJ_REF(TilemapVX, Viewport, Viewport, "viewport")
DEF_PROP_OBJ_REF(TilemapVX, Table, MapData, "map_data")
DEF_PROP_OBJ_REF(TilemapVX, Table, FlashData, "flash_data")
DEF_PROP_OBJ_REF(TilemapVX, Table, Flags, "flags")
DEF_PROP_B(TilemapVX, Visible)

View file

@ -62,9 +62,7 @@ RB_METHOD(viewportInitialize)
setPrivateData(self, v);
/* Wrap property objects */
v->setRect(new Rect(*v->getRect()));
v->setColor(new Color);
v->setTone(new Tone);
v->initDynAttribs();
wrapProperty(self, v->getRect(), "rect", RectType);
wrapProperty(self, v->getColor(), "color", ColorType);
@ -78,9 +76,9 @@ RB_METHOD(viewportInitialize)
return self;
}
DEF_PROP_OBJ(Viewport, Rect, Rect, "rect")
DEF_PROP_OBJ(Viewport, Color, Color, "color")
DEF_PROP_OBJ(Viewport, Tone, Tone, "tone")
DEF_PROP_OBJ_VAL(Viewport, Rect, Rect, "rect")
DEF_PROP_OBJ_VAL(Viewport, Color, Color, "color")
DEF_PROP_OBJ_VAL(Viewport, Tone, Tone, "tone")
DEF_PROP_I(Viewport, OX)
DEF_PROP_I(Viewport, OY)

View file

@ -32,7 +32,8 @@ RB_METHOD(windowInitialize)
setPrivateData(self, w);
w->setCursorRect(new Rect);
w->initDynAttribs();
wrapNilProperty(self, "windowskin");
wrapNilProperty(self, "contents");
wrapProperty(self, w->getCursorRect(), "cursor_rect", RectType);
@ -51,9 +52,9 @@ RB_METHOD(windowUpdate)
return Qnil;
}
DEF_PROP_OBJ_NIL(Window, Bitmap, Windowskin, "windowskin")
DEF_PROP_OBJ_NIL(Window, Bitmap, Contents, "contents")
DEF_PROP_OBJ(Window, Rect, CursorRect, "cursor_rect")
DEF_PROP_OBJ_REF(Window, Bitmap, Windowskin, "windowskin")
DEF_PROP_OBJ_REF(Window, Bitmap, Contents, "contents")
DEF_PROP_OBJ_VAL(Window, Rect, CursorRect, "cursor_rect")
DEF_PROP_B(Window, Stretch)
DEF_PROP_B(Window, Active)

View file

@ -51,8 +51,8 @@ RB_METHOD(windowVXInitialize)
setPrivateData(self, w);
w->setCursorRect(new Rect);
w->setTone(new Tone);
w->initDynAttribs();
wrapNilProperty(self, "windowskin");
wrapProperty(self, w->getTone(), "tone", ToneType);
wrapProperty(self, w->getCursorRect(), "cursor_rect", RectType);
@ -109,11 +109,11 @@ RB_METHOD(windowVXIsClosed)
return rb_bool_new(w->isClosed());
}
DEF_PROP_OBJ_NIL(WindowVX, Bitmap, Windowskin, "windowskin")
DEF_PROP_OBJ_NIL(WindowVX, Bitmap, Contents, "contents")
DEF_PROP_OBJ_REF(WindowVX, Bitmap, Windowskin, "windowskin")
DEF_PROP_OBJ_REF(WindowVX, Bitmap, Contents, "contents")
DEF_PROP_OBJ(WindowVX, Rect, CursorRect, "cursor_rect")
DEF_PROP_OBJ(WindowVX, Tone, Tone, "tone")
DEF_PROP_OBJ_VAL(WindowVX, Rect, CursorRect, "cursor_rect")
DEF_PROP_OBJ_VAL(WindowVX, Tone, Tone, "tone")
DEF_PROP_I(WindowVX, X)
DEF_PROP_I(WindowVX, Y)