Tilemap/VX: Ensure proxy objects don't outlive their parents
Either of these would previously crash (same for VX): tm = Tilemap.new at = tm.autotiles tm = nil GC.start at[0] = Bitmap.new(1, 1) tm = Tilemap.new at = tm.autotiles tm.dispose at[0] = Bitmap.new(1, 1) Funnily, this makes RMXP itself crash too, but crashing is never acceptable except for possibly resource exhaustion.
This commit is contained in:
parent
e9d0d0566b
commit
9758e660c4
|
@ -94,6 +94,10 @@ RB_METHOD(tilemapInitialize)
|
||||||
|
|
||||||
rb_iv_set(autotilesObj, "array", ary);
|
rb_iv_set(autotilesObj, "array", ary);
|
||||||
|
|
||||||
|
/* Circular reference so both objects are always
|
||||||
|
* alive at the same time */
|
||||||
|
rb_iv_set(autotilesObj, "tilemap", self);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,10 @@ RB_METHOD(tilemapVXInitialize)
|
||||||
|
|
||||||
rb_iv_set(autotilesObj, "array", ary);
|
rb_iv_set(autotilesObj, "array", ary);
|
||||||
|
|
||||||
|
/* Circular reference so both objects are always
|
||||||
|
* alive at the same time */
|
||||||
|
rb_iv_set(autotilesObj, "tilemap", self);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@ struct
|
||||||
SYMD(tone),
|
SYMD(tone),
|
||||||
SYMD(rect),
|
SYMD(rect),
|
||||||
SYMD(src_rect),
|
SYMD(src_rect),
|
||||||
|
SYMD(tilemap),
|
||||||
SYMD(tileset),
|
SYMD(tileset),
|
||||||
SYMD(autotiles),
|
SYMD(autotiles),
|
||||||
SYMD(map_data),
|
SYMD(map_data),
|
||||||
|
|
|
@ -42,6 +42,7 @@ enum CommonSymbol
|
||||||
CStone,
|
CStone,
|
||||||
CSrect,
|
CSrect,
|
||||||
CSsrc_rect,
|
CSsrc_rect,
|
||||||
|
CStilemap,
|
||||||
CStileset,
|
CStileset,
|
||||||
CSautotiles,
|
CSautotiles,
|
||||||
CSmap_data,
|
CSmap_data,
|
||||||
|
|
|
@ -93,13 +93,18 @@ MRB_METHOD(tilemapInitialize)
|
||||||
|
|
||||||
wrapProperty(mrb, self, &t->getAutotiles(), CSautotiles, TilemapAutotilesType);
|
wrapProperty(mrb, self, &t->getAutotiles(), CSautotiles, TilemapAutotilesType);
|
||||||
|
|
||||||
mrb_value autotilesObj = mrb_iv_get(mrb, self, getMrbData(mrb)->symbols[CSautotiles]);
|
MrbData &mrbData = *getMrbData(mrb);
|
||||||
|
mrb_value autotilesObj = mrb_iv_get(mrb, self, mrbData.symbols[CSautotiles]);
|
||||||
|
|
||||||
mrb_value ary = mrb_ary_new_capa(mrb, 7);
|
mrb_value ary = mrb_ary_new_capa(mrb, 7);
|
||||||
for (int i = 0; i < 7; ++i)
|
for (int i = 0; i < 7; ++i)
|
||||||
mrb_ary_push(mrb, ary, mrb_nil_value());
|
mrb_ary_push(mrb, ary, mrb_nil_value());
|
||||||
|
|
||||||
mrb_iv_set(mrb, autotilesObj, getMrbData(mrb)->symbols[CSarray], ary);
|
mrb_iv_set(mrb, autotilesObj, mrbData.symbols[CSarray], ary);
|
||||||
|
|
||||||
|
/* Circular reference so both objects are always
|
||||||
|
* alive at the same time */
|
||||||
|
mrb_iv_set(mrb, autotilesObj, mrbData.symbols[CStilemap], self);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
|
@ -241,7 +241,6 @@ struct TilemapPrivate
|
||||||
{
|
{
|
||||||
Viewport *viewport;
|
Viewport *viewport;
|
||||||
|
|
||||||
Tilemap::Autotiles autotilesProxy;
|
|
||||||
Bitmap *autotiles[autotileCount];
|
Bitmap *autotiles[autotileCount];
|
||||||
|
|
||||||
Bitmap *tileset;
|
Bitmap *tileset;
|
||||||
|
@ -1183,6 +1182,9 @@ void ZLayer::finiUpdateZ(ZLayer *prev)
|
||||||
|
|
||||||
void Tilemap::Autotiles::set(int i, Bitmap *bitmap)
|
void Tilemap::Autotiles::set(int i, Bitmap *bitmap)
|
||||||
{
|
{
|
||||||
|
if (!p)
|
||||||
|
return;
|
||||||
|
|
||||||
if (i < 0 || i > autotileCount-1)
|
if (i < 0 || i > autotileCount-1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1206,6 +1208,9 @@ void Tilemap::Autotiles::set(int i, Bitmap *bitmap)
|
||||||
|
|
||||||
Bitmap *Tilemap::Autotiles::get(int i) const
|
Bitmap *Tilemap::Autotiles::get(int i) const
|
||||||
{
|
{
|
||||||
|
if (!p)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (i < 0 || i > autotileCount-1)
|
if (i < 0 || i > autotileCount-1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -1215,7 +1220,7 @@ Bitmap *Tilemap::Autotiles::get(int i) const
|
||||||
Tilemap::Tilemap(Viewport *viewport)
|
Tilemap::Tilemap(Viewport *viewport)
|
||||||
{
|
{
|
||||||
p = new TilemapPrivate(viewport);
|
p = new TilemapPrivate(viewport);
|
||||||
p->autotilesProxy.p = p;
|
atProxy.p = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
Tilemap::~Tilemap()
|
Tilemap::~Tilemap()
|
||||||
|
@ -1244,11 +1249,11 @@ void Tilemap::update()
|
||||||
p->tiles.aniIdx = 0;
|
p->tiles.aniIdx = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Tilemap::Autotiles &Tilemap::getAutotiles() const
|
Tilemap::Autotiles &Tilemap::getAutotiles()
|
||||||
{
|
{
|
||||||
guardDisposed();
|
guardDisposed();
|
||||||
|
|
||||||
return p->autotilesProxy;
|
return atProxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEF_ATTR_RD_SIMPLE(Tilemap, Viewport, Viewport*, p->viewport)
|
DEF_ATTR_RD_SIMPLE(Tilemap, Viewport, Viewport*, p->viewport)
|
||||||
|
@ -1379,4 +1384,5 @@ void Tilemap::setOY(int value)
|
||||||
void Tilemap::releaseResources()
|
void Tilemap::releaseResources()
|
||||||
{
|
{
|
||||||
delete p;
|
delete p;
|
||||||
|
atProxy.p = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ public:
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
Autotiles &getAutotiles() const;
|
Autotiles &getAutotiles();
|
||||||
Viewport *getViewport() const;
|
Viewport *getViewport() const;
|
||||||
|
|
||||||
DECL_ATTR( Tileset, Bitmap* )
|
DECL_ATTR( Tileset, Bitmap* )
|
||||||
|
@ -68,6 +68,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TilemapPrivate *p;
|
TilemapPrivate *p;
|
||||||
|
Autotiles atProxy;
|
||||||
|
|
||||||
void releaseResources();
|
void releaseResources();
|
||||||
const char *klassName() const { return "tilemap"; }
|
const char *klassName() const { return "tilemap"; }
|
||||||
|
|
|
@ -41,7 +41,6 @@
|
||||||
|
|
||||||
struct TilemapVXPrivate : public ViewportElement, TileAtlasVX::Reader
|
struct TilemapVXPrivate : public ViewportElement, TileAtlasVX::Reader
|
||||||
{
|
{
|
||||||
TilemapVX::BitmapArray bitmapsProxy;
|
|
||||||
Bitmap *bitmaps[BM_COUNT];
|
Bitmap *bitmaps[BM_COUNT];
|
||||||
|
|
||||||
Table *mapData;
|
Table *mapData;
|
||||||
|
@ -358,6 +357,9 @@ struct TilemapVXPrivate : public ViewportElement, TileAtlasVX::Reader
|
||||||
|
|
||||||
void TilemapVX::BitmapArray::set(int i, Bitmap *bitmap)
|
void TilemapVX::BitmapArray::set(int i, Bitmap *bitmap)
|
||||||
{
|
{
|
||||||
|
if (!p)
|
||||||
|
return;
|
||||||
|
|
||||||
if (i < 0 || i >= BM_COUNT)
|
if (i < 0 || i >= BM_COUNT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -378,6 +380,9 @@ void TilemapVX::BitmapArray::set(int i, Bitmap *bitmap)
|
||||||
|
|
||||||
Bitmap *TilemapVX::BitmapArray::get(int i) const
|
Bitmap *TilemapVX::BitmapArray::get(int i) const
|
||||||
{
|
{
|
||||||
|
if (!p)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (i < 0 || i >= BM_COUNT)
|
if (i < 0 || i >= BM_COUNT)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -387,7 +392,7 @@ Bitmap *TilemapVX::BitmapArray::get(int i) const
|
||||||
TilemapVX::TilemapVX(Viewport *viewport)
|
TilemapVX::TilemapVX(Viewport *viewport)
|
||||||
{
|
{
|
||||||
p = new TilemapVXPrivate(viewport);
|
p = new TilemapVXPrivate(viewport);
|
||||||
p->bitmapsProxy.p = p;
|
bmProxy.p = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
TilemapVX::~TilemapVX()
|
TilemapVX::~TilemapVX()
|
||||||
|
@ -413,11 +418,11 @@ void TilemapVX::update()
|
||||||
p->aniOffset = Vec2(aniIdxA * 2 * 32, aniIdxC * 32);
|
p->aniOffset = Vec2(aniIdxA * 2 * 32, aniIdxC * 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
TilemapVX::BitmapArray &TilemapVX::getBitmapArray() const
|
TilemapVX::BitmapArray &TilemapVX::getBitmapArray()
|
||||||
{
|
{
|
||||||
guardDisposed();
|
guardDisposed();
|
||||||
|
|
||||||
return p->bitmapsProxy;
|
return bmProxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEF_ATTR_RD_SIMPLE(TilemapVX, MapData, Table*, p->mapData)
|
DEF_ATTR_RD_SIMPLE(TilemapVX, MapData, Table*, p->mapData)
|
||||||
|
@ -521,4 +526,5 @@ void TilemapVX::setOY(int value)
|
||||||
void TilemapVX::releaseResources()
|
void TilemapVX::releaseResources()
|
||||||
{
|
{
|
||||||
delete p;
|
delete p;
|
||||||
|
bmProxy.p = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ public:
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
BitmapArray &getBitmapArray() const;
|
BitmapArray &getBitmapArray();
|
||||||
|
|
||||||
DECL_ATTR( Viewport, Viewport* )
|
DECL_ATTR( Viewport, Viewport* )
|
||||||
DECL_ATTR( MapData, Table* )
|
DECL_ATTR( MapData, Table* )
|
||||||
|
@ -66,6 +66,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TilemapVXPrivate *p;
|
TilemapVXPrivate *p;
|
||||||
|
BitmapArray bmProxy;
|
||||||
|
|
||||||
void releaseResources();
|
void releaseResources();
|
||||||
const char *klassName() const { return "tilemap"; }
|
const char *klassName() const { return "tilemap"; }
|
||||||
|
|
Loading…
Reference in New Issue