diff --git a/binding-mri/binding-util.cpp b/binding-mri/binding-util.cpp index c85a86a..7755625 100644 --- a/binding-mri/binding-util.cpp +++ b/binding-mri/binding-util.cpp @@ -26,6 +26,7 @@ #include "util.h" #include +#include #include void initType(rb_data_type_struct &type, @@ -97,6 +98,18 @@ void raiseRbExc(const Exception &exc) rb_raise(excClass, "%s", exc.msg.c_str()); } +void +raiseDisposedAccess(VALUE self) +{ + const char *klassName = RTYPEDDATA_TYPE(self)->wrap_struct_name; + char buf[32]; + + strncpy(buf, klassName, sizeof(buf)); + buf[0] = tolower(buf[0]); + + rb_raise(getRbData()->exc[RGSS], "disposed %s", buf); +} + int rb_get_args(int argc, VALUE *argv, const char *format, ...) { diff --git a/binding-mri/binding-util.h b/binding-mri/binding-util.h index 441907e..06edad7 100644 --- a/binding-mri/binding-util.h +++ b/binding-mri/binding-util.h @@ -87,17 +87,34 @@ static void freeInstance(void *inst) #define INIT_TYPE(Klass) initType(Klass##Type, #Klass, freeInstance) +void +raiseDisposedAccess(VALUE self); + +inline void +checkDisposed(VALUE self) +{ + if (!RTYPEDDATA_DATA(self)) + raiseDisposedAccess(self); +} + template -static inline C * +inline C * getPrivateData(VALUE self) { - return static_cast(RTYPEDDATA_DATA(self)); + C *c = static_cast(RTYPEDDATA_DATA(self)); + + if (!c) + raiseDisposedAccess(self); + + return c; } template static inline C * getPrivateDataCheck(VALUE self, const rb_data_type_struct &type) { + /* We don't check for disposed here because any disposable + * property is always also nullable */ void *obj = Check_TypedStruct(self, &type); return static_cast(obj); } @@ -286,17 +303,11 @@ rb_check_argc(int actual, int expected) return self; \ } -/* If we're not binding a disposable class, - * we want to #undef DEF_PROP_CHK_DISP */ -#define DEF_PROP_CHK_DISP \ - checkDisposed(k, DISP_CLASS_NAME); - #define DEF_PROP_OBJ(Klass, PropKlass, PropName, prop_iv) \ RB_METHOD(Klass##Get##PropName) \ { \ RB_UNUSED_PARAM; \ - Klass *k = getPrivateData(self); (void) k; \ - DEF_PROP_CHK_DISP \ + checkDisposed(self); \ return rb_iv_get(self, prop_iv); \ } \ RB_METHOD(Klass##Set##PropName) \ @@ -311,13 +322,14 @@ rb_check_argc(int actual, int expected) return propObj; \ } -/* Object property with allowed NIL */ +/* Object property 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) \ RB_METHOD(Klass##Get##PropName) \ { \ RB_UNUSED_PARAM; \ - Klass *k = getPrivateData(self); (void) k; \ - DEF_PROP_CHK_DISP \ return rb_iv_get(self, prop_iv); \ } \ RB_METHOD(Klass##Set##PropName) \ @@ -341,7 +353,6 @@ rb_check_argc(int actual, int expected) { \ RB_UNUSED_PARAM; \ Klass *k = getPrivateData(self); \ - DEF_PROP_CHK_DISP \ return value_fun(k->get##PropName()); \ } \ RB_METHOD(Klass##Set##PropName) \ diff --git a/binding-mri/bitmap-binding.cpp b/binding-mri/bitmap-binding.cpp index 77a35d2..0d2de74 100644 --- a/binding-mri/bitmap-binding.cpp +++ b/binding-mri/bitmap-binding.cpp @@ -26,8 +26,6 @@ #include "binding-util.h" #include "binding-types.h" -#define DISP_CLASS_NAME "bitmap" - DEF_TYPE(Bitmap); void bitmapInitProps(Bitmap *b, VALUE self) @@ -123,7 +121,7 @@ RB_METHOD(bitmapBlt) src = getPrivateDataCheck(srcObj, BitmapType); srcRect = getPrivateDataCheck(srcRectObj, RectType); - GUARD_EXC( b->blt(x, y, *src, srcRect->toIntRect(), opacity); ); + GUARD_EXC( b->blt(x, y, src, srcRect->toIntRect(), opacity); ); return self; } @@ -146,7 +144,7 @@ RB_METHOD(bitmapStretchBlt) destRect = getPrivateDataCheck(destRectObj, RectType); srcRect = getPrivateDataCheck(srcRectObj, RectType); - GUARD_EXC( b->stretchBlt(destRect->toIntRect(), *src, srcRect->toIntRect(), opacity); ); + GUARD_EXC( b->stretchBlt(destRect->toIntRect(), src, srcRect->toIntRect(), opacity); ); return self; } diff --git a/binding-mri/disposable-binding.h b/binding-mri/disposable-binding.h index 050d6a8..6b873d5 100644 --- a/binding-mri/disposable-binding.h +++ b/binding-mri/disposable-binding.h @@ -25,41 +25,74 @@ #include "disposable.h" #include "binding-util.h" +/* 'Children' are disposables that are disposed together + * with their parent. Currently this is only used by Viewport + * in RGSS1. + * FIXME: Disable this behavior when RGSS2 or 3 */ +inline void +disposableAddChild(VALUE disp, VALUE child) +{ + VALUE children = rb_iv_get(disp, "children"); + + if (NIL_P(children)) + { + children = rb_ary_new(); + rb_iv_set(disp, "children", children); + } + + /* Assumes children are never removed until destruction */ + rb_ary_push(children, child); +} + +inline void +disposableDisposeChildren(VALUE disp) +{ + VALUE children = rb_iv_get(disp, "children"); + + if (NIL_P(children)) + return; + + ID dispFun = rb_intern("dispose"); + + /* Note: RMXP doesn't call overridden 'dispose' methods here */ + for (long i = 0; i < RARRAY_LEN(children); ++i) + rb_funcall2(rb_ary_entry(children, i), dispFun, 0, 0); +} + template RB_METHOD(disposableDispose) { RB_UNUSED_PARAM; - Disposable *d = getPrivateData(self); + C *c = static_cast(RTYPEDDATA_DATA(self)); - d->dispose(); + /* Nothing to do if already disposed */ + if (!c) + return Qnil; + + /* Inform core */ + c->wasDisposed(); + + disposableDisposeChildren(self); + + delete c; + setPrivateData(self, 0); return Qnil; } -template RB_METHOD(disposableIsDisposed) { RB_UNUSED_PARAM; - Disposable *d = getPrivateData(self); - - return rb_bool_new(d->isDisposed()); + return rb_bool_new(RTYPEDDATA_DATA(self) == 0); } template static void disposableBindingInit(VALUE klass) { _rb_define_method(klass, "dispose", disposableDispose); - _rb_define_method(klass, "disposed?", disposableIsDisposed); -} - -inline void checkDisposed(Disposable *d, const char *klassName) -{ - RbData *data = getRbData(); (void) data; - - if (d->isDisposed()) - rb_raise(getRbData()->exc[RGSS], "disposed %s", klassName); + _rb_define_method(klass, "disposed?", disposableIsDisposed); } #endif // DISPOSABLEBINDING_H diff --git a/binding-mri/font-binding.cpp b/binding-mri/font-binding.cpp index 66b6339..dc46469 100644 --- a/binding-mri/font-binding.cpp +++ b/binding-mri/font-binding.cpp @@ -153,9 +153,6 @@ RB_METHOD(FontSetName) return argv[0]; } -#undef DEF_PROP_CHK_DISP -#define DEF_PROP_CHK_DISP - DEF_PROP_I(Font, Size) DEF_PROP_B(Font, Bold) DEF_PROP_B(Font, Italic) diff --git a/binding-mri/plane-binding.cpp b/binding-mri/plane-binding.cpp index 3fdb808..d1426a2 100644 --- a/binding-mri/plane-binding.cpp +++ b/binding-mri/plane-binding.cpp @@ -43,8 +43,6 @@ RB_METHOD(planeInitialize) return self; } -#define DISP_CLASS_NAME "plane" - DEF_PROP_OBJ_NIL(Plane, Bitmap, Bitmap, "bitmap") DEF_PROP_OBJ(Plane, Color, Color, "color") DEF_PROP_OBJ(Plane, Tone, Tone, "tone") diff --git a/binding-mri/sprite-binding.cpp b/binding-mri/sprite-binding.cpp index 94d8ee3..bf0d4f7 100644 --- a/binding-mri/sprite-binding.cpp +++ b/binding-mri/sprite-binding.cpp @@ -48,8 +48,6 @@ RB_METHOD(spriteInitialize) return self; } -#define DISP_CLASS_NAME "sprite" - DEF_PROP_OBJ_NIL(Sprite, Bitmap, Bitmap, "bitmap") DEF_PROP_OBJ(Sprite, Rect, SrcRect, "src_rect") DEF_PROP_OBJ(Sprite, Color, Color, "color") diff --git a/binding-mri/tilemap-binding.cpp b/binding-mri/tilemap-binding.cpp index f525158..1fe0fe8 100644 --- a/binding-mri/tilemap-binding.cpp +++ b/binding-mri/tilemap-binding.cpp @@ -115,15 +115,11 @@ RB_METHOD(tilemapUpdate) return Qnil; } -#define DISP_CLASS_NAME "tilemap" - RB_METHOD(tilemapGetViewport) { RB_UNUSED_PARAM; - Tilemap *t = getPrivateData(self); - - checkDisposed(t, DISP_CLASS_NAME); + checkDisposed(self); return rb_iv_get(self, "viewport"); } @@ -170,4 +166,3 @@ tilemapBindingInit() INIT_PROP_BIND( Tilemap, OX, "ox" ); INIT_PROP_BIND( Tilemap, OY, "oy" ); } - diff --git a/binding-mri/viewport-binding.cpp b/binding-mri/viewport-binding.cpp index 585762c..75f447e 100644 --- a/binding-mri/viewport-binding.cpp +++ b/binding-mri/viewport-binding.cpp @@ -65,11 +65,14 @@ RB_METHOD(viewportInitialize) wrapProperty(self, v->getColor(), "color", ColorType); wrapProperty(self, v->getTone(), "tone", ToneType); + /* 'elements' holds all SceneElements that become children + * of this viewport, so we can dispose them when the viewport + * is disposed */ + rb_iv_set(self, "elements", rb_ary_new()); + return self; } -#define DISP_CLASS_NAME "viewport" - DEF_PROP_OBJ(Viewport, Rect, Rect, "rect") DEF_PROP_OBJ(Viewport, Color, Color, "color") DEF_PROP_OBJ(Viewport, Tone, Tone, "tone") diff --git a/binding-mri/viewportelement-binding.h b/binding-mri/viewportelement-binding.h index 3a73136..2359198 100644 --- a/binding-mri/viewportelement-binding.h +++ b/binding-mri/viewportelement-binding.h @@ -27,15 +27,14 @@ #include "binding-types.h" #include "sceneelement-binding.h" +#include "disposable-binding.h" template RB_METHOD(viewportElementGetViewport) { RB_UNUSED_PARAM; - ViewportElement *ve = getPrivateData(self); - - GUARD_EXC( ve->aboutToAccess(); ); + checkDisposed(self); return rb_iv_get(self, "viewport"); } @@ -77,7 +76,10 @@ viewportElementInitialize(int argc, VALUE *argv, VALUE self) rb_get_args(argc, argv, "|o", &viewportObj RB_ARG_END); if (!NIL_P(viewportObj)) + { viewport = getPrivateDataCheck(viewportObj, ViewportType); + disposableAddChild(viewportObj, self); + } /* Construct object */ C *ve = new C(viewport); diff --git a/binding-mri/window-binding.cpp b/binding-mri/window-binding.cpp index b77c49c..0fddf6c 100644 --- a/binding-mri/window-binding.cpp +++ b/binding-mri/window-binding.cpp @@ -51,8 +51,6 @@ RB_METHOD(windowUpdate) return Qnil; } -#define DISP_CLASS_NAME "window" - DEF_PROP_OBJ_NIL(Window, Bitmap, Windowskin, "windowskin") DEF_PROP_OBJ_NIL(Window, Bitmap, Contents, "contents") DEF_PROP_OBJ(Window, Rect, CursorRect, "cursor_rect") diff --git a/binding-mruby/binding-util.cpp b/binding-mruby/binding-util.cpp index 70e1d46..6a35a65 100644 --- a/binding-mruby/binding-util.cpp +++ b/binding-mruby/binding-util.cpp @@ -23,6 +23,8 @@ #include "util.h" #include "exception.h" +#include + #define SYMD(symbol) { CS##symbol, #symbol } struct @@ -48,7 +50,9 @@ struct SYMD(cursor_rect), SYMD(path), SYMD(array), - SYMD(default_color) + SYMD(default_color), + SYMD(children), + SYMD(dispose) }; static elementsN(symData); @@ -140,6 +144,19 @@ void raiseMrbExc(mrb_state *mrb, const Exception &exc) mrb_raise(mrb, excClass, exc.msg.c_str()); } +void +raiseDisposedAccess(mrb_state *mrb, mrb_value self) +{ + const char *klassName = DATA_TYPE(self)->struct_name; + char buf[32]; + + strncpy(buf, klassName, sizeof(buf)); + buf[0] = tolower(buf[0]); + + mrb_raisef(mrb, getMrbData(mrb)->exc[RGSS], + "disposed %S", mrb_str_new_cstr(mrb, buf)); +} + MRB_METHOD_PUB(inspectObject) { static char buffer[64]; diff --git a/binding-mruby/binding-util.h b/binding-mruby/binding-util.h index 38c5e56..2faacf9 100644 --- a/binding-mruby/binding-util.h +++ b/binding-mruby/binding-util.h @@ -50,6 +50,8 @@ enum CommonSymbol CSpath, CSarray, CSdefault_color, + CSchildren, + CSdispose, CommonSymbolsMax }; @@ -143,16 +145,10 @@ defineClass(mrb_state *mrb, const char *name) #define MRB_FUN_UNUSED_PARAM { (void) mrb; } -/* If we're not binding a disposable class, - * we want to #undef DEF_PROP_CHK_DISP */ -#define DEF_PROP_CHK_DISP \ - checkDisposed(mrb, k, DISP_CLASS_NAME); - #define DEF_PROP_OBJ(Klass, PropKlass, PropName, prop_iv) \ MRB_METHOD(Klass##Get##PropName) \ { \ - Klass *k = getPrivateData(mrb, self); (void) k; \ - DEF_PROP_CHK_DISP \ + checkDisposed(mrb, self); \ return getProperty(mrb, self, prop_iv); \ } \ MRB_METHOD(Klass##Set##PropName) \ @@ -171,8 +167,6 @@ defineClass(mrb_state *mrb, const char *name) #define DEF_PROP_OBJ_NIL(Klass, PropKlass, PropName, prop_iv) \ MRB_METHOD(Klass##Get##PropName) \ { \ - Klass *k = getPrivateData(mrb, self); (void) k; \ - DEF_PROP_CHK_DISP \ return getProperty(mrb, self, prop_iv); \ } \ MRB_METHOD(Klass##Set##PropName) \ @@ -194,7 +188,6 @@ defineClass(mrb_state *mrb, const char *name) MRB_METHOD(Klass##Get##PropName) \ { \ Klass *k = getPrivateData(mrb, self); \ - DEF_PROP_CHK_DISP \ return mrb_##conv_t##_value(k->get##PropName()); \ } \ MRB_METHOD(Klass##Set##PropName) \ @@ -215,6 +208,7 @@ defineClass(mrb_state *mrb, const char *name) #define DEF_PROP_B(Klass, PropName) \ DEF_PROP(Klass, mrb_bool, PropName, "b", bool) +// FIXME: use initialize_copy #define CLONE_FUN(Klass) \ MRB_METHOD(Klass##Clone) \ { \ @@ -252,19 +246,33 @@ getSym(mrb_state *mrb, CommonSymbol sym) return getMrbData(mrb)->symbols[sym]; } -template -inline T * +void +raiseDisposedAccess(mrb_state *mrb, mrb_value self); + +inline void checkDisposed(mrb_state *mrb, mrb_value self) +{ + if (!DATA_PTR(self)) + raiseDisposedAccess(mrb, self); +} + +template +inline C * getPrivateData(mrb_state *mrb, mrb_value self) { - (void) mrb; - return static_cast(DATA_PTR(self)); + C *c = static_cast(DATA_PTR(self)); + + if (!c) + raiseDisposedAccess(mrb, self); + + return c; } template inline T * getPrivateDataCheck(mrb_state *mrb, mrb_value obj, const mrb_data_type &type) { - return static_cast(mrb_check_datatype(mrb, obj, &type)); + void *ptr = mrb_check_datatype(mrb, obj, &type); + return static_cast(ptr); } inline void diff --git a/binding-mruby/bitmap-binding.cpp b/binding-mruby/bitmap-binding.cpp index cfb93e5..f6dd714 100644 --- a/binding-mruby/bitmap-binding.cpp +++ b/binding-mruby/bitmap-binding.cpp @@ -26,8 +26,6 @@ #include "binding-util.h" #include "binding-types.h" -#define DISP_CLASS_NAME "bitmap" - DEF_TYPE(Bitmap); MRB_METHOD(bitmapInitialize) @@ -111,7 +109,7 @@ MRB_METHOD(bitmapBlt) src = getPrivateDataCheck(mrb, srcObj, BitmapType); srcRect = getPrivateDataCheck(mrb, srcRectObj, RectType); - GUARD_EXC( b->blt(x, y, *src, srcRect->toIntRect(), opacity); ) + GUARD_EXC( b->blt(x, y, src, srcRect->toIntRect(), opacity); ) return mrb_nil_value(); } @@ -134,7 +132,7 @@ MRB_METHOD(bitmapStretchBlt) destRect = getPrivateDataCheck(mrb, destRectObj, RectType); srcRect = getPrivateDataCheck(mrb, srcRectObj, RectType); - GUARD_EXC( b->stretchBlt(destRect->toIntRect(), *src, srcRect->toIntRect(), opacity); ) + GUARD_EXC( b->stretchBlt(destRect->toIntRect(), src, srcRect->toIntRect(), opacity); ) return mrb_nil_value(); } @@ -277,8 +275,7 @@ MRB_METHOD(bitmapTextSize) MRB_METHOD(bitmapGetFont) { - Bitmap *b = getPrivateData(mrb, self); - checkDisposed(mrb, b, "bitmap"); + checkDisposed(mrb, self); return getProperty(mrb, self, CSfont); } diff --git a/binding-mruby/disposable-binding.h b/binding-mruby/disposable-binding.h index 762124f..646ffce 100644 --- a/binding-mruby/disposable-binding.h +++ b/binding-mruby/disposable-binding.h @@ -25,14 +25,60 @@ #include "disposable.h" #include "binding-util.h" +#include "mruby/array.h" + #include +/* 'Children' are disposables that are disposed together + * with their parent. Currently this is only used by Viewport + * in RGSS1. + * FIXME: Disable this behavior when RGSS2 or 3 */ +inline void +disposableAddChild(mrb_state *mrb, mrb_value disp, mrb_value child) +{ + mrb_sym sym = getMrbData(mrb)->symbols[CSchildren]; + mrb_value children = mrb_iv_get(mrb, disp, sym); + + if (mrb_nil_p(children)) + { + children = mrb_ary_new(mrb); + mrb_iv_set(mrb, disp, sym, children); + } + + /* Assumes children are never removed until destruction */ + mrb_ary_push(mrb, children, child); +} + +inline void +disposableDisposeChildren(mrb_state *mrb, mrb_value disp) +{ + MrbData *mrbData = getMrbData(mrb); + mrb_value children = mrb_iv_get(mrb, disp, mrbData->symbols[CSchildren]); + + if (mrb_nil_p(children)) + return; + + for (mrb_int i = 0; i < RARRAY_LEN(children); ++i) + mrb_funcall_argv(mrb, mrb_ary_entry(children, i), + mrbData->symbols[CSdispose], 0, 0); +} + template MRB_METHOD(disposableDispose) { - Disposable *d = getPrivateData(mrb, self); + C *c = static_cast(DATA_PTR(self)); - d->dispose(); + /* Nothing to do if already disposed */ + if (!c) + return mrb_nil_value(); + + /* Inform core */ + c->wasDisposed(); + + disposableDisposeChildren(mrb, self); + + delete c; + DATA_PTR(self) = 0; return mrb_nil_value(); } @@ -40,9 +86,9 @@ MRB_METHOD(disposableDispose) template MRB_METHOD(disposableDisposed) { - Disposable *d = getPrivateData(mrb, self); + MRB_UNUSED_PARAM; - return mrb_bool_value(d->isDisposed()); + return mrb_bool_value(DATA_PTR(self) == 0); } template @@ -52,13 +98,4 @@ static void disposableBindingInit(mrb_state *mrb, RClass *klass) mrb_define_method(mrb, klass, "disposed?", disposableDisposed, MRB_ARGS_NONE()); } -inline void checkDisposed(mrb_state *mrb, Disposable *d, const char *klassName) -{ - MrbData *data = getMrbData(mrb); - - if (d->isDisposed()) - mrb_raisef(mrb, data->exc[RGSS], "disposed %S", - mrb_str_new_static(mrb, klassName, strlen(klassName))); -} - #endif // DISPOSABLEBINDING_H diff --git a/binding-mruby/font-binding.cpp b/binding-mruby/font-binding.cpp index c5b82d7..5d921d8 100644 --- a/binding-mruby/font-binding.cpp +++ b/binding-mruby/font-binding.cpp @@ -78,9 +78,6 @@ MRB_METHOD(FontSetName) return name; } -#undef DEF_PROP_CHK_DISP -#define DEF_PROP_CHK_DISP - DEF_PROP_I(Font, Size) DEF_PROP_B(Font, Bold) DEF_PROP_B(Font, Italic) diff --git a/binding-mruby/plane-binding.cpp b/binding-mruby/plane-binding.cpp index 0903364..430250b 100644 --- a/binding-mruby/plane-binding.cpp +++ b/binding-mruby/plane-binding.cpp @@ -43,8 +43,6 @@ MRB_METHOD(planeInitialize) return self; } -#define DISP_CLASS_NAME "plane" - DEF_PROP_OBJ(Plane, Bitmap, Bitmap, CSbitmap) DEF_PROP_OBJ(Plane, Color, Color, CScolor) DEF_PROP_OBJ(Plane, Tone, Tone, CStone) diff --git a/binding-mruby/sprite-binding.cpp b/binding-mruby/sprite-binding.cpp index 8542247..a25e91e 100644 --- a/binding-mruby/sprite-binding.cpp +++ b/binding-mruby/sprite-binding.cpp @@ -47,8 +47,6 @@ MRB_METHOD(spriteInitialize) return self; } -#define DISP_CLASS_NAME "sprite" - DEF_PROP_OBJ_NIL(Sprite, Bitmap, Bitmap, CSbitmap) DEF_PROP_OBJ(Sprite, Rect, SrcRect, CSsrc_rect) DEF_PROP_OBJ(Sprite, Color, Color, CScolor) diff --git a/binding-mruby/tilemap-binding.cpp b/binding-mruby/tilemap-binding.cpp index 78f3e6d..e208275 100644 --- a/binding-mruby/tilemap-binding.cpp +++ b/binding-mruby/tilemap-binding.cpp @@ -118,13 +118,9 @@ MRB_METHOD(tilemapUpdate) return mrb_nil_value(); } -#define DISP_CLASS_NAME "tilemap" - MRB_METHOD(tilemapGetViewport) { - Tilemap *t = getPrivateData(mrb, self); - - checkDisposed(mrb, t, DISP_CLASS_NAME); + checkDisposed(mrb, self); return getProperty(mrb, self, CSviewport); } diff --git a/binding-mruby/viewport-binding.cpp b/binding-mruby/viewport-binding.cpp index 728bf6f..0e97c34 100644 --- a/binding-mruby/viewport-binding.cpp +++ b/binding-mruby/viewport-binding.cpp @@ -68,8 +68,6 @@ MRB_METHOD(viewportInitialize) return self; } -#define DISP_CLASS_NAME "viewport" - DEF_PROP_OBJ(Viewport, Rect, Rect, CSrect) DEF_PROP_OBJ(Viewport, Color, Color, CScolor) DEF_PROP_OBJ(Viewport, Tone, Tone, CStone) diff --git a/binding-mruby/viewportelement-binding.h b/binding-mruby/viewportelement-binding.h index b362a1e..a4ea09c 100644 --- a/binding-mruby/viewportelement-binding.h +++ b/binding-mruby/viewportelement-binding.h @@ -27,13 +27,12 @@ #include "binding-types.h" #include "sceneelement-binding.h" +#include "disposable-binding.h" template MRB_METHOD(viewportElementGetViewport) { - ViewportElement *ve = getPrivateData(mrb, self); - - GUARD_EXC( ve->aboutToAccess(); ) + checkDisposed(mrb, self); return getProperty(mrb, self, CSviewport); } @@ -49,7 +48,10 @@ viewportElementInitialize(mrb_state *mrb, mrb_value self) mrb_get_args(mrb, "|o", &viewportObj); if (!mrb_nil_p(viewportObj)) + { viewport = getPrivateDataCheck(mrb, viewportObj, ViewportType); + disposableAddChild(mrb, viewportObj, self); + } /* Construct object */ C *ve = new C(viewport); diff --git a/binding-mruby/window-binding.cpp b/binding-mruby/window-binding.cpp index 49a1414..ac2ece5 100644 --- a/binding-mruby/window-binding.cpp +++ b/binding-mruby/window-binding.cpp @@ -49,8 +49,6 @@ MRB_METHOD(windowUpdate) return mrb_nil_value(); } -#define DISP_CLASS_NAME "window" - DEF_PROP_OBJ_NIL(Window, Bitmap, Windowskin, CSwindowskin) DEF_PROP_OBJ_NIL(Window, Bitmap, Contents, CScontents) DEF_PROP_OBJ(Window, Rect, CursorRect, CScursor_rect) diff --git a/src/bitmap.cpp b/src/bitmap.cpp index c6b920a..a62cee4 100644 --- a/src/bitmap.cpp +++ b/src/bitmap.cpp @@ -44,8 +44,6 @@ #include "font.h" #include "eventthread.h" -#define DISP_CLASS_NAME "bitmap" - #define GUARD_MEGA \ { \ if (p->megaSurface) \ @@ -292,18 +290,21 @@ Bitmap::Bitmap(const Bitmap &other) p->gl = shState->texPool().request(other.width(), other.height()); - blt(0, 0, other, rect()); + blt(0, 0, &other, rect()); } Bitmap::~Bitmap() { - dispose(); + if (p->megaSurface) + SDL_FreeSurface(p->megaSurface); + else + shState->texPool().release(p->gl); + + delete p; } int Bitmap::width() const { - GUARD_DISPOSED; - if (p->megaSurface) return p->megaSurface->w; @@ -312,8 +313,6 @@ int Bitmap::width() const int Bitmap::height() const { - GUARD_DISPOSED; - if (p->megaSurface) return p->megaSurface->h; @@ -326,45 +325,49 @@ IntRect Bitmap::rect() const } void Bitmap::blt(int x, int y, - const Bitmap &source, IntRect rect, + const Bitmap *source, IntRect rect, int opacity) { + if (!source) + return; + // FIXME: RGSS allows the source rect to both lie outside // the bitmap rect and be inverted in both directions; // clamping only covers a subset of these cases (and // doesn't fix anything for a direct stretch_blt call). /* Clamp rect to source bitmap size */ - if (rect.x + rect.w > source.width()) - rect.w = source.width() - rect.x; + if (rect.x + rect.w > source->width()) + rect.w = source->width() - rect.x; - if (rect.y + rect.h > source.height()) - rect.h = source.height() - rect.y; + if (rect.y + rect.h > source->height()) + rect.h = source->height() - rect.y; stretchBlt(IntRect(x, y, rect.w, rect.h), source, rect, opacity); } void Bitmap::stretchBlt(const IntRect &destRect, - const Bitmap &source, const IntRect &sourceRect, + const Bitmap *source, const IntRect &sourceRect, int opacity) { - GUARD_DISPOSED; - GUARD_MEGA; + if (!source) + return; + opacity = clamp(opacity, 0, 255); if (opacity == 0) return; - if (source.megaSurface()) + if (source->megaSurface()) { /* Don't do transparent blits for now */ if (opacity < 255) - source.ensureNonMega(); + source->ensureNonMega(); - SDL_Surface *srcSurf = source.megaSurface(); + SDL_Surface *srcSurf = source->megaSurface(); SDL_Rect srcRect = sourceRect; SDL_Rect dstRect = destRect; @@ -411,7 +414,7 @@ void Bitmap::stretchBlt(const IntRect &destRect, { /* Fast blit */ GLMeta::blitBegin(p->gl); - GLMeta::blitSource(source.p->gl); + GLMeta::blitSource(source->p->gl); GLMeta::blitRectangle(sourceRect, destRect); GLMeta::blitEnd(); } @@ -427,10 +430,10 @@ void Bitmap::stretchBlt(const IntRect &destRect, GLMeta::blitRectangle(destRect, Vec2i()); GLMeta::blitEnd(); - FloatRect bltSubRect((float) sourceRect.x / source.width(), - (float) sourceRect.y / source.height(), - ((float) source.width() / sourceRect.w) * ((float) destRect.w / gpTex.width), - ((float) source.height() / sourceRect.h) * ((float) destRect.h / gpTex.height)); + FloatRect bltSubRect((float) sourceRect.x / source->width(), + (float) sourceRect.y / source->height(), + ((float) source->width() / sourceRect.w) * ((float) destRect.w / gpTex.width), + ((float) source->height() / sourceRect.h) * ((float) destRect.h / gpTex.height)); BltShader &shader = shState->shaders().blt; shader.bind(); @@ -442,7 +445,7 @@ void Bitmap::stretchBlt(const IntRect &destRect, quad.setTexPosRect(sourceRect, destRect); quad.setColor(Vec4(1, 1, 1, normOpacity)); - source.p->bindTexture(shader); + source->p->bindTexture(shader); p->bindFBO(); p->pushSetViewport(shader); @@ -465,8 +468,6 @@ void Bitmap::fillRect(int x, int y, void Bitmap::fillRect(const IntRect &rect, const Vec4 &color) { - GUARD_DISPOSED; - GUARD_MEGA; p->fillRect(rect, color); @@ -495,8 +496,6 @@ void Bitmap::gradientFillRect(const IntRect &rect, const Vec4 &color1, const Vec4 &color2, bool vertical) { - GUARD_DISPOSED; - GUARD_MEGA; SimpleColorShader &shader = shState->shaders().simpleColor; @@ -541,8 +540,6 @@ void Bitmap::clearRect(int x, int y, int width, int height) void Bitmap::clearRect(const IntRect &rect) { - GUARD_DISPOSED; - GUARD_MEGA; p->fillRect(rect, Vec4()); @@ -552,8 +549,6 @@ void Bitmap::clearRect(const IntRect &rect) void Bitmap::blur() { - GUARD_DISPOSED; - GUARD_MEGA; Quad &quad = shState->gpQuad(); @@ -597,8 +592,6 @@ void Bitmap::blur() void Bitmap::radialBlur(int angle, int divisions) { - GUARD_DISPOSED; - GUARD_MEGA; angle = clamp(angle, 0, 359); @@ -694,8 +687,6 @@ void Bitmap::radialBlur(int angle, int divisions) void Bitmap::clear() { - GUARD_DISPOSED; - GUARD_MEGA; p->bindFBO(); @@ -713,8 +704,6 @@ void Bitmap::clear() Color Bitmap::getPixel(int x, int y) const { - GUARD_DISPOSED; - GUARD_MEGA; if (x < 0 || y < 0 || x >= width() || y >= height()) @@ -745,8 +734,6 @@ Color Bitmap::getPixel(int x, int y) const void Bitmap::setPixel(int x, int y, const Color &color) { - GUARD_DISPOSED; - GUARD_MEGA; uint8_t pixel[] = @@ -767,8 +754,6 @@ void Bitmap::setPixel(int x, int y, const Color &color) void Bitmap::hueChange(int hue) { - GUARD_DISPOSED; - GUARD_MEGA; if ((hue % 360) == 0) @@ -815,8 +800,6 @@ void Bitmap::drawText(int x, int y, void Bitmap::drawText(const IntRect &rect, const char *str, int align) { - GUARD_DISPOSED; - GUARD_MEGA; if (*str == '\0') @@ -1042,8 +1025,6 @@ static uint16_t utf8_to_ucs2(const char *_input, IntRect Bitmap::textSize(const char *str) { - GUARD_DISPOSED; - GUARD_MEGA; TTF_Font *font = p->font->getSdlFont(); @@ -1077,9 +1058,6 @@ SDL_Surface *Bitmap::megaSurface() const void Bitmap::ensureNonMega() const { - if (isDisposed()) - return; - GUARD_MEGA; } @@ -1092,13 +1070,3 @@ void Bitmap::taintArea(const IntRect &rect) { p->addTaintedArea(rect); } - -void Bitmap::releaseResources() -{ - if (p->megaSurface) - SDL_FreeSurface(p->megaSurface); - else - shState->texPool().release(p->gl); - - delete p; -} diff --git a/src/bitmap.h b/src/bitmap.h index fd4d8c6..d481fd5 100644 --- a/src/bitmap.h +++ b/src/bitmap.h @@ -49,11 +49,11 @@ public: IntRect rect() const; void blt(int x, int y, - const Bitmap &source, IntRect rect, + const Bitmap *source, IntRect rect, int opacity = 255); void stretchBlt(const IntRect &destRect, - const Bitmap &source, const IntRect &sourceRect, + const Bitmap *source, const IntRect &sourceRect, int opacity = 255); void fillRect(int x, int y, @@ -119,8 +119,6 @@ public: sigc::signal modified; private: - void releaseResources(); - BitmapPrivate *p; }; diff --git a/src/disposable.h b/src/disposable.h index 9ecc971..0704b17 100644 --- a/src/disposable.h +++ b/src/disposable.h @@ -25,39 +25,63 @@ #include "exception.h" #include +#include class Disposable { public: - Disposable() - : disposed(false) - {} - - virtual ~Disposable() {} - - void dispose() - { - if (disposed) - return; - - releaseResources(); - disposed = true; - wasDisposed(); - } - - bool isDisposed() const { return disposed; } - sigc::signal wasDisposed; - -protected: - virtual void releaseResources() = 0; - -private: - bool disposed; }; -/* Every cpp needs to define DISP_CLASS_NAME for itself (lowercase) */ -#define GUARD_DISPOSED \ -{ if (isDisposed()) throw Exception(Exception::RGSSError, "disposed %s", DISP_CLASS_NAME); } +/* A helper struct which monitors the dispose signal of + * properties, and automatically sets the prop pointer to + * null. Can call an optional notify method when prop is + * nulled */ +template +struct DisposeWatch +{ + typedef void (C::*NotifyFun)(); + + /* The object owning the prop (and this helper) */ + C *owner; + /* Optional notify method */ + const NotifyFun notify; + /* Location of the prop pointer inside the owner */ + P *&propLocation; + sigc::connection dispCon; + + DisposeWatch(C *owner, P *&propLocation, NotifyFun notify = 0) + : owner(owner), + notify(notify), + propLocation(propLocation) + {} + + ~DisposeWatch() + { + dispCon.disconnect(); + } + + /* Call this when a new object was set for the prop */ + void update(Disposable *prop) + { + dispCon.disconnect(); + + if (!prop) + return; + + dispCon = prop->wasDisposed.connect + (sigc::mem_fun(this, &DisposeWatch::onDisposed)); + } + +private: + void onDisposed() + { + dispCon.disconnect(); + propLocation = 0; + + if (notify) + (owner->*notify)(); + } +}; #endif // DISPOSABLE_H diff --git a/src/plane.cpp b/src/plane.cpp index 622b1c7..2f6ee55 100644 --- a/src/plane.cpp +++ b/src/plane.cpp @@ -45,6 +45,8 @@ static float fwrap(float value, float range) struct PlanePrivate { Bitmap *bitmap; + DisposeWatch bitmapWatch; + NormValue opacity; BlendType blendType; Color *color; @@ -65,6 +67,7 @@ struct PlanePrivate PlanePrivate() : bitmap(0), + bitmapWatch(this, bitmap), opacity(255), blendType(BlendNormal), color(&tmp.color), @@ -153,8 +156,6 @@ Plane::Plane(Viewport *viewport) onGeometryChange(scene->getGeometry()); } -#define DISP_CLASS_NAME "plane" - DEF_ATTR_RD_SIMPLE(Plane, Bitmap, Bitmap*, p->bitmap) DEF_ATTR_RD_SIMPLE(Plane, OX, int, p->ox) DEF_ATTR_RD_SIMPLE(Plane, OY, int, p->oy) @@ -168,14 +169,15 @@ DEF_ATTR_SIMPLE(Plane, Tone, Tone*, p->tone) Plane::~Plane() { - dispose(); + unlink(); + + delete p; } void Plane::setBitmap(Bitmap *value) { - GUARD_DISPOSED; - p->bitmap = value; + p->bitmapWatch.update(value); if (!value) return; @@ -185,8 +187,6 @@ void Plane::setBitmap(Bitmap *value) void Plane::setOX(int value) { - GUARD_DISPOSED; - if (p->ox == value) return; @@ -196,8 +196,6 @@ void Plane::setOX(int value) void Plane::setOY(int value) { - GUARD_DISPOSED; - if (p->oy == value) return; @@ -207,8 +205,6 @@ void Plane::setOY(int value) void Plane::setZoomX(float value) { - GUARD_DISPOSED; - if (p->zoomX == value) return; @@ -218,8 +214,6 @@ void Plane::setZoomX(float value) void Plane::setZoomY(float value) { - GUARD_DISPOSED; - if (p->zoomY == value) return; @@ -229,8 +223,6 @@ void Plane::setZoomY(float value) void Plane::setBlendType(int value) { - GUARD_DISPOSED - switch (value) { default : @@ -252,9 +244,6 @@ void Plane::draw() if (!p->bitmap) return; - if (p->bitmap->isDisposed()) - return; - if (!p->opacity) return; @@ -307,16 +296,3 @@ void Plane::onGeometryChange(const Scene::Geometry &geo) p->sceneGeo = geo; p->quadSourceDirty = true; } - -void Plane::aboutToAccess() const -{ - GUARD_DISPOSED -} - - -void Plane::releaseResources() -{ - unlink(); - - delete p; -} diff --git a/src/plane.h b/src/plane.h index 904923c..9f4cd25 100644 --- a/src/plane.h +++ b/src/plane.h @@ -52,9 +52,6 @@ private: void draw(); void onGeometryChange(const Scene::Geometry &); - void aboutToAccess() const; - - void releaseResources(); }; #endif // PLANE_H diff --git a/src/scene.cpp b/src/scene.cpp index d7706cf..55e5232 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -143,15 +143,11 @@ void SceneElement::setScene(Scene &scene) int SceneElement::getZ() const { - aboutToAccess(); - return z; } void SceneElement::setZ(int value) { - aboutToAccess(); - if (z == value) return; @@ -161,15 +157,11 @@ void SceneElement::setZ(int value) bool SceneElement::getVisible() const { - aboutToAccess(); - return visible; } void SceneElement::setVisible(bool value) { - aboutToAccess(); - visible = value; } diff --git a/src/scene.h b/src/scene.h index 79a8fda..9aa916c 100644 --- a/src/scene.h +++ b/src/scene.h @@ -78,10 +78,6 @@ public: DECL_ATTR_VIRT( Z, int ) DECL_ATTR_VIRT( Visible, bool ) - /* Disposable classes reimplement this to - * check if they're disposed before access */ - virtual void aboutToAccess() const {} - protected: /* A bit about OpenGL state: * diff --git a/src/sprite.cpp b/src/sprite.cpp index b5888c1..a2f9197 100644 --- a/src/sprite.cpp +++ b/src/sprite.cpp @@ -43,6 +43,7 @@ struct SpritePrivate { Bitmap *bitmap; + DisposeWatch bitmapWatch; Quad quad; Transform trans; @@ -88,6 +89,7 @@ struct SpritePrivate SpritePrivate() : bitmap(0), + bitmapWatch(this, bitmap), srcRect(&tmp.rect), mirrored(false), bushDepth(0), @@ -165,9 +167,6 @@ struct SpritePrivate if (!bitmap) return; - if (bitmap->isDisposed()) - return; - if (!opacity) return; @@ -310,10 +309,10 @@ Sprite::Sprite(Viewport *viewport) Sprite::~Sprite() { - dispose(); -} + unlink(); -#define DISP_CLASS_NAME "sprite" + delete p; +} DEF_ATTR_RD_SIMPLE(Sprite, Bitmap, Bitmap*, p->bitmap) DEF_ATTR_RD_SIMPLE(Sprite, SrcRect, Rect*, p->srcRect) @@ -344,12 +343,11 @@ DEF_ATTR_RD_SIMPLE(Sprite, WavePhase, float, p->wave.phase) void Sprite::setBitmap(Bitmap *bitmap) { - GUARD_DISPOSED - if (p->bitmap == bitmap) return; p->bitmap = bitmap; + p->bitmapWatch.update(bitmap); if (!bitmap) return; @@ -367,8 +365,6 @@ void Sprite::setBitmap(Bitmap *bitmap) void Sprite::setSrcRect(Rect *rect) { - GUARD_DISPOSED - if (p->srcRect == rect) return; @@ -381,8 +377,6 @@ void Sprite::setSrcRect(Rect *rect) void Sprite::setX(int value) { - GUARD_DISPOSED - if (p->trans.getPosition().x == value) return; @@ -391,8 +385,6 @@ void Sprite::setX(int value) void Sprite::setY(int value) { - GUARD_DISPOSED - if (p->trans.getPosition().y == value) return; @@ -405,8 +397,6 @@ void Sprite::setY(int value) void Sprite::setOX(int value) { - GUARD_DISPOSED - if (p->trans.getOrigin().x == value) return; @@ -415,8 +405,6 @@ void Sprite::setOX(int value) void Sprite::setOY(int value) { - GUARD_DISPOSED - if (p->trans.getOrigin().y == value) return; @@ -425,8 +413,6 @@ void Sprite::setOY(int value) void Sprite::setZoomX(float value) { - GUARD_DISPOSED - if (p->trans.getScale().x == value) return; @@ -435,8 +421,6 @@ void Sprite::setZoomX(float value) void Sprite::setZoomY(float value) { - GUARD_DISPOSED - if (p->trans.getScale().y == value) return; @@ -450,8 +434,6 @@ void Sprite::setZoomY(float value) void Sprite::setAngle(float value) { - GUARD_DISPOSED - if (p->trans.getRotation() == value) return; @@ -460,8 +442,6 @@ void Sprite::setAngle(float value) void Sprite::setMirror(bool mirrored) { - GUARD_DISPOSED - if (p->mirrored == mirrored) return; @@ -471,8 +451,6 @@ void Sprite::setMirror(bool mirrored) void Sprite::setBushDepth(int value) { - GUARD_DISPOSED - if (p->bushDepth == value) return; @@ -482,8 +460,6 @@ void Sprite::setBushDepth(int value) void Sprite::setBlendType(int type) { - GUARD_DISPOSED - switch (type) { default : @@ -504,7 +480,6 @@ void Sprite::setBlendType(int type) #define DEF_WAVE_SETTER(Name, name, type) \ void Sprite::setWave##Name(type value) \ { \ - GUARD_DISPOSED; \ if (p->wave.name == value) \ return; \ p->wave.name = value; \ @@ -529,14 +504,6 @@ void Sprite::update() #endif -/* Disposable */ -void Sprite::releaseResources() -{ - unlink(); - - delete p; -} - /* SceneElement */ void Sprite::draw() { diff --git a/src/sprite.h b/src/sprite.h index 22ee697..ea1b440 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -75,8 +75,6 @@ private: void draw(); void onGeometryChange(const Scene::Geometry &); - - void releaseResources(); }; #endif // SPRITE_H diff --git a/src/tilemap.cpp b/src/tilemap.cpp index cef54d9..09d5136 100644 --- a/src/tilemap.cpp +++ b/src/tilemap.cpp @@ -38,6 +38,7 @@ #include "tileatlas.h" #include +#include #include #include @@ -241,6 +242,8 @@ struct TilemapPrivate Bitmap *autotiles[autotileCount]; Bitmap *tileset; + DisposeWatch tilesetWatch; + Table *mapData; Table *flashData; Table *priorities; @@ -352,6 +355,7 @@ struct TilemapPrivate TilemapPrivate(Viewport *viewport) : viewport(viewport), tileset(0), + tilesetWatch(this, tileset), mapData(0), flashData(0), priorities(0), @@ -439,7 +443,7 @@ struct TilemapPrivate void updateAtlasInfo() { - if (!tileset || tileset->isDisposed()) + if (!tileset) { atlas.size = Vec2i(); return; @@ -468,9 +472,6 @@ struct TilemapPrivate if (!autotiles[i]) continue; - if (autotiles[i]->isDisposed()) - continue; - if (autotiles[i]->megaSurface()) continue; @@ -516,15 +517,22 @@ struct TilemapPrivate flashDirty = true; } + void onAutotileDisposed(int i) + { + /* RMXP actually crashes if an active autotile bitmap is disposed.. + * let's not crash ourselves, for consistency's sake */ + autotiles[i] = 0; + autotilesCon[i].disconnect(); + autotilesDispCon[i].disconnect(); + atlasDirty = true; + } + /* Checks for the minimum amount of data needed to display */ bool verifyResources() { if (!tileset) return false; - if (tileset->isDisposed()) - return false; - if (!mapData) return false; @@ -1211,7 +1219,7 @@ void Tilemap::Autotiles::set(int i, Bitmap *bitmap) p->autotilesDispCon[i].disconnect(); p->autotilesDispCon[i] = bitmap->wasDisposed.connect - (sigc::mem_fun(p, &TilemapPrivate::invalidateAtlasContents)); + (sigc::bind(sigc::mem_fun(p, &TilemapPrivate::onAutotileDisposed), i)); p->updateAutotileInfo(); } @@ -1232,7 +1240,7 @@ Tilemap::Tilemap(Viewport *viewport) Tilemap::~Tilemap() { - dispose(); + delete p; } void Tilemap::update() @@ -1259,8 +1267,6 @@ Tilemap::Autotiles &Tilemap::getAutotiles() const return p->autotilesProxy; } -#define DISP_CLASS_NAME "tilemap" - DEF_ATTR_RD_SIMPLE(Tilemap, Viewport, Viewport*, p->viewport) DEF_ATTR_RD_SIMPLE(Tilemap, Tileset, Bitmap*, p->tileset) DEF_ATTR_RD_SIMPLE(Tilemap, MapData, Table*, p->mapData) @@ -1274,8 +1280,6 @@ DEF_ATTR_RD_SIMPLE(Tilemap, OY, int, p->offset.y) void Tilemap::setViewport(Viewport *value) { - GUARD_DISPOSED - if (p->viewport == value) return; @@ -1294,12 +1298,14 @@ void Tilemap::setViewport(Viewport *value) void Tilemap::setTileset(Bitmap *value) { - GUARD_DISPOSED - if (p->tileset == value) return; p->tileset = value; + p->tilesetWatch.update(value); + + if (!value) + return; p->invalidateAtlasSize(); p->tilesetCon.disconnect(); @@ -1311,13 +1317,14 @@ void Tilemap::setTileset(Bitmap *value) void Tilemap::setMapData(Table *value) { - GUARD_DISPOSED - if (p->mapData == value) return; p->mapData = value; + if (!value) + return; + p->invalidateBuffers(); p->mapDataCon.disconnect(); p->mapDataCon = value->modified.connect @@ -1326,13 +1333,14 @@ void Tilemap::setMapData(Table *value) void Tilemap::setFlashData(Table *value) { - GUARD_DISPOSED - if (p->flashData == value) return; p->flashData = value; + if (!value) + return; + p->invalidateFlash(); p->flashDataCon.disconnect(); p->flashDataCon = value->modified.connect @@ -1341,13 +1349,14 @@ void Tilemap::setFlashData(Table *value) void Tilemap::setPriorities(Table *value) { - GUARD_DISPOSED - if (p->priorities == value) return; p->priorities = value; + if (!value) + return; + p->invalidateBuffers(); p->prioritiesCon.disconnect(); p->prioritiesCon = value->modified.connect @@ -1356,8 +1365,6 @@ void Tilemap::setPriorities(Table *value) void Tilemap::setVisible(bool value) { - GUARD_DISPOSED - if (p->visible == value) return; @@ -1373,8 +1380,6 @@ void Tilemap::setVisible(bool value) void Tilemap::setOX(int value) { - GUARD_DISPOSED - if (p->offset.x == value) return; @@ -1385,8 +1390,6 @@ void Tilemap::setOX(int value) void Tilemap::setOY(int value) { - GUARD_DISPOSED - if (p->offset.y == value) return; @@ -1395,9 +1398,3 @@ void Tilemap::setOY(int value) p->zOrderDirty = true; p->mapViewportDirty = true; } - - -void Tilemap::releaseResources() -{ - delete p; -} diff --git a/src/tilemap.h b/src/tilemap.h index fc9624e..ea27884 100644 --- a/src/tilemap.h +++ b/src/tilemap.h @@ -68,8 +68,6 @@ public: private: TilemapPrivate *p; - - void releaseResources(); }; #endif // TILEMAP_H diff --git a/src/util.h b/src/util.h index 7361532..3f63b5e 100644 --- a/src/util.h +++ b/src/util.h @@ -116,13 +116,9 @@ inline bool contains(const C &c, const V &v) type get##name() const { return loc; } \ void set##name(type value) { loc = value; } -/* Undef this if not needed */ -#define CHK_DISP GUARD_DISPOSED - #define DEF_ATTR_RD_SIMPLE_DETAILED(klass, name, type, location, keyword1) \ type klass :: get##name() keyword1 \ { \ - CHK_DISP \ return location; \ } @@ -130,7 +126,6 @@ inline bool contains(const C &c, const V &v) DEF_ATTR_RD_SIMPLE_DETAILED(klass, name, type, location, keyword1) \ void klass :: set##name(type value) \ { \ - CHK_DISP \ location = value; \ } diff --git a/src/viewport.cpp b/src/viewport.cpp index bd17687..114924b 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -125,10 +125,10 @@ void Viewport::initViewport(int x, int y, int width, int height) Viewport::~Viewport() { - dispose(); -} + unlink(); -#define DISP_CLASS_NAME "viewport" + delete p; +} DEF_ATTR_RD_SIMPLE(Viewport, OX, int, geometry.xOrigin) DEF_ATTR_RD_SIMPLE(Viewport, OY, int, geometry.yOrigin) @@ -139,8 +139,6 @@ DEF_ATTR_SIMPLE(Viewport, Tone, Tone*, p->tone) void Viewport::setOX(int value) { - GUARD_DISPOSED - if (geometry.xOrigin == value) return; @@ -150,8 +148,6 @@ void Viewport::setOX(int value) void Viewport::setOY(int value) { - GUARD_DISPOSED - if (geometry.yOrigin == value) return; @@ -161,8 +157,6 @@ void Viewport::setOY(int value) void Viewport::setRect(Rect *value) { - GUARD_DISPOSED - if (p->rect == value) return; @@ -210,14 +204,6 @@ void Viewport::onGeometryChange(const Geometry &geo) p->recomputeOnScreen(); } -/* Disposable */ -void Viewport::releaseResources() -{ - unlink(); - - delete p; -} - ViewportElement::ViewportElement(Viewport *viewport, int z) : SceneElement(viewport ? *viewport : *shState->screen(), z), diff --git a/src/viewport.h b/src/viewport.h index cb10688..4c60cbb 100644 --- a/src/viewport.h +++ b/src/viewport.h @@ -51,8 +51,6 @@ private: void onGeometryChange(const Geometry &); bool isEffectiveViewport(Rect *&, Color *&, Tone *&) const; - void releaseResources(); - ViewportPrivate *p; friend struct ViewportPrivate; diff --git a/src/window.cpp b/src/window.cpp index 344407e..4c21105 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -169,7 +169,11 @@ struct QuadChunk struct WindowPrivate { Bitmap *windowskin; + DisposeWatch windowskinWatch; + Bitmap *contents; + DisposeWatch contentsWatch; + bool bgStretch; Rect *cursorRect; bool active; @@ -246,7 +250,9 @@ struct WindowPrivate WindowPrivate(Viewport *viewport = 0) : windowskin(0), + windowskinWatch(this, windowskin), contents(0), + contentsWatch(this, contents, &WindowPrivate::markControlVertDirty), bgStretch(true), cursorRect(&tmp.rect), active(true), @@ -280,7 +286,7 @@ struct WindowPrivate prepareCon.disconnect(); } - void onCursorRectChange() + void markControlVertDirty() { controlsVertDirty = true; } @@ -289,7 +295,7 @@ struct WindowPrivate { cursorRectCon.disconnect(); cursorRectCon = cursorRect->valueChanged.connect - (sigc::mem_fun(this, &WindowPrivate::onCursorRectChange)); + (sigc::mem_fun(this, &WindowPrivate::markControlVertDirty)); } void buildBaseVert() @@ -686,7 +692,11 @@ Window::Window(Viewport *viewport) Window::~Window() { - dispose(); + p->controlsElement.release(); + + unlink(); + + delete p; } void Window::update() @@ -695,8 +705,6 @@ void Window::update() p->stepAnimations(); } -#define DISP_CLASS_NAME "window" - DEF_ATTR_SIMPLE(Window, X, int, p->position.x) DEF_ATTR_SIMPLE(Window, Y, int, p->position.y) @@ -716,9 +724,8 @@ DEF_ATTR_RD_SIMPLE(Window, ContentsOpacity, int, p->contentsOpacity) void Window::setWindowskin(Bitmap *value) { - GUARD_DISPOSED; - p->windowskin = value; + p->windowskinWatch.update(value); if (!value) return; @@ -728,12 +735,11 @@ void Window::setWindowskin(Bitmap *value) void Window::setContents(Bitmap *value) { - GUARD_DISPOSED; - if (p->contents == value) return; p->contents = value; + p->contentsWatch.update(value); p->controlsVertDirty = true; if (!value) @@ -745,8 +751,6 @@ void Window::setContents(Bitmap *value) void Window::setStretch(bool value) { - GUARD_DISPOSED - if (value == p->bgStretch) return; @@ -756,21 +760,17 @@ void Window::setStretch(bool value) void Window::setCursorRect(Rect *value) { - GUARD_DISPOSED - if (p->cursorRect == value) return; p->cursorRect = value; p->refreshCursorRectCon(); - p->onCursorRectChange(); + p->markControlVertDirty(); } void Window::setActive(bool value) { - GUARD_DISPOSED - if (p->active == value) return; @@ -780,8 +780,6 @@ void Window::setActive(bool value) void Window::setPause(bool value) { - GUARD_DISPOSED - if (p->pause == value) return; @@ -793,8 +791,6 @@ void Window::setPause(bool value) void Window::setWidth(int value) { - GUARD_DISPOSED - if (p->size.x == value) return; @@ -804,8 +800,6 @@ void Window::setWidth(int value) void Window::setHeight(int value) { - GUARD_DISPOSED - if (p->size.y == value) return; @@ -815,8 +809,6 @@ void Window::setHeight(int value) void Window::setOX(int value) { - GUARD_DISPOSED - if (p->contentsOffset.x == value) return; @@ -826,8 +818,6 @@ void Window::setOX(int value) void Window::setOY(int value) { - GUARD_DISPOSED - if (p->contentsOffset.y == value) return; @@ -837,8 +827,6 @@ void Window::setOY(int value) void Window::setOpacity(int value) { - GUARD_DISPOSED - if (p->opacity == value) return; @@ -848,8 +836,6 @@ void Window::setOpacity(int value) void Window::setBackOpacity(int value) { - GUARD_DISPOSED - if (p->backOpacity == value) return; @@ -859,8 +845,6 @@ void Window::setBackOpacity(int value) void Window::setContentsOpacity(int value) { - GUARD_DISPOSED - if (p->contentsOpacity == value) return; @@ -897,12 +881,3 @@ void Window::onViewportChange() { p->controlsElement.setScene(*this->scene); } - -void Window::releaseResources() -{ - p->controlsElement.release(); - - unlink(); - - delete p; -} diff --git a/src/window.h b/src/window.h index 57a4a2b..50e88e9 100644 --- a/src/window.h +++ b/src/window.h @@ -65,8 +65,6 @@ private: void setVisible(bool value); void onViewportChange(); - - void releaseResources(); }; #endif // WINDOW_H