From 37043e7b2ddcbf91461767e27cacd93e2304d698 Mon Sep 17 00:00:00 2001 From: Relintai Date: Mon, 21 Oct 2019 23:18:06 +0200 Subject: [PATCH] Implemented reference counting. --- rectpack2D/pack.h | 2 ++ texture_packer.cpp | 65 +++++++++++++++++++++++++++++++++++++++++----- texture_packer.h | 4 +++ 3 files changed, 65 insertions(+), 6 deletions(-) diff --git a/rectpack2D/pack.h b/rectpack2D/pack.h index bead2d4..59f875b 100644 --- a/rectpack2D/pack.h +++ b/rectpack2D/pack.h @@ -74,6 +74,8 @@ struct rect_xywhf : public rect_xywh { void flip(); bool flipped; + int refcount; + Ref atlas_texture; Ref original_texture; }; diff --git a/texture_packer.cpp b/texture_packer.cpp index c7798b9..3592055 100644 --- a/texture_packer.cpp +++ b/texture_packer.cpp @@ -30,9 +30,12 @@ Ref TexturePacker::add_texture(Ref texture) { //we need to check differently this case for (int i = 0; i < _rects.size(); ++i) { rect_xywhf *r = _rects.get(i); - //Refcount! - if (r->atlas_texture == texture) + + if (r->atlas_texture == texture) { + ++(r->refcount); + return r->atlas_texture; + } } Ref tex; @@ -43,6 +46,7 @@ Ref TexturePacker::add_texture(Ref texture) { rect_xywhf *rect = memnew(rect_xywhf); + rect->refcount = 1; rect->w = atlas_text->get_region().size.x; rect->h = atlas_text->get_region().size.y; @@ -63,9 +67,12 @@ Ref TexturePacker::add_texture(Ref texture) { for (int i = 0; i < _rects.size(); ++i) { rect_xywhf *r = _rects.get(i); - //Refcount! - if (r->original_texture == texture) + + if (r->original_texture == texture) { + ++(r->refcount); + return r->atlas_texture; + } } Ref tex; @@ -77,6 +84,7 @@ Ref TexturePacker::add_texture(Ref texture) { rect_xywhf *rect = memnew(rect_xywhf); + rect->refcount = 1; rect->original_texture = texture; rect->atlas_texture = tex; @@ -100,11 +108,49 @@ Ref TexturePacker::get_texture(int index) { return _rects.get(index)->atlas_texture; } +void TexturePacker::unref_texture_index(int index) { + ERR_FAIL_INDEX(index, _rects.size()); + + rect_xywhf *r = _rects.get(index); + + int rc = --(r->refcount); + + if (rc <= 0) { + _rects.remove(index); + + r->atlas_texture.unref(); + r->atlas_texture.unref(); + + memdelete(r); + } +} + +void TexturePacker::unref_texture(Ref texture) { + for (int i = 0; i < _rects.size(); ++i) { + rect_xywhf *r = _rects.get(i); + + if (r->original_texture == texture) { + + int rc = --(r->refcount); + + if (rc <= 0) { + _rects.remove(i); + + r->atlas_texture.unref(); + r->atlas_texture.unref(); + + memdelete(r); + } + + return; + } + } +} + void TexturePacker::remove_texture_index(int index) { ERR_FAIL_INDEX(index, _rects.size()); rect_xywhf *r = _rects.get(index); - _rects.remove(index); r->atlas_texture.unref(); r->atlas_texture.unref(); @@ -116,10 +162,13 @@ void TexturePacker::remove_texture(Ref texture) { for (int i = 0; i < _rects.size(); ++i) { rect_xywhf *r = _rects.get(i); - //TODO refcount! if (r->original_texture == texture) { + _rects.remove(i); + r->atlas_texture.unref(); + r->atlas_texture.unref(); + memdelete(r); return; @@ -266,8 +315,12 @@ void TexturePacker::_bind_methods() { ClassDB::bind_method(D_METHOD("add_texture", "texture"), &TexturePacker::add_texture); ClassDB::bind_method(D_METHOD("get_texture", "index"), &TexturePacker::get_texture); ClassDB::bind_method(D_METHOD("get_original_texture", "index"), &TexturePacker::get_original_texture); + + ClassDB::bind_method(D_METHOD("unref_texture_index", "index"), &TexturePacker::unref_texture_index); + ClassDB::bind_method(D_METHOD("unref_texture", "texture"), &TexturePacker::unref_texture); ClassDB::bind_method(D_METHOD("remove_texture_index", "index"), &TexturePacker::remove_texture_index); ClassDB::bind_method(D_METHOD("remove_texture", "texture"), &TexturePacker::remove_texture); + ClassDB::bind_method(D_METHOD("get_texture_count"), &TexturePacker::get_texture_count); ClassDB::bind_method(D_METHOD("clear"), &TexturePacker::clear); diff --git a/texture_packer.h b/texture_packer.h index 3ca6778..9a0de2e 100644 --- a/texture_packer.h +++ b/texture_packer.h @@ -26,8 +26,12 @@ public: Ref add_texture(Ref texture); Ref get_texture(int index); Ref get_original_texture(int index); + + void unref_texture_index(int index); + void unref_texture(Ref texture); void remove_texture_index(int index); void remove_texture(Ref texture); + int get_texture_count(); void clear();