From f8c26fc515cb4fb6b24b766889d4b0b0a3c12a26 Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Fri, 5 Sep 2014 01:26:03 +0200 Subject: [PATCH] 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 --- binding-mri/binding-util.h | 42 ++++++------ binding-mri/bitmap-binding.cpp | 31 ++++++--- binding-mri/etc-binding.cpp | 2 +- binding-mri/font-binding.cpp | 41 ++++++------ binding-mri/plane-binding.cpp | 9 ++- binding-mri/sprite-binding.cpp | 12 ++-- binding-mri/tilemap-binding.cpp | 8 +-- binding-mri/tilemapvx-binding.cpp | 9 ++- binding-mri/viewport-binding.cpp | 10 ++- binding-mri/window-binding.cpp | 9 +-- binding-mri/windowvx-binding.cpp | 12 ++-- src/bitmap.cpp | 12 +++- src/bitmap.h | 4 ++ src/etc.cpp | 104 ++++++++++++++++-------------- src/etc.h | 64 +++++++++--------- src/font.cpp | 77 ++++++++++++++++------ src/font.h | 8 +++ src/plane.cpp | 11 +++- src/plane.h | 2 + src/sprite.cpp | 32 +++++---- src/sprite.h | 2 + src/util.h | 14 ++++ src/viewport.cpp | 15 ++--- src/viewport.h | 2 + src/window.cpp | 21 +++--- src/window.h | 2 + src/windowvx.cpp | 23 ++----- src/windowvx.h | 2 + 28 files changed, 337 insertions(+), 243 deletions(-) diff --git a/binding-mri/binding-util.h b/binding-mri/binding-util.h index 703d525..c3f54e3 100644 --- a/binding-mri/binding-util.h +++ b/binding-mri/binding-util.h @@ -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(self); \ - VALUE propObj = *argv; \ - PropKlass *prop; \ - prop = getPrivateDataCheck(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(self); \ + VALUE propObj = *argv; \ + PropKlass *prop; \ + prop = getPrivateDataCheck(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) \ { \ diff --git a/binding-mri/bitmap-binding.cpp b/binding-mri/bitmap-binding.cpp index a49d3e5..b2448d6 100644 --- a/binding-mri/bitmap-binding.cpp +++ b/binding-mri/bitmap-binding.cpp @@ -43,7 +43,7 @@ void bitmapInitProps(Bitmap *b, VALUE self) rb_obj_call_init(fontObj, 0, 0); Font *font = getPrivateData(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(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(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); diff --git a/binding-mri/etc-binding.cpp b/binding-mri/etc-binding.cpp index 6b848ca..2c2cdd2 100644 --- a/binding-mri/etc-binding.cpp +++ b/binding-mri/etc-binding.cpp @@ -110,7 +110,7 @@ INIT_FUN(Rect, int, "iiii", 0) { \ VALUE otherObj = argv[0]; \ Klass *other = getPrivateDataCheck(otherObj, Klass##Type); \ - k->set(*other); \ + *k = *other; \ } \ else \ { \ diff --git a/binding-mri/font-binding.cpp b/binding-mri/font-binding.cpp index 8849197..c6f468a 100644 --- a/binding-mri/font-binding.cpp +++ b/binding-mri/font-binding.cpp @@ -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(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(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"); diff --git a/binding-mri/plane-binding.cpp b/binding-mri/plane-binding.cpp index 0cbb48f..5d2c407 100644 --- a/binding-mri/plane-binding.cpp +++ b/binding-mri/plane-binding.cpp @@ -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) diff --git a/binding-mri/sprite-binding.cpp b/binding-mri/sprite-binding.cpp index 830ef87..427d7b8 100644 --- a/binding-mri/sprite-binding.cpp +++ b/binding-mri/sprite-binding.cpp @@ -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) diff --git a/binding-mri/tilemap-binding.cpp b/binding-mri/tilemap-binding.cpp index 58674b9..54cbd05 100644 --- a/binding-mri/tilemap-binding.cpp +++ b/binding-mri/tilemap-binding.cpp @@ -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) diff --git a/binding-mri/tilemapvx-binding.cpp b/binding-mri/tilemapvx-binding.cpp index 7e51d2f..af15968 100644 --- a/binding-mri/tilemapvx-binding.cpp +++ b/binding-mri/tilemapvx-binding.cpp @@ -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) diff --git a/binding-mri/viewport-binding.cpp b/binding-mri/viewport-binding.cpp index 612ac16..566d66e 100644 --- a/binding-mri/viewport-binding.cpp +++ b/binding-mri/viewport-binding.cpp @@ -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) diff --git a/binding-mri/window-binding.cpp b/binding-mri/window-binding.cpp index 5df0e7b..1cd0ac3 100644 --- a/binding-mri/window-binding.cpp +++ b/binding-mri/window-binding.cpp @@ -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) diff --git a/binding-mri/windowvx-binding.cpp b/binding-mri/windowvx-binding.cpp index d70f02e..17bdd77 100644 --- a/binding-mri/windowvx-binding.cpp +++ b/binding-mri/windowvx-binding.cpp @@ -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) diff --git a/src/bitmap.cpp b/src/bitmap.cpp index f508334..beff91b 100644 --- a/src/bitmap.cpp +++ b/src/bitmap.cpp @@ -1067,7 +1067,17 @@ IntRect Bitmap::textSize(const char *str) return IntRect(0, 0, w, h); } -DEF_ATTR_SIMPLE(Bitmap, Font, Font*, p->font) +DEF_ATTR_RD_SIMPLE(Bitmap, Font, Font*, p->font) + +void Bitmap::setFont(Font *value) +{ + *p->font = *value; +} + +void Bitmap::setInitFont(Font *value) +{ + p->font = value; +} TEXFBO &Bitmap::getGLTypes() { diff --git a/src/bitmap.h b/src/bitmap.h index 22da2fe..89216d0 100644 --- a/src/bitmap.h +++ b/src/bitmap.h @@ -101,6 +101,10 @@ public: DECL_ATTR(Font, Font*) + /* Sets initial reference without copying by value, + * use at construction */ + void setInitFont(Font *value); + /* */ TEXFBO &getGLTypes(); SDL_Surface *megaSurface() const; diff --git a/src/etc.cpp b/src/etc.cpp index 7764c85..14f8f4c 100644 --- a/src/etc.cpp +++ b/src/etc.cpp @@ -52,20 +52,15 @@ bool Color::operator==(const Color &o) const alpha == o.alpha; } -void Color::updateInternal() +const Color &Color::operator=(const Color &o) { - norm.x = red / 255; - norm.y = green / 255; - norm.z = blue / 255; - norm.w = alpha / 255; -} + red = o.red; + green = o.green; + blue = o.blue; + alpha = o.alpha; + norm = o.norm; -void Color::updateExternal() -{ - red = norm.x * 255; - green = norm.y * 255; - blue = norm.z * 255; - alpha = norm.w * 255; + return o; } void Color::set(double red, double green, double blue, double alpha) @@ -78,15 +73,6 @@ void Color::set(double red, double green, double blue, double alpha) updateInternal(); } -void Color::set(const Color &other) -{ - red = other.red; - green = other.green; - blue = other.blue; - alpha = other.alpha; - norm = other.norm; -} - void Color::setRed(double value) { red = value; @@ -111,15 +97,6 @@ void Color::setAlpha(double value) norm.w = clamp(value, 0, 255) / 255; } -void Color::toSDLColor(SDL_Color &c) const -{ - c.r = clamp(red, 0, 255); - c.g = clamp(green, 0, 255); - c.b = clamp(blue, 0, 255); -// c.a = clamp(alpha, 0, 255); - c.a = 255; -} - /* Serializable */ int Color::serialSize() const { @@ -153,6 +130,31 @@ Color *Color::deserialize(const char *data, int len) return c; } +void Color::updateInternal() +{ + norm.x = red / 255; + norm.y = green / 255; + norm.z = blue / 255; + norm.w = alpha / 255; +} + +void Color::updateExternal() +{ + red = norm.x * 255; + green = norm.y * 255; + blue = norm.z * 255; + alpha = norm.w * 255; +} + +void Color::toSDLColor(SDL_Color &c) const +{ + c.r = clamp(red, 0, 255); + c.g = clamp(green, 0, 255); + c.b = clamp(blue, 0, 255); +// c.a = clamp(alpha, 0, 255); + c.a = 255; +} + Tone::Tone(double red, double green, double blue, double gray) : red(red), green(green), blue(blue), gray(gray) @@ -173,14 +175,6 @@ bool Tone::operator==(const Tone &o) const gray == o.gray; } -void Tone::updateInternal() -{ - norm.x = (float) clamp(red, -255, 255) / 255; - norm.y = (float) clamp(green, -255, 255) / 255; - norm.z = (float) clamp(blue, -255, 255) / 255; - norm.w = (float) clamp(gray, 0, 255) / 255; -} - void Tone::set(double red, double green, double blue, double gray) { this->red = red; @@ -192,15 +186,17 @@ void Tone::set(double red, double green, double blue, double gray) valueChanged(); } -void Tone::set(const Tone &other) +const Tone& Tone::operator=(const Tone &o) { - red = other.red; - green= other.green; - blue = other.blue; - gray = other.gray; - norm = other.norm; + red = o.red; + green = o.green; + blue = o.blue; + gray = o.gray; + norm = o.norm; valueChanged(); + + return o; } void Tone::setRed(double value) @@ -268,6 +264,14 @@ Tone *Tone::deserialize(const char *data, int len) return t; } +void Tone::updateInternal() +{ + norm.x = (float) clamp(red, -255, 255) / 255; + norm.y = (float) clamp(green, -255, 255) / 255; + norm.z = (float) clamp(blue, -255, 255) / 255; + norm.w = (float) clamp(gray, 0, 255) / 255; +} + Rect::Rect(int x, int y, int width, int height) : x(x), y(y), width(width), height(height) @@ -315,14 +319,16 @@ void Rect::set(int x, int y, int w, int h) valueChanged(); } -void Rect::set(const Rect &other) +const Rect &Rect::operator=(const Rect &o) { - x = other.x; - y = other.y; - width = other.width; - height = other.height; + x = o.x; + y = o.y; + width = o.width; + height = o.height; valueChanged(); + + return o; } void Rect::empty() diff --git a/src/etc.h b/src/etc.h index d977569..3fba42f 100644 --- a/src/etc.h +++ b/src/etc.h @@ -50,13 +50,10 @@ struct Color : public Serializable virtual ~Color() {} - bool operator==(const Color &o) const; - - void updateInternal(); - void updateExternal(); - + const Color &operator=(const Color &o); void set(double red, double green, double blue, double alpha); - void set(const Color &other); + + bool operator==(const Color &o) const; void setRed(double value); void setGreen(double value); @@ -68,6 +65,15 @@ struct Color : public Serializable double getBlue() const { return blue; } double getAlpha() const { return alpha; } + /* Serializable */ + int serialSize() const; + void serialize(char *buffer) const; + static Color *deserialize(const char *data, int len); + + /* Internal */ + void updateInternal(); + void updateExternal(); + bool hasEffect() const { return (alpha != 0); @@ -75,11 +81,6 @@ struct Color : public Serializable void toSDLColor(SDL_Color &c) const; - /* Serializable */ - int serialSize() const; - void serialize(char *buffer) const; - static Color *deserialize(const char *data, int len); - /* Range (0.0 ~ 255.0) */ double red; double green; @@ -103,10 +104,8 @@ struct Tone : public Serializable bool operator==(const Tone &o) const; - void updateInternal(); - void set(double red, double green, double blue, double gray); - void set(const Tone &other); + const Tone &operator=(const Tone &o); void setRed(double value); void setGreen(double value); @@ -118,6 +117,14 @@ struct Tone : public Serializable double getBlue() const { return blue; } double getGray() const { return gray; } + /* Serializable */ + int serialSize() const; + void serialize(char *buffer) const; + static Tone *deserialize(const char *data, int len); + + /* Internal */ + void updateInternal(); + bool hasEffect() const { return ((int)red != 0 || @@ -126,11 +133,6 @@ struct Tone : public Serializable (int)gray != 0); } - /* Serializable */ - int serialSize() const; - void serialize(char *buffer) const; - static Tone *deserialize(const char *data, int len); - /* Range (-255.0 ~ 255.0) */ double red; double green; @@ -159,17 +161,7 @@ struct Rect : public Serializable bool operator==(const Rect &o) const; void operator=(const IntRect &rect); void set(int x, int y, int w, int h); - void set(const Rect &other); - - FloatRect toFloatRect() const - { - return FloatRect(x, y, width, height); - } - - IntRect toIntRect() - { - return IntRect(x, y, width, height); - } + const Rect &operator=(const Rect &o); void empty(); bool isEmpty() const; @@ -184,10 +176,22 @@ struct Rect : public Serializable int getWidth() const { return width; } int getHeight() const { return height; } + /* Serializable */ int serialSize() const; void serialize(char *buffer) const; static Rect *deserialize(const char *data, int len); + /* Internal */ + FloatRect toFloatRect() const + { + return FloatRect(x, y, width, height); + } + + IntRect toIntRect() + { + return IntRect(x, y, width, height); + } + int x; int y; int width; diff --git a/src/font.cpp b/src/font.cpp index 8a85f6c..09b5ec8 100644 --- a/src/font.cpp +++ b/src/font.cpp @@ -255,6 +255,20 @@ struct FontPrivate outColorTmp(*other.outColor), sdlFont(other.sdlFont) {} + + void operator=(const FontPrivate &o) + { + name = o.name; + size = o.size; + bold = o.bold; + italic = o.italic; + outline = o.outline; + shadow = o.shadow; + *color = *o.color; + *outColor = *o.outColor; + + sdlFont = 0; + } }; std::string FontPrivate::defaultName = "Arial"; @@ -269,12 +283,6 @@ Color *FontPrivate::defaultOutColor = &FontPrivate::defaultOutColorTmp; Color FontPrivate::defaultColorTmp(255, 255, 255, 255); Color FontPrivate::defaultOutColorTmp(0, 0, 0, 128); -void Font::initDefaults() -{ - FontPrivate::defaultOutline = (rgssVer >= 3 ? true : false); - FontPrivate::defaultShadow = (rgssVer >= 3 ? false : true ); -} - bool Font::doesExist(const char *name) { if (!name) @@ -299,6 +307,13 @@ Font::~Font() delete p; } +const Font &Font::operator=(const Font &o) +{ + *p = *o.p; + + return o; +} + const char *Font::getName() const { return p->name.c_str(); @@ -329,21 +344,21 @@ void Font::setSize(int value) #undef CHK_DISP #define CHK_DISP -DEF_ATTR_RD_SIMPLE(Font, Size, int, p->size) -DEF_ATTR_SIMPLE(Font, Bold, bool, p->bold) -DEF_ATTR_SIMPLE(Font, Italic, bool, p->italic) -DEF_ATTR_SIMPLE(Font, Color, Color*, p->color) -DEF_ATTR_SIMPLE(Font, Shadow, bool, p->shadow) -DEF_ATTR_SIMPLE(Font, Outline, bool, p->outline) -DEF_ATTR_SIMPLE(Font, OutColor, Color*, p->outColor) +DEF_ATTR_RD_SIMPLE(Font, Size, int, p->size) +DEF_ATTR_SIMPLE (Font, Bold, bool, p->bold) +DEF_ATTR_SIMPLE (Font, Italic, bool, p->italic) +DEF_ATTR_SIMPLE (Font, Shadow, bool, p->shadow) +DEF_ATTR_SIMPLE (Font, Outline, bool, p->outline) +DEF_ATTR_OBJ_VALUE(Font, Color, Color*, p->color) +DEF_ATTR_OBJ_VALUE(Font, OutColor, Color*, p->outColor) -DEF_ATTR_SIMPLE_STATIC(Font, DefaultSize, int, FontPrivate::defaultSize) -DEF_ATTR_SIMPLE_STATIC(Font, DefaultBold, bool, FontPrivate::defaultBold) -DEF_ATTR_SIMPLE_STATIC(Font, DefaultItalic, bool, FontPrivate::defaultItalic) -DEF_ATTR_SIMPLE_STATIC(Font, DefaultColor, Color*, FontPrivate::defaultColor) -DEF_ATTR_SIMPLE_STATIC(Font, DefaultShadow, bool, FontPrivate::defaultShadow) -DEF_ATTR_SIMPLE_STATIC(Font, DefaultOutline, bool, FontPrivate::defaultOutline) -DEF_ATTR_SIMPLE_STATIC(Font, DefaultOutColor, Color*, FontPrivate::defaultOutColor) +DEF_ATTR_SIMPLE_STATIC (Font, DefaultSize, int, FontPrivate::defaultSize) +DEF_ATTR_SIMPLE_STATIC (Font, DefaultBold, bool, FontPrivate::defaultBold) +DEF_ATTR_SIMPLE_STATIC (Font, DefaultItalic, bool, FontPrivate::defaultItalic) +DEF_ATTR_SIMPLE_STATIC (Font, DefaultShadow, bool, FontPrivate::defaultShadow) +DEF_ATTR_SIMPLE_STATIC (Font, DefaultOutline, bool, FontPrivate::defaultOutline) +DEF_ATTR_OBJ_VALUE_STATIC(Font, DefaultColor, Color*, FontPrivate::defaultColor) +DEF_ATTR_OBJ_VALUE_STATIC(Font, DefaultOutColor, Color*, FontPrivate::defaultOutColor) const char *Font::getDefaultName() { @@ -355,6 +370,28 @@ void Font::setDefaultName(const char *value) FontPrivate::defaultName = value; } +void Font::initDynAttribs() +{ + p->color = new Color(p->colorTmp); + + if (rgssVer >= 3) + p->outColor = new Color(p->outColorTmp);; +} + +void Font::initDefaultDynAttribs() +{ + FontPrivate::defaultColor = new Color(FontPrivate::defaultColorTmp); + + if (rgssVer >= 3) + FontPrivate::defaultOutColor = new Color(FontPrivate::defaultOutColorTmp); +} + +void Font::initDefaults() +{ + FontPrivate::defaultOutline = (rgssVer >= 3 ? true : false); + FontPrivate::defaultShadow = (rgssVer >= 3 ? false : true ); +} + _TTF_Font *Font::getSdlFont() { if (!p->sdlFont) diff --git a/src/font.h b/src/font.h index 8a5b075..9320600 100644 --- a/src/font.h +++ b/src/font.h @@ -82,6 +82,8 @@ public: Font(const Font &other); ~Font(); + const Font &operator=(const Font &o); + const char *getName() const; void setName(const char *value); @@ -102,6 +104,12 @@ public: DECL_ATTR_STATIC( DefaultOutline, bool ) DECL_ATTR_STATIC( DefaultOutColor, Color* ) + /* Assigns heap allocated objects to object properties; + * using this in pure C++ will cause memory leaks + * (ie. only to be used in GCed language bindings */ + void initDynAttribs(); + static void initDefaultDynAttribs(); + static void initDefaults(); /* internal */ diff --git a/src/plane.cpp b/src/plane.cpp index 8b0f308..1982bce 100644 --- a/src/plane.cpp +++ b/src/plane.cpp @@ -163,9 +163,9 @@ DEF_ATTR_RD_SIMPLE(Plane, ZoomX, float, p->zoomX) DEF_ATTR_RD_SIMPLE(Plane, ZoomY, float, p->zoomY) DEF_ATTR_RD_SIMPLE(Plane, BlendType, int, p->blendType) -DEF_ATTR_SIMPLE(Plane, Opacity, int, p->opacity) -DEF_ATTR_SIMPLE(Plane, Color, Color*, p->color) -DEF_ATTR_SIMPLE(Plane, Tone, Tone*, p->tone) +DEF_ATTR_SIMPLE (Plane, Opacity, int, p->opacity) +DEF_ATTR_OBJ_VALUE(Plane, Color, Color*, p->color) +DEF_ATTR_OBJ_VALUE(Plane, Tone, Tone*, p->tone) Plane::~Plane() { @@ -238,6 +238,11 @@ void Plane::setBlendType(int value) } } +void Plane::initDynAttribs() +{ + p->color = new Color; + p->tone = new Tone; +} void Plane::draw() { diff --git a/src/plane.h b/src/plane.h index 9f4cd25..1b55278 100644 --- a/src/plane.h +++ b/src/plane.h @@ -47,6 +47,8 @@ public: DECL_ATTR( Color, Color* ) DECL_ATTR( Tone, Tone* ) + void initDynAttribs(); + private: PlanePrivate *p; diff --git a/src/sprite.cpp b/src/sprite.cpp index 50a2415..b436db2 100644 --- a/src/sprite.cpp +++ b/src/sprite.cpp @@ -304,7 +304,6 @@ Sprite::~Sprite() } DEF_ATTR_RD_SIMPLE(Sprite, Bitmap, Bitmap*, p->bitmap) -DEF_ATTR_RD_SIMPLE(Sprite, SrcRect, Rect*, p->srcRect) DEF_ATTR_RD_SIMPLE(Sprite, X, int, p->trans.getPosition().x) DEF_ATTR_RD_SIMPLE(Sprite, Y, int, p->trans.getPosition().y) DEF_ATTR_RD_SIMPLE(Sprite, OX, int, p->trans.getOrigin().x) @@ -322,10 +321,12 @@ DEF_ATTR_RD_SIMPLE(Sprite, WaveLength, int, p->wave.length) DEF_ATTR_RD_SIMPLE(Sprite, WaveSpeed, int, p->wave.speed) DEF_ATTR_RD_SIMPLE(Sprite, WavePhase, float, p->wave.phase) -DEF_ATTR_SIMPLE(Sprite, BushOpacity, int, p->bushOpacity) -DEF_ATTR_SIMPLE(Sprite, Opacity, int, p->opacity) -DEF_ATTR_SIMPLE(Sprite, Color, Color*, p->color) -DEF_ATTR_SIMPLE(Sprite, Tone, Tone*, p->tone) +DEF_ATTR_SIMPLE (Sprite, BushOpacity, int, p->bushOpacity) +DEF_ATTR_SIMPLE (Sprite, Opacity, int, p->opacity) + +DEF_ATTR_OBJ_VALUE(Sprite, SrcRect, Rect*, p->srcRect) +DEF_ATTR_OBJ_VALUE(Sprite, Color, Color*, p->color) +DEF_ATTR_OBJ_VALUE(Sprite, Tone, Tone*, p->tone) void Sprite::setBitmap(Bitmap *bitmap) { @@ -347,18 +348,6 @@ void Sprite::setBitmap(Bitmap *bitmap) p->wave.dirty = true; } -void Sprite::setSrcRect(Rect *rect) -{ - if (p->srcRect == rect) - return; - - p->srcRect = rect; - p->updateSrcRectCon(); - - if (p->bitmap) - p->onSrcRectChange(); -} - void Sprite::setX(int value) { if (p->trans.getPosition().x == value) @@ -476,6 +465,15 @@ DEF_WAVE_SETTER(Phase, phase, float) #undef DEF_WAVE_SETTER +void Sprite::initDynAttribs() +{ + p->srcRect = new Rect; + p->color = new Color; + p->tone = new Tone; + + p->updateSrcRectCon(); +} + /* Flashable */ void Sprite::update() { diff --git a/src/sprite.h b/src/sprite.h index 3783f90..b1645bb 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -67,6 +67,8 @@ public: DECL_ATTR( WaveSpeed, int ) DECL_ATTR( WavePhase, float ) + void initDynAttribs(); + private: SpritePrivate *p; diff --git a/src/util.h b/src/util.h index 3f63b5e..b8b42f4 100644 --- a/src/util.h +++ b/src/util.h @@ -137,4 +137,18 @@ inline bool contains(const C &c, const V &v) #define DEF_ATTR_SIMPLE_STATIC(klass, name, type, location) \ DEF_ATTR_SIMPLE_DETAILED(klass, name, type, location, ) +#define DEF_ATTR_OBJ_VALUE(klass, name, type, location) \ + DEF_ATTR_RD_SIMPLE_DETAILED(klass, name, type, location, const) \ + void klass :: set##name(type value) \ + { \ + *location = *value; \ + } + +#define DEF_ATTR_OBJ_VALUE_STATIC(klass, name, type, location) \ + DEF_ATTR_RD_SIMPLE_DETAILED(klass, name, type, location, ) \ + void klass :: set##name(type value) \ + { \ + *location = *value; \ + } + #endif // UTIL_H diff --git a/src/viewport.cpp b/src/viewport.cpp index 38aa89f..49c3798 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -141,10 +141,10 @@ Viewport::~Viewport() DEF_ATTR_RD_SIMPLE(Viewport, OX, int, geometry.xOrigin) DEF_ATTR_RD_SIMPLE(Viewport, OY, int, geometry.yOrigin) -DEF_ATTR_RD_SIMPLE(Viewport, Rect, Rect*, p->rect) -DEF_ATTR_SIMPLE(Viewport, Color, Color*, p->color) -DEF_ATTR_SIMPLE(Viewport, Tone, Tone*, p->tone) +DEF_ATTR_OBJ_VALUE(Viewport, Rect, Rect*, p->rect) +DEF_ATTR_OBJ_VALUE(Viewport, Color, Color*, p->color) +DEF_ATTR_OBJ_VALUE(Viewport, Tone, Tone*, p->tone) void Viewport::setOX(int value) { @@ -164,14 +164,13 @@ void Viewport::setOY(int value) notifyGeometryChange(); } -void Viewport::setRect(Rect *value) +void Viewport::initDynAttribs() { - if (p->rect == value) - return; + p->rect = new Rect(*p->rect); + p->color = new Color; + p->tone = new Tone; - p->rect = value; p->updateRectCon(); - p->onRectChange(); } /* Scene */ diff --git a/src/viewport.h b/src/viewport.h index 6d340b6..325da41 100644 --- a/src/viewport.h +++ b/src/viewport.h @@ -43,6 +43,8 @@ public: DECL_ATTR( Color, Color* ) DECL_ATTR( Tone, Tone* ) + void initDynAttribs(); + private: void initViewport(int x, int y, int width, int height); void geometryChanged(); diff --git a/src/window.cpp b/src/window.cpp index 6f985fd..1d43d95 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -711,7 +711,6 @@ DEF_ATTR_SIMPLE(Window, Y, int, p->position.y) DEF_ATTR_RD_SIMPLE(Window, Windowskin, Bitmap*, p->windowskin) DEF_ATTR_RD_SIMPLE(Window, Contents, Bitmap*, p->contents) DEF_ATTR_RD_SIMPLE(Window, Stretch, bool, p->bgStretch) -DEF_ATTR_RD_SIMPLE(Window, CursorRect, Rect*, p->cursorRect) DEF_ATTR_RD_SIMPLE(Window, Active, bool, p->active) DEF_ATTR_RD_SIMPLE(Window, Pause, bool, p->pause) DEF_ATTR_RD_SIMPLE(Window, Width, int, p->size.x) @@ -722,6 +721,8 @@ DEF_ATTR_RD_SIMPLE(Window, Opacity, int, p->opacity) DEF_ATTR_RD_SIMPLE(Window, BackOpacity, int, p->backOpacity) DEF_ATTR_RD_SIMPLE(Window, ContentsOpacity, int, p->contentsOpacity) +DEF_ATTR_OBJ_VALUE(Window, CursorRect, Rect*, p->cursorRect) + void Window::setWindowskin(Bitmap *value) { p->windowskin = value; @@ -758,17 +759,6 @@ void Window::setStretch(bool value) p->baseVertDirty = true; } -void Window::setCursorRect(Rect *value) -{ - if (p->cursorRect == value) - return; - - p->cursorRect = value; - - p->refreshCursorRectCon(); - p->markControlVertDirty(); -} - void Window::setActive(bool value) { if (p->active == value) @@ -852,6 +842,13 @@ void Window::setContentsOpacity(int value) p->contentsQuad.setColor(Vec4(1, 1, 1, p->contentsOpacity.norm)); } +void Window::initDynAttribs() +{ + p->cursorRect = new Rect; + + p->refreshCursorRectCon(); +} + void Window::draw() { p->drawBase(); diff --git a/src/window.h b/src/window.h index 50e88e9..a3fb315 100644 --- a/src/window.h +++ b/src/window.h @@ -56,6 +56,8 @@ public: DECL_ATTR( BackOpacity, int ) DECL_ATTR( ContentsOpacity, int ) + void initDynAttribs(); + private: WindowPrivate *p; diff --git a/src/windowvx.cpp b/src/windowvx.cpp index 936792f..103bc44 100644 --- a/src/windowvx.cpp +++ b/src/windowvx.cpp @@ -870,7 +870,6 @@ DEF_ATTR_SIMPLE(WindowVX, Y, int, p->geo.y) DEF_ATTR_RD_SIMPLE(WindowVX, Windowskin, Bitmap*, p->windowskin) DEF_ATTR_RD_SIMPLE(WindowVX, Contents, Bitmap*, p->contents) -DEF_ATTR_RD_SIMPLE(WindowVX, CursorRect, Rect*, p->cursorRect) DEF_ATTR_RD_SIMPLE(WindowVX, Active, bool, p->active) DEF_ATTR_RD_SIMPLE(WindowVX, ArrowsVisible, bool, p->arrowsVisible) DEF_ATTR_RD_SIMPLE(WindowVX, Pause, bool, p->pause) @@ -884,7 +883,9 @@ DEF_ATTR_RD_SIMPLE(WindowVX, Opacity, int, p->opacity) DEF_ATTR_RD_SIMPLE(WindowVX, BackOpacity, int, p->backOpacity) DEF_ATTR_RD_SIMPLE(WindowVX, ContentsOpacity, int, p->contentsOpacity) DEF_ATTR_RD_SIMPLE(WindowVX, Openness, int, p->openness) -DEF_ATTR_RD_SIMPLE(WindowVX, Tone, Tone*, p->tone) + +DEF_ATTR_OBJ_VALUE(WindowVX, CursorRect, Rect*, p->cursorRect) +DEF_ATTR_OBJ_VALUE(WindowVX, Tone, Tone*, p->tone) void WindowVX::setWindowskin(Bitmap *value) { @@ -909,16 +910,6 @@ void WindowVX::setContents(Bitmap *value) p->ctrlVertDirty = true; } -void WindowVX::setCursorRect(Rect *value) -{ - if (p->cursorRect == value) - return; - - p->cursorRect = value; - p->cursorVertDirty = true; - p->refreshCursorRectCon(); -} - void WindowVX::setActive(bool value) { if (p->active == value) @@ -1050,12 +1041,12 @@ void WindowVX::setOpenness(int value) p->updateBaseQuad(); } -void WindowVX::setTone(Tone *value) +void WindowVX::initDynAttribs() { - if (p->tone == value) - return; + p->cursorRect = new Rect; + p->tone = new Tone; - p->tone = value; + p->refreshCursorRectCon(); p->refreshToneCon(); } diff --git a/src/windowvx.h b/src/windowvx.h index 3d42410..d90840f 100644 --- a/src/windowvx.h +++ b/src/windowvx.h @@ -66,6 +66,8 @@ public: DECL_ATTR( Openness, int ) DECL_ATTR( Tone, Tone* ) + void initDynAttribs(); + private: WindowVXPrivate *p;