summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/animatedsprite.cpp8
-rw-r--r--src/animatedsprite.h2
-rw-r--r--src/animationparticle.h2
-rw-r--r--src/gui/itempopup.cpp21
-rw-r--r--src/gui/minimap.cpp14
-rw-r--r--src/gui/minimap.h4
-rw-r--r--src/gui/widgets/desktop.cpp13
-rw-r--r--src/gui/widgets/desktop.h4
-rw-r--r--src/gui/widgets/emoteshortcutcontainer.cpp2
-rw-r--r--src/gui/widgets/icon.cpp7
-rw-r--r--src/gui/widgets/icon.h10
-rw-r--r--src/imagesprite.cpp9
-rw-r--r--src/imagesprite.h7
-rw-r--r--src/item.cpp26
-rw-r--r--src/item.h9
-rw-r--r--src/map.cpp5
-rw-r--r--src/particle.cpp8
-rw-r--r--src/particleemitter.cpp13
-rw-r--r--src/particleemitter.h5
-rw-r--r--src/resources/emotedb.cpp39
-rw-r--r--src/resources/emotedb.h7
-rw-r--r--src/resources/mapreader.cpp3
-rw-r--r--src/resources/resource.h23
-rw-r--r--src/resources/resourcemanager.cpp13
-rw-r--r--src/resources/resourcemanager.h9
25 files changed, 127 insertions, 136 deletions
diff --git a/src/animatedsprite.cpp b/src/animatedsprite.cpp
index 6a5800aa..7aa475d9 100644
--- a/src/animatedsprite.cpp
+++ b/src/animatedsprite.cpp
@@ -35,9 +35,6 @@ AnimatedSprite::AnimatedSprite(SpriteDef *sprite):
{
assert(mSprite);
- // Take possession of the sprite
- mSprite->incRef();
-
// Play the stand animation by default
play(SpriteAction::STAND);
}
@@ -53,10 +50,7 @@ AnimatedSprite *AnimatedSprite::load(const std::string &filename, int variant)
return as;
}
-AnimatedSprite::~AnimatedSprite()
-{
- mSprite->decRef();
-}
+AnimatedSprite::~AnimatedSprite() = default;
bool AnimatedSprite::reset()
{
diff --git a/src/animatedsprite.h b/src/animatedsprite.h
index 2c7d589f..05c73ddd 100644
--- a/src/animatedsprite.h
+++ b/src/animatedsprite.h
@@ -87,7 +87,7 @@ class AnimatedSprite final : public Sprite
int mFrameIndex = 0; /**< The index of the current frame. */
int mFrameTime = 0; /**< The time since start of frame. */
- SpriteDef *mSprite; /**< The sprite definition. */
+ ResourceRef<SpriteDef> mSprite; /**< The sprite definition. */
Action *mAction = nullptr; /**< The currently active action. */
Animation *mAnimation = nullptr; /**< The currently active animation. */
Frame *mFrame = nullptr; /**< The currently active frame. */
diff --git a/src/animationparticle.h b/src/animationparticle.h
index 230d4e7d..69b2dbbe 100644
--- a/src/animationparticle.h
+++ b/src/animationparticle.h
@@ -27,8 +27,6 @@
#include <libxml/tree.h>
-#include <memory>
-
class Map;
class AnimationParticle : public ImageParticle
diff --git a/src/gui/itempopup.cpp b/src/gui/itempopup.cpp
index f552a570..8208a5d8 100644
--- a/src/gui/itempopup.cpp
+++ b/src/gui/itempopup.cpp
@@ -102,7 +102,7 @@ ItemPopup::ItemPopup():
mItemWeight = new TextBox;
mItemWeight->setEditable(false);
- mIcon = new Icon(nullptr);
+ mIcon = new Icon;
add(mItemName);
add(mItemDesc);
@@ -113,15 +113,7 @@ ItemPopup::ItemPopup():
addMouseListener(this);
}
-ItemPopup::~ItemPopup()
-{
- if (mIcon)
- {
- Image *image = mIcon->getImage();
- if (image)
- image->decRef();
- }
-}
+ItemPopup::~ItemPopup() = default;
void ItemPopup::setEquipmentText(const std::string& text)
{
@@ -158,16 +150,11 @@ void ItemPopup::setItem(const ItemInfo &item, bool showImage)
int space = 0;
- Image *oldImage = mIcon->getImage();
- if (oldImage)
- oldImage->decRef();
-
if (showImage)
{
ResourceManager *resman = ResourceManager::getInstance();
- Image *image = resman->getImage(
- paths.getStringValue("itemIcons")
- + item.getDisplay().image);
+ auto image = resman->getImageRef(paths.getStringValue("itemIcons") +
+ item.getDisplay().image);
mIcon->setImage(image);
if (image)
diff --git a/src/gui/minimap.cpp b/src/gui/minimap.cpp
index 4a940254..cb38fba6 100644
--- a/src/gui/minimap.cpp
+++ b/src/gui/minimap.cpp
@@ -65,16 +65,12 @@ Minimap::Minimap():
Minimap::~Minimap()
{
config.setValue(getWindowName() + "Show", mShow);
-
- if (mMapImage)
- mMapImage->decRef();
}
void Minimap::setMap(Map *map)
{
// Set the title for the Minimap
std::string caption;
- std::string minimapName;
if (map)
caption = map->getName();
@@ -85,11 +81,7 @@ void Minimap::setMap(Map *map)
minimap->setCaption(caption);
// Adapt the image
- if (mMapImage)
- {
- mMapImage->decRef();
- mMapImage = nullptr;
- }
+ mMapImage = nullptr;
if (map)
{
@@ -98,13 +90,13 @@ void Minimap::setMap(Map *map)
"graphics/minimaps/" + map->getFilename() + ".png";
ResourceManager *resman = ResourceManager::getInstance();
- minimapName = map->getProperty("minimap");
+ std::string minimapName = map->getProperty("minimap");
if (minimapName.empty() && resman->exists(tempname))
minimapName = tempname;
if (!minimapName.empty())
- mMapImage = resman->getImage(minimapName);
+ mMapImage = resman->getImageRef(minimapName);
}
if (mMapImage)
diff --git a/src/gui/minimap.h b/src/gui/minimap.h
index 6eb051ef..6e80a3c1 100644
--- a/src/gui/minimap.h
+++ b/src/gui/minimap.h
@@ -24,6 +24,8 @@
#include "gui/widgets/window.h"
+#include "resources/resource.h"
+
class Image;
class Map;
@@ -59,7 +61,7 @@ class Minimap : public Window
private:
Map *mMap = nullptr;
- Image *mMapImage = nullptr;
+ ResourceRef<Image> mMapImage;
float mWidthProportion = 0.5;
float mHeightProportion = 0.5;
static bool mShow;
diff --git a/src/gui/widgets/desktop.cpp b/src/gui/widgets/desktop.cpp
index 474aadb0..ca86360e 100644
--- a/src/gui/widgets/desktop.cpp
+++ b/src/gui/widgets/desktop.cpp
@@ -52,11 +52,7 @@ Desktop::Desktop()
add(mVersionLabel, 25, 2);
}
-Desktop::~Desktop()
-{
- if (mWallpaper)
- mWallpaper->decRef();
-}
+Desktop::~Desktop() = default;
void Desktop::reloadWallpaper()
{
@@ -109,14 +105,11 @@ void Desktop::setBestFittingWallpaper()
return;
ResourceManager *resman = ResourceManager::getInstance();
- Image *wallpaper = resman->getImage(wallpaperName);
+ auto wallpaper = resman->getImageRef(wallpaperName);
if (wallpaper)
{
- if (mWallpaper)
- mWallpaper->decRef(Resource::DeleteImmediately);
-
- mWallpaper = wallpaper;
+ mWallpaper = std::move(wallpaper);
}
else
{
diff --git a/src/gui/widgets/desktop.h b/src/gui/widgets/desktop.h
index 97294423..5909ac72 100644
--- a/src/gui/widgets/desktop.h
+++ b/src/gui/widgets/desktop.h
@@ -26,6 +26,8 @@
#include "gui/widgets/container.h"
+#include "resources/resource.h"
+
#include <guichan/widgetlistener.hpp>
class Image;
@@ -61,7 +63,7 @@ class Desktop : public Container, gcn::WidgetListener
private:
void setBestFittingWallpaper();
- Image *mWallpaper = nullptr;
+ ResourceRef<Image> mWallpaper;
gcn::Label *mVersionLabel;
};
diff --git a/src/gui/widgets/emoteshortcutcontainer.cpp b/src/gui/widgets/emoteshortcutcontainer.cpp
index 4df0c4b9..c72d166f 100644
--- a/src/gui/widgets/emoteshortcutcontainer.cpp
+++ b/src/gui/widgets/emoteshortcutcontainer.cpp
@@ -89,7 +89,7 @@ void EmoteShortcutContainer::draw(gcn::Graphics *graphics)
if (mEmoteMoved != -1)
{
// Draw the emote image being dragged by the cursor.
- const ImageSprite *sprite = EmoteDB::get(mEmoteMoved).sprite;
+ const ImageSprite *sprite = EmoteDB::get(mEmoteMoved).sprite.get();
const int tPosX = mCursorPosX - (sprite->getWidth() / 2);
const int tPosY = mCursorPosY - (sprite->getHeight() / 2);
diff --git a/src/gui/widgets/icon.cpp b/src/gui/widgets/icon.cpp
index 5becadd1..67fd8384 100644
--- a/src/gui/widgets/icon.cpp
+++ b/src/gui/widgets/icon.cpp
@@ -27,14 +27,17 @@
#include "resources/resourcemanager.h"
Icon::Icon(const std::string &file)
- : Icon(ResourceManager::getInstance()->getImage(file))
-{}
+ : Icon(ResourceManager::getInstance()->getImageRef(file))
+{
+}
Icon::Icon(Image *image)
{
setImage(image);
}
+Icon::~Icon() = default;
+
void Icon::setImage(Image *image)
{
mImage = image;
diff --git a/src/gui/widgets/icon.h b/src/gui/widgets/icon.h
index 508d2095..3ebc2c16 100644
--- a/src/gui/widgets/icon.h
+++ b/src/gui/widgets/icon.h
@@ -22,6 +22,8 @@
#ifndef ICON_H
#define ICON_H
+#include "resources/resource.h"
+
#include <guichan/widget.hpp>
class Image;
@@ -39,12 +41,14 @@ class Icon : public gcn::Widget
*
* @param filename The file name of the image to display
*/
- Icon(const std::string &filename);
+ explicit Icon(const std::string &filename);
/**
* Constructor, uses an existing Image.
*/
- Icon(Image *image);
+ explicit Icon(Image *image = nullptr);
+
+ ~Icon() override;
/**
* Gets the current Image.
@@ -62,7 +66,7 @@ class Icon : public gcn::Widget
void draw(gcn::Graphics *g) override;
private:
- Image *mImage = nullptr;
+ ResourceRef<Image> mImage;
};
#endif // ICON_H
diff --git a/src/imagesprite.cpp b/src/imagesprite.cpp
index 74d9bc43..9ef27cd1 100644
--- a/src/imagesprite.cpp
+++ b/src/imagesprite.cpp
@@ -23,17 +23,12 @@
#include "graphics.h"
ImageSprite::ImageSprite(Image *image):
- mImage(image)
+ mImage(image)
{
mAlpha = mImage->getAlpha();
-
- mImage->incRef();
}
-ImageSprite::~ImageSprite()
-{
- mImage->decRef();
-}
+ImageSprite::~ImageSprite() = default;
bool ImageSprite::draw(Graphics *graphics, int posX, int posY) const
{
diff --git a/src/imagesprite.h b/src/imagesprite.h
index 5a04f9ed..4fc69927 100644
--- a/src/imagesprite.h
+++ b/src/imagesprite.h
@@ -60,8 +60,13 @@ public:
int getDuration() const override
{ return 0; }
+ // Hack to allow the ImageSprite to be used with SubImage instances, which
+ // are not reference counted.
+ void releaseImageRef()
+ { mImage.release(); }
+
private:
- Image *mImage;
+ ResourceRef<Image> mImage;
};
#endif // IMAGESPRITE_H
diff --git a/src/item.cpp b/src/item.cpp
index 30536df0..5ce1fea5 100644
--- a/src/item.cpp
+++ b/src/item.cpp
@@ -36,38 +36,24 @@ Item::Item(int id, int quantity, bool equipped):
setId(id);
}
-Item::~Item()
-{
- if (mImage)
- mImage->decRef();
-}
+Item::~Item() = default;
void Item::setId(int id)
{
mId = id;
// Load the associated image
- if (mImage)
- mImage->decRef();
-
- if (mDrawImage)
- mDrawImage->decRef();
-
ResourceManager *resman = ResourceManager::getInstance();
- SpriteDisplay display = getInfo().getDisplay();
- std::string imagePath = paths.getStringValue("itemIcons")
- + display.image;
- mImage = resman->getImage(imagePath);
- mDrawImage = resman->getImage(imagePath);
+ const SpriteDisplay &display = getInfo().getDisplay();
+ mImage = resman->getImage(paths.getStringValue("itemIcons") + display.image);
if (!mImage)
mImage = Theme::getImageFromTheme(paths.getValue("unknownItemFile",
"unknown-item.png"));
- if (!mDrawImage)
- mDrawImage = Theme::getImageFromTheme(
- paths.getValue("unknownItemFile",
- "unknown-item.png"));
+ // Remove the automatic reference added by the ResourceManager
+ if (mImage)
+ mImage->decRef();
}
void Item::doEvent(Event::Type eventName)
diff --git a/src/item.h b/src/item.h
index 2be75164..b5dd1fe2 100644
--- a/src/item.h
+++ b/src/item.h
@@ -25,6 +25,7 @@
#include "event.h"
#include "resources/itemdb.h"
+#include "resources/resource.h"
class Image;
@@ -56,11 +57,6 @@ class Item
Image *getImage() const { return mImage; }
/**
- * Returns the item image.
- */
- Image *getDrawImage() const { return mDrawImage; }
-
- /**
* Sets the number of items.
*/
void setQuantity(int quantity) { mQuantity = quantity; }
@@ -121,8 +117,7 @@ class Item
protected:
int mId; /**< Item type id. */
- Image *mImage = nullptr; /**< Item image. */
- Image *mDrawImage = nullptr; /**< Draw image. */
+ ResourceRef<Image> mImage; /**< Item image. */
int mQuantity; /**< Number of items. */
bool mEquipped; /**< Item is equipped. */
bool mInEquipment = false; /**< Item is in equipment */
diff --git a/src/map.cpp b/src/map.cpp
index 77f9feb8..e9d29b61 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -243,7 +243,7 @@ void Map::initializeAmbientLayers()
auto addAmbientLayer = [=](const std::string &name, std::vector<AmbientLayer> &list)
{
- if (Image *img = resman->getImage(getProperty(name + "image")))
+ if (auto img = resman->getImageRef(getProperty(name + "image")))
{
auto &ambientLayer = list.emplace_back(img);
ambientLayer.mParallax = getFloatProperty(name + "parallax");
@@ -251,9 +251,6 @@ void Map::initializeAmbientLayers()
ambientLayer.mSpeedY = getFloatProperty(name + "scrollY");
ambientLayer.mMask = getIntProperty(name + "mask", 1);
ambientLayer.mKeepRatio = getBoolProperty(name + "keepratio");
-
- // The AmbientLayer takes control over the image.
- img->decRef();
}
};
diff --git a/src/particle.cpp b/src/particle.cpp
index 953e4160..56998df4 100644
--- a/src/particle.cpp
+++ b/src/particle.cpp
@@ -19,17 +19,19 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "particle.h"
+
#include "animationparticle.h"
#include "configuration.h"
-#include "resources/dye.h"
#include "imageparticle.h"
#include "log.h"
#include "map.h"
-#include "particle.h"
#include "particleemitter.h"
#include "rotationalparticle.h"
#include "textparticle.h"
+#include "resources/dye.h"
+#include "resources/image.h"
#include "resources/resourcemanager.h"
#include "utils/dtor.h"
@@ -295,8 +297,8 @@ Particle *Particle::addEffect(const std::string &particleEffectFile,
std::string imageSrc = (const char*)node->xmlChildrenNode->content;
if (!imageSrc.empty() && !dyePalettes.empty())
Dye::instantiate(imageSrc, dyePalettes);
- Image *img= resman->getImage(imageSrc);
+ auto img = resman->getImageRef(imageSrc);
newParticle = new ImageParticle(mMap, img);
}
// Other
diff --git a/src/particleemitter.cpp b/src/particleemitter.cpp
index 196a43d2..edb892e1 100644
--- a/src/particleemitter.cpp
+++ b/src/particleemitter.cpp
@@ -41,9 +41,7 @@
ParticleEmitter::ParticleEmitter(xmlNodePtr emitterNode, Particle *target,
Map *map, int rotation,
- const std::string& dyePalettes):
- mOutputPauseLeft(0),
- mParticleImage(nullptr)
+ const std::string &dyePalettes)
{
mMap = map;
mParticleTarget = target;
@@ -104,7 +102,7 @@ ParticleEmitter::ParticleEmitter(xmlNodePtr emitterNode, Particle *target,
Dye::instantiate(image, dyePalettes);
ResourceManager *resman = ResourceManager::getInstance();
- mParticleImage = resman->getImage(image);
+ mParticleImage = resman->getImageRef(image);
}
}
else if (name == "horizontal-angle")
@@ -403,16 +401,11 @@ ParticleEmitter & ParticleEmitter::operator=(const ParticleEmitter &o)
mOutputPauseLeft = 0;
- if (mParticleImage) mParticleImage->incRef();
-
return *this;
}
-ParticleEmitter::~ParticleEmitter()
-{
- if (mParticleImage) mParticleImage->decRef();
-}
+ParticleEmitter::~ParticleEmitter() = default;
template <typename T> ParticleEmitterProp<T>
diff --git a/src/particleemitter.h b/src/particleemitter.h
index 5b139318..512272ff 100644
--- a/src/particleemitter.h
+++ b/src/particleemitter.h
@@ -25,6 +25,7 @@
#include "particleemitterprop.h"
#include "resources/animation.h"
+#include "resources/resource.h"
#include "utils/xml.h"
@@ -120,12 +121,12 @@ class ParticleEmitter
ParticleEmitterProp<int> mOutput; /**< Number of particles spawned per update */
ParticleEmitterProp<int> mOutputPause; /**< Pause in frames between two spawns */
- int mOutputPauseLeft;
+ int mOutputPauseLeft = 0;
/*
* Graphical representation of the particles
*/
- Image *mParticleImage; /**< Particle image, if used */
+ ResourceRef<Image> mParticleImage; /**< Particle image, if used */
Animation mParticleAnimation; /**< Filename of particle animation file */
Animation mParticleRotation; /**< Filename of particle rotation file */
ParticleEmitterProp<float> mParticleAlpha; /**< Opacity of the graphical representation of the particles */
diff --git a/src/resources/emotedb.cpp b/src/resources/emotedb.cpp
index e1dd8f4a..b0536a0e 100644
--- a/src/resources/emotedb.cpp
+++ b/src/resources/emotedb.cpp
@@ -44,8 +44,8 @@ void EmoteDB::init()
mUnknown.name = "unknown";
mUnknown.effectId = -1;
- mUnknown.sprite = new ImageSprite(
- ResourceManager::getInstance()->getImage("graphics/sprites/error.png"));
+ mUnknown.sprite = std::make_unique<ImageSprite>(
+ ResourceManager::getInstance()->getImageRef("graphics/sprites/error.png"));
}
void EmoteDB::readEmoteNode(xmlNodePtr node, const std::string &filename)
@@ -57,16 +57,16 @@ void EmoteDB::readEmoteNode(xmlNodePtr node, const std::string &filename)
return;
}
- Emote currentEmote;
+ Emote emote;
- currentEmote.id = id;
- currentEmote.name = XML::getProperty(node, "name", "unknown");
- currentEmote.effectId = XML::getProperty(node, "effectid", -1);
+ emote.id = id;
+ emote.name = XML::getProperty(node, "name", "unknown");
+ emote.effectId = XML::getProperty(node, "effectid", -1);
- if (currentEmote.effectId == -1)
+ if (emote.effectId == -1)
{
logger->log("Emote Database: Warning: Emote %s has no attached effect in %s!",
- currentEmote.name.c_str(), filename.c_str());
+ emote.name.c_str(), filename.c_str());
return;
}
@@ -77,25 +77,26 @@ void EmoteDB::readEmoteNode(xmlNodePtr node, const std::string &filename)
if (imageName.empty() || width <= 0 || height <= 0)
{
logger->log("Emote Database: Warning: Emote %s has bad imageset values in %s",
- currentEmote.name.c_str(), filename.c_str());
+ emote.name.c_str(), filename.c_str());
return;
}
- ImageSet *is = ResourceManager::getInstance()->getImageSet(imageName,
- width,
- height);
- if (!is || is->size() == 0)
+ emote.is = ResourceManager::getInstance()->getImageSet(imageName,
+ width,
+ height);
+ emote.is->decRef(); // clear automatic reference
+
+ if (!emote.is || emote.is->size() == 0)
{
logger->log("Emote Database: Error loading imageset for emote %s in %s",
- currentEmote.name.c_str(), filename.c_str());
- delete is;
+ emote.name.c_str(), filename.c_str());
return;
}
// For now we just use the first image in the animation
- currentEmote.sprite = new ImageSprite(is->get(0));
+ emote.sprite = std::make_unique<ImageSprite>(emote.is->get(0));
- mEmotes.push_back(std::move(currentEmote));
+ mEmotes.push_back(std::move(emote));
}
void EmoteDB::checkStatus()
@@ -105,7 +106,9 @@ void EmoteDB::checkStatus()
void EmoteDB::unload()
{
- // todo: don't we need to delete the sprites?
+ for (auto &emote : mEmotes)
+ emote.sprite->releaseImageRef();
+
mEmotes.clear();
mLoaded = false;
}
diff --git a/src/resources/emotedb.h b/src/resources/emotedb.h
index 1ed86a05..a6f93211 100644
--- a/src/resources/emotedb.h
+++ b/src/resources/emotedb.h
@@ -22,10 +22,14 @@
#ifndef EMOTE_DB_H
#define EMOTE_DB_H
+#include <memory>
#include <string>
+#include "resources/resource.h"
+
#include "utils/xml.h"
+class ImageSet;
class ImageSprite;
struct Emote
@@ -33,7 +37,8 @@ struct Emote
int id;
int effectId;
std::string name;
- ImageSprite *sprite;
+ ResourceRef<ImageSet> is;
+ std::unique_ptr<ImageSprite> sprite;
};
/**
diff --git a/src/resources/mapreader.cpp b/src/resources/mapreader.cpp
index 2136ed58..b49195fc 100644
--- a/src/resources/mapreader.cpp
+++ b/src/resources/mapreader.cpp
@@ -529,13 +529,12 @@ static Tileset *readTileset(xmlNodePtr node, const std::string &path,
std::string sourceStr = resolveRelativePath(pathDir, source);
ResourceManager *resman = ResourceManager::getInstance();
- Image *tilebmp = resman->getImage(sourceStr);
+ auto tilebmp = resman->getImageRef(sourceStr);
if (tilebmp)
{
set = new Tileset(tilebmp, tw, th, firstGid, margin,
spacing);
- tilebmp->decRef();
}
else
{
diff --git a/src/resources/resource.h b/src/resources/resource.h
index 9fe00f3d..e1f37d73 100644
--- a/src/resources/resource.h
+++ b/src/resources/resource.h
@@ -120,6 +120,20 @@ public:
return *this;
}
+ // Move assignment operator
+ ResourceRef &operator=(ResourceRef &&other)
+ {
+ if (this != &other)
+ {
+ if (mResource)
+ mResource->decRef();
+
+ mResource = other.mResource;
+ other.mResource = nullptr;
+ }
+ return *this;
+ }
+
// Allow dereferencing
RESOURCE *operator->() const
{ return mResource; }
@@ -131,6 +145,15 @@ public:
operator RESOURCE *() const
{ return mResource; }
+ /**
+ * Releases the resource without decrementing the reference count!
+ *
+ * This is currently necessary to avoid calls to decRef on instances of
+ * SubImage, which are not reference counted resources.
+ */
+ void release()
+ { mResource = nullptr; }
+
private:
RESOURCE *mResource;
};
diff --git a/src/resources/resourcemanager.cpp b/src/resources/resourcemanager.cpp
index f43aea41..e6600236 100644
--- a/src/resources/resourcemanager.cpp
+++ b/src/resources/resourcemanager.cpp
@@ -310,6 +310,13 @@ Image *ResourceManager::getImage(const std::string &idPath)
}));
}
+ResourceRef<Image> ResourceManager::getImageRef(const std::string &idPath)
+{
+ ResourceRef<Image> img = getImage(idPath);
+ img->decRef(); // remove ref added by ResourceManager::get
+ return img;
+}
+
ImageSet *ResourceManager::getImageSet(const std::string &imagePath,
int w, int h)
{
@@ -317,13 +324,11 @@ ImageSet *ResourceManager::getImageSet(const std::string &imagePath,
ss << imagePath << "[" << w << "x" << h << "]";
return static_cast<ImageSet*>(get(ss.str(), [&] () -> Resource * {
- Image *img = getImage(imagePath);
+ auto img = getImageRef(imagePath);
if (!img)
return nullptr;
- auto *res = new ImageSet(img, w, h);
- img->decRef();
- return res;
+ return new ImageSet(img, w, h);
}));
}
diff --git a/src/resources/resourcemanager.h b/src/resources/resourcemanager.h
index 6694321c..d1c32d8c 100644
--- a/src/resources/resourcemanager.h
+++ b/src/resources/resourcemanager.h
@@ -22,6 +22,8 @@
#ifndef RESOURCE_MANAGER_H
#define RESOURCE_MANAGER_H
+#include "resources/resource.h"
+
#include <ctime>
#include <functional>
#include <map>
@@ -31,7 +33,6 @@
class Image;
class ImageSet;
class Music;
-class Resource;
class SoundEffect;
class SpriteDef;
@@ -144,6 +145,12 @@ class ResourceManager
/**
* Convenience wrapper around ResourceManager::get for loading
+ * images. Returns an automatically reference-counted resource.
+ */
+ ResourceRef<Image> getImageRef(const std::string &idPath);
+
+ /**
+ * Convenience wrapper around ResourceManager::get for loading
* songs.
*/
Music *getMusic(const std::string &idPath);