summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2013-04-10 00:33:27 +0300
committerAndrei Karas <akaras@inbox.ru>2013-04-10 00:33:27 +0300
commita0c7a0e2d34a13f2c3e86f662e352977ebe2ae73 (patch)
tree15996308da765b18751048c6bdaeb81926959328
parentc5ff42706d5ff540b5f557fa1a2b1924a6cdf07b (diff)
downloadmv-a0c7a0e2d34a13f2c3e86f662e352977ebe2ae73.tar.gz
mv-a0c7a0e2d34a13f2c3e86f662e352977ebe2ae73.tar.bz2
mv-a0c7a0e2d34a13f2c3e86f662e352977ebe2ae73.tar.xz
mv-a0c7a0e2d34a13f2c3e86f662e352977ebe2ae73.zip
Add option to left all per map sprites in memory if once was loaded.
This can prevent random lags and also can use more memory.
-rw-r--r--src/commands.cpp1
-rw-r--r--src/defaults.cpp1
-rw-r--r--src/game.cpp4
-rw-r--r--src/gui/setup_perfomance.cpp4
-rw-r--r--src/resources/resource.h8
-rw-r--r--src/resources/resourcemanager.cpp30
-rw-r--r--src/resources/resourcemanager.h3
-rw-r--r--src/resources/spritedef.cpp10
-rw-r--r--src/resources/spritedef.h2
9 files changed, 56 insertions, 7 deletions
diff --git a/src/commands.cpp b/src/commands.cpp
index 8ddd0f0bf..9b3a776d4 100644
--- a/src/commands.cpp
+++ b/src/commands.cpp
@@ -349,6 +349,7 @@ impHandler0(clear)
impHandler0(cleanGraphics)
{
ResourceManager *const resman = ResourceManager::getInstance();
+ resman->cleanProtected();
while (resman->cleanOrphans(true));
if (debugChatTab)
diff --git a/src/defaults.cpp b/src/defaults.cpp
index 96f22dba7..f70788eca 100644
--- a/src/defaults.cpp
+++ b/src/defaults.cpp
@@ -314,6 +314,7 @@ DefaultsData* getConfigDefaults()
AddDEF("enableLangTab", true);
AddDEF("showAllLang", false);
AddDEF("moveNames", false);
+ AddDEF("uselonglivesprites", false);
return configData;
}
diff --git a/src/game.cpp b/src/game.cpp
index 465911767..105be45cf 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -1008,6 +1008,9 @@ void Game::changeMap(const std::string &mapPath)
{
resetAdjustLevel();
+ ResourceManager *const resman = ResourceManager::getInstance();
+ resman->cleanProtected();
+
if (viewport)
viewport->clearPopup();
@@ -1038,7 +1041,6 @@ void Game::changeMap(const std::string &mapPath)
std::string realFullMap = paths.getValue("maps", "maps/").append(
MapDB::getMapName(mMapName)).append(".tmx");
- const ResourceManager *const resman = ResourceManager::getInstance();
if (!resman->exists(realFullMap))
realFullMap.append(".gz");
diff --git a/src/gui/setup_perfomance.cpp b/src/gui/setup_perfomance.cpp
index c570ba1a1..0d924690b 100644
--- a/src/gui/setup_perfomance.cpp
+++ b/src/gui/setup_perfomance.cpp
@@ -129,6 +129,10 @@ Setup_Perfomance::Setup_Perfomance(const Widget2 *const widget) :
new SetupItemCheckBox(_("Enable texture atlases (OpenGL)"), "",
"useAtlases", this, "useAtlasesEvent");
+ new SetupItemCheckBox(_("Cache all sprites per map (can use "
+ "additinal memory)"), "", "uselonglivesprites", this,
+ "uselonglivespritesEvent");
+
setDimension(gcn::Rectangle(0, 0, 550, 350));
}
diff --git a/src/resources/resource.h b/src/resources/resource.h
index 2e73cd3f0..0577a3569 100644
--- a/src/resources/resource.h
+++ b/src/resources/resource.h
@@ -43,6 +43,7 @@ class Resource
*/
Resource() :
mTimeStamp(0),
+ mProtected(false),
#ifdef DEBUG_DUMP_LEAKS
mRefCount(0),
mDumped(false)
@@ -86,6 +87,12 @@ class Resource
std::string getSource() const A_WARN_UNUSED
{ return mSource; }
+ void setProtected(bool b)
+ { mProtected = b; }
+
+ bool isProtected() const
+ { return mProtected; }
+
#ifdef DEBUG_DUMP_LEAKS
bool getDumped() const A_WARN_UNUSED
{ return mDumped; }
@@ -105,6 +112,7 @@ class Resource
private:
time_t mTimeStamp; /**< Time at which the resource was orphaned. */
+ bool mProtected;
unsigned mRefCount; /**< Reference count. */
#ifdef DEBUG_DUMP_LEAKS
bool mDumped;
diff --git a/src/resources/resourcemanager.cpp b/src/resources/resourcemanager.cpp
index ef5ccf128..2baf09340 100644
--- a/src/resources/resourcemanager.cpp
+++ b/src/resources/resourcemanager.cpp
@@ -63,7 +63,8 @@ ResourceManager::ResourceManager() :
mOldestOrphan(0),
mSelectedSkin(""),
mSkinName(""),
- mDestruction(0)
+ mDestruction(0),
+ mUseLongLiveSprites(config.getBoolValue("uselonglivesprites"))
{
logger->log1("Initializing resource manager...");
}
@@ -188,6 +189,27 @@ void ResourceManager::cleanUp(Resource *const res)
#endif
}
+void ResourceManager::cleanProtected()
+{
+ ResourceIterator iter = mResources.begin();
+ while (iter != mResources.end())
+ {
+ Resource *res = iter->second;
+ if (!res)
+ {
+ ++ iter;
+ continue;
+ }
+ if (res->isProtected())
+ {
+ res->setProtected(false);
+ res->decRef();
+ }
+
+ ++ iter;
+ }
+}
+
bool ResourceManager::cleanOrphans(const bool always)
{
timeval tv;
@@ -772,6 +794,7 @@ struct SpriteDefLoader
{
std::string path;
int variant;
+ bool useLongLiveSprites;
static Resource *load(const void *const v)
{
if (!v)
@@ -779,14 +802,14 @@ struct SpriteDefLoader
const SpriteDefLoader *const
rl = static_cast<const SpriteDefLoader *const>(v);
- return SpriteDef::load(rl->path, rl->variant);
+ return SpriteDef::load(rl->path, rl->variant, rl->useLongLiveSprites);
}
};
SpriteDef *ResourceManager::getSprite(const std::string &path,
const int variant)
{
- SpriteDefLoader rl = { path, variant };
+ SpriteDefLoader rl = { path, variant, mUseLongLiveSprites };
std::stringstream ss;
ss << path << "[" << variant << "]";
return static_cast<SpriteDef*>(get(ss.str(), SpriteDefLoader::load, &rl));
@@ -888,6 +911,7 @@ void ResourceManager::deleteInstance()
if (instance)
{
logger->log("clean orphans start");
+ instance->cleanProtected();
while (instance->cleanOrphans(true));
logger->log("clean orphans end");
ResourceIterator iter = instance->mResources.begin();
diff --git a/src/resources/resourcemanager.h b/src/resources/resourcemanager.h
index 72efe8693..e2352136e 100644
--- a/src/resources/resourcemanager.h
+++ b/src/resources/resourcemanager.h
@@ -317,6 +317,8 @@ class ResourceManager final
bool cleanOrphans(const bool always = false);
+ void cleanProtected();
+
bool isInCache(const std::string &idPath) const A_WARN_UNUSED;
Resource *getTempResource(const std::string &idPath) A_WARN_UNUSED;
@@ -346,6 +348,7 @@ class ResourceManager final
std::string mSelectedSkin;
std::string mSkinName;
bool mDestruction;
+ bool mUseLongLiveSprites;
static DelayedAnim mDelayedAnimations;
};
diff --git a/src/resources/spritedef.cpp b/src/resources/spritedef.cpp
index ff9b71901..b417345fd 100644
--- a/src/resources/spritedef.cpp
+++ b/src/resources/spritedef.cpp
@@ -73,7 +73,8 @@ unsigned SpriteDef::findNumber(const unsigned num) const
return min;
}
-SpriteDef *SpriteDef::load(const std::string &animationFile, const int variant)
+SpriteDef *SpriteDef::load(const std::string &animationFile,
+ const int variant, bool prot)
{
const size_t pos = animationFile.find('|');
std::string palettes;
@@ -90,7 +91,7 @@ SpriteDef *SpriteDef::load(const std::string &animationFile, const int variant)
std::string errorFile = paths.getStringValue("sprites").append(
paths.getStringValue("spriteErrorFile"));
if (animationFile != errorFile)
- return load(errorFile, 0);
+ return load(errorFile, 0, prot);
else
return nullptr;
}
@@ -101,6 +102,11 @@ SpriteDef *SpriteDef::load(const std::string &animationFile, const int variant)
def->substituteActions();
if (serverVersion < 1)
def->fixDeadAction();
+ if (prot)
+ {
+ def->incRef();
+ def->setProtected(true);
+ }
return def;
}
diff --git a/src/resources/spritedef.h b/src/resources/spritedef.h
index ebccc2bd7..3a8fe5a01 100644
--- a/src/resources/spritedef.h
+++ b/src/resources/spritedef.h
@@ -118,7 +118,7 @@ class SpriteDef final : public Resource
* Loads a sprite definition file.
*/
static SpriteDef *load(const std::string &file,
- const int variant) A_WARN_UNUSED;
+ const int variant, bool prot) A_WARN_UNUSED;
/**
* Returns the specified action.