summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2012-06-20 00:34:39 +0300
committerAndrei Karas <akaras@inbox.ru>2012-06-21 00:59:10 +0300
commitaa68511ad3d339be8c8f42fc6c083b696d8e687b (patch)
tree1bf138439c28b4a879c6b35e4361801bd5e1d246
parent12002b81544038bc5855189c74aca761d0c08f1b (diff)
downloadmanaplus-aa68511ad3d339be8c8f42fc6c083b696d8e687b.tar.gz
manaplus-aa68511ad3d339be8c8f42fc6c083b696d8e687b.tar.bz2
manaplus-aa68511ad3d339be8c8f42fc6c083b696d8e687b.tar.xz
manaplus-aa68511ad3d339be8c8f42fc6c083b696d8e687b.zip
Add delayed images load.
Can work for now only in OpenGL modes.
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/Makefile.am2
-rw-r--r--src/actorsprite.cpp5
-rw-r--r--src/animatedsprite.cpp52
-rw-r--r--src/animatedsprite.h16
-rw-r--r--src/animationdelayload.cpp63
-rw-r--r--src/animationdelayload.h50
-rw-r--r--src/being.cpp2
-rw-r--r--src/game.cpp5
-rw-r--r--src/resources/resourcemanager.cpp69
-rw-r--r--src/resources/resourcemanager.h18
11 files changed, 275 insertions, 9 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 4cb8bd869..cba2c3450 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -491,6 +491,8 @@ SET(SRCS
actorspritemanager.h
animatedsprite.cpp
animatedsprite.h
+ animationdelayload.cpp
+ animationdelayload.h
animationparticle.cpp
animationparticle.h
auctionmanager.cpp
diff --git a/src/Makefile.am b/src/Makefile.am
index 0bf3c056c..8b798adc0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -507,6 +507,8 @@ manaplus_SOURCES += gui/widgets/avatarlistbox.cpp \
actorspritemanager.h \
animatedsprite.cpp \
animatedsprite.h \
+ animationdelayload.cpp \
+ animationdelayload.h \
animationparticle.cpp \
animationparticle.h \
auctionmanager.cpp \
diff --git a/src/actorsprite.cpp b/src/actorsprite.cpp
index 7bd496d30..b78f6bb91 100644
--- a/src/actorsprite.cpp
+++ b/src/actorsprite.cpp
@@ -332,7 +332,7 @@ void ActorSprite::setupSpriteDisplay(const SpriteDisplay &display,
+ combineDye2((*it)->sprite, color);
int variant = (*it)->variant;
- addSprite(AnimatedSprite::load(file, variant));
+ addSprite(AnimatedSprite::delayedLoad(file, variant));
}
// Ensure that something is shown, if desired
@@ -340,7 +340,8 @@ void ActorSprite::setupSpriteDisplay(const SpriteDisplay &display,
{
if (display.image.empty())
{
- addSprite(AnimatedSprite::load(paths.getStringValue("sprites")
+ addSprite(AnimatedSprite::delayedLoad(
+ paths.getStringValue("sprites")
+ paths.getStringValue("spriteErrorFile")));
}
else
diff --git a/src/animatedsprite.cpp b/src/animatedsprite.cpp
index 1dc5b16c8..77ec69126 100644
--- a/src/animatedsprite.cpp
+++ b/src/animatedsprite.cpp
@@ -22,6 +22,7 @@
#include "animatedsprite.h"
+#include "animationdelayload.h"
#include "graphics.h"
#include "logger.h"
@@ -34,6 +35,8 @@
#include "debug.h"
+bool AnimatedSprite::mEnableCache = false;
+
AnimatedSprite::AnimatedSprite(SpriteDef *sprite):
mDirection(DIRECTION_DOWN),
mLastTime(0),
@@ -44,7 +47,8 @@ AnimatedSprite::AnimatedSprite(SpriteDef *sprite):
mAnimation(nullptr),
mFrame(nullptr),
mNumber(100),
- mNumber1(100)
+ mNumber1(100),
+ mDelayLoad(nullptr)
{
mAlpha = 1.0f;
@@ -67,6 +71,20 @@ AnimatedSprite *AnimatedSprite::load(const std::string &filename, int variant)
return as;
}
+AnimatedSprite *AnimatedSprite::delayedLoad(const std::string &filename,
+ int variant)
+{
+ if (!mEnableCache)
+ return load(filename, variant);
+ ResourceManager *resman = ResourceManager::getInstance();
+ if (resman->getFromCache(filename, variant))
+ return load(filename, variant);
+
+ AnimatedSprite *as = new AnimatedSprite(nullptr);
+ as->setDelayLoad(filename, variant);
+ return as;
+}
+
AnimatedSprite::~AnimatedSprite()
{
if (mSprite)
@@ -74,6 +92,13 @@ AnimatedSprite::~AnimatedSprite()
mSprite->decRef();
mSprite = nullptr;
}
+ if (mDelayLoad)
+ {
+ mDelayLoad->clearSprite();
+ ResourceManager::removeDelayLoad(mDelayLoad);
+ delete mDelayLoad;
+ mDelayLoad = nullptr;
+ }
}
bool AnimatedSprite::reset()
@@ -94,7 +119,12 @@ bool AnimatedSprite::reset()
bool AnimatedSprite::play(std::string spriteAction)
{
if (!mSprite)
- return false;
+ {
+ if (!mDelayLoad)
+ return false;
+ mDelayLoad->setAction(spriteAction);
+ return true;
+ }
Action *action = mSprite->getAction(spriteAction, mNumber);
if (!action)
@@ -343,3 +373,21 @@ bool AnimatedSprite::updateNumber(unsigned num)
}
return false;
}
+
+void AnimatedSprite::setDelayLoad(const std::string &filename,
+ int variant)
+{
+ if (mDelayLoad)
+ {
+ mDelayLoad->clearSprite();
+ ResourceManager::removeDelayLoad(mDelayLoad);
+ delete mDelayLoad;
+ }
+ mDelayLoad = new AnimationDelayLoad(filename, variant, this);
+ ResourceManager::addDelayedAnimation(mDelayLoad);
+}
+
+void AnimatedSprite::clearDelayLoad()
+{
+ mDelayLoad = nullptr;
+}
diff --git a/src/animatedsprite.h b/src/animatedsprite.h
index d28badfc1..4f4caff16 100644
--- a/src/animatedsprite.h
+++ b/src/animatedsprite.h
@@ -29,6 +29,7 @@
#include <string>
class Animation;
+class AnimationDelayLoad;
struct Frame;
/**
@@ -53,6 +54,9 @@ class AnimatedSprite : public Sprite
static AnimatedSprite *load(const std::string &filename,
int variant = 0);
+ static AnimatedSprite *delayedLoad(const std::string &filename,
+ int variant = 0);
+
virtual ~AnimatedSprite();
bool reset();
@@ -86,9 +90,19 @@ class AnimatedSprite : public Sprite
bool updateNumber(unsigned num);
+ void clearDelayLoad();
+
+ void setSprite(SpriteDef *sprite)
+ { mSprite = sprite; }
+
+ static void setEnableCache(bool b)
+ { mEnableCache = b; }
+
private:
bool updateCurrentAnimation(unsigned int dt);
+ void setDelayLoad(const std::string &filename, int variant);
+
SpriteDirection mDirection; /**< The sprite direction. */
int mLastTime; /**< The last time update was called. */
@@ -101,6 +115,8 @@ class AnimatedSprite : public Sprite
Frame *mFrame; /**< The currently active frame. */
unsigned mNumber;
unsigned mNumber1;
+ AnimationDelayLoad *mDelayLoad;
+ static bool mEnableCache;
};
#endif
diff --git a/src/animationdelayload.cpp b/src/animationdelayload.cpp
new file mode 100644
index 000000000..0ce50ec2c
--- /dev/null
+++ b/src/animationdelayload.cpp
@@ -0,0 +1,63 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2012 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "animationdelayload.h"
+
+#include "animatedsprite.h"
+
+#include "resources/resourcemanager.h"
+
+#include "debug.h"
+
+AnimationDelayLoad::AnimationDelayLoad(const std::string &fileName,
+ int variant, AnimatedSprite *sprite) :
+ mFileName(fileName),
+ mVariant(variant),
+ mSprite(sprite),
+ mAction(SpriteAction::STAND)
+{
+}
+
+AnimationDelayLoad::~AnimationDelayLoad()
+{
+ if (mSprite)
+ {
+ mSprite->clearDelayLoad();
+ mSprite = nullptr;
+ }
+}
+
+void AnimationDelayLoad::clearSprite()
+{
+ mSprite = nullptr;
+}
+
+void AnimationDelayLoad::load()
+{
+ if (mSprite)
+ {
+ ResourceManager *resman = ResourceManager::getInstance();
+ SpriteDef *s = resman->getSprite(mFileName, mVariant);
+ if (!s)
+ return;
+ mSprite->setSprite(s);
+ mSprite->play(mAction);
+ }
+}
diff --git a/src/animationdelayload.h b/src/animationdelayload.h
new file mode 100644
index 000000000..b6b8a3321
--- /dev/null
+++ b/src/animationdelayload.h
@@ -0,0 +1,50 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2012 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ANIMATIONDELAYLOAD_H
+#define ANIMATIONDELAYLOAD_H
+
+#include <string>
+
+class AnimatedSprite;
+
+class AnimationDelayLoad
+{
+ public:
+ AnimationDelayLoad(const std::string &fileName,
+ int variant, AnimatedSprite *sprite);
+
+ ~AnimationDelayLoad();
+
+ void clearSprite();
+
+ void load();
+
+ void setAction(std::string action)
+ { mAction = action; }
+
+ private:
+ std::string mFileName;
+ int mVariant;
+ AnimatedSprite *mSprite;
+ std::string mAction;
+};
+
+#endif // ANIMATIONDELAYLOAD_H
diff --git a/src/being.cpp b/src/being.cpp
index 89aa5275d..740989993 100644
--- a/src/being.cpp
+++ b/src/being.cpp
@@ -1786,7 +1786,7 @@ void Being::setSprite(unsigned int slot, int id, std::string color,
color = info.getDyeColorsString(colorId);
filename = combineDye(filename, color);
- equipmentSprite = AnimatedSprite::load(
+ equipmentSprite = AnimatedSprite::delayedLoad(
paths.getStringValue("sprites") + filename);
}
diff --git a/src/game.cpp b/src/game.cpp
index 8fdb2b230..75317edac 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -23,6 +23,7 @@
#include "game.h"
#include "auctionmanager.h"
+#include "animatedsprite.h"
#include "channelmanager.h"
#include "commandhandler.h"
#include "effectmanager.h"
@@ -386,6 +387,8 @@ Game::Game():
top->add(viewport);
viewport->requestMoveToBottom();
+ AnimatedSprite::setEnableCache(mainGraphics->getOpenGL());
+
createGuiWindows();
windowMenu = new WindowMenu;
@@ -569,6 +572,8 @@ void Game::slowLogic()
killStats->recalcStats();
if (shopWindow)
shopWindow->updateTimes();
+ if (mainGraphics->getOpenGL())
+ ResourceManager::delayedLoad();
PacketCounters::update();
// Handle network stuff
diff --git a/src/resources/resourcemanager.cpp b/src/resources/resourcemanager.cpp
index 37975cf16..16214661c 100644
--- a/src/resources/resourcemanager.cpp
+++ b/src/resources/resourcemanager.cpp
@@ -22,6 +22,7 @@
#include "resources/resourcemanager.h"
+#include "animationdelayload.h"
#include "client.h"
#include "configuration.h"
#include "logger.h"
@@ -52,6 +53,7 @@
#include "debug.h"
ResourceManager *ResourceManager::instance = nullptr;
+DelayedAnim ResourceManager::mDelayedAnimations;
ResourceManager::ResourceManager() :
mOldestOrphan(0),
@@ -354,8 +356,15 @@ bool ResourceManager::addResource(const std::string &idPath,
return false;
}
-Resource *ResourceManager::get(const std::string &idPath, generator fun,
- void *data)
+Resource *ResourceManager::getFromCache(const std::string &filename,
+ int variant)
+{
+ std::stringstream ss;
+ ss << filename << "[" << variant << "]";
+ return getFromCache(ss.str());
+}
+
+Resource *ResourceManager::getFromCache(const std::string &idPath)
{
// Check if the id exists, and return the value if it does.
ResourceIterator resIter = mResources.find(idPath);
@@ -376,8 +385,17 @@ Resource *ResourceManager::get(const std::string &idPath, generator fun,
res->incRef();
return res;
}
+ return nullptr;
+}
- Resource *resource = fun(data);
+Resource *ResourceManager::get(const std::string &idPath, generator fun,
+ void *data)
+{
+ Resource *resource = getFromCache(idPath);
+ if (resource)
+ return resource;
+
+ resource = fun(data);
if (resource)
{
@@ -745,3 +763,48 @@ Image *ResourceManager::getRescaled(Image *image, int width, int height)
Image *img = static_cast<Image*>(get(idPath, RescaledLoader::load, &rl));
return img;
}
+
+void ResourceManager::delayedLoad()
+{
+ static int loadTime = 0;
+ if (loadTime < cur_time)
+ {
+// loadTime = tick_time + 10;
+ loadTime = tick_time;
+
+ int k = 0;
+ DelayedAnimIter it = mDelayedAnimations.begin();
+ DelayedAnimIter it_end = mDelayedAnimations.end();
+ while (it != it_end && k < 1)
+ {
+ (*it)->load();
+ AnimationDelayLoad *tmp = *it;
+ it = mDelayedAnimations.erase(it);
+ delete tmp;
+ k ++;
+ }
+ const int time2 = tick_time;
+// if (time2 != loadTime)
+// {
+// logger->log("diff %d", time2 - loadTime);
+// }
+ if (time2 > loadTime)
+ loadTime = time2 + (time2 - loadTime) * 2 + 10;
+// loadTime += 10 - time2;
+ else
+ loadTime = time2 + 3;
+ }
+}
+
+void ResourceManager::removeDelayLoad(AnimationDelayLoad *delayedLoad)
+{
+ for(DelayedAnimIter it = mDelayedAnimations.begin(),
+ it_end = mDelayedAnimations.end(); it != it_end; ++ it)
+ {
+ if (*it == delayedLoad)
+ {
+ mDelayedAnimations.erase(it);
+ return;
+ }
+ }
+}
diff --git a/src/resources/resourcemanager.h b/src/resources/resourcemanager.h
index ca6bdb373..4900b7ce3 100644
--- a/src/resources/resourcemanager.h
+++ b/src/resources/resourcemanager.h
@@ -28,9 +28,11 @@
#include "utils/stringvector.h"
#include <ctime>
+#include <list>
#include <map>
#include <set>
+class AnimationDelayLoad;
class Image;
class ImageSet;
class Music;
@@ -41,6 +43,9 @@ class SpriteDef;
struct SDL_Surface;
struct SDL_RWops;
+typedef std::list<AnimationDelayLoad*> DelayedAnim;
+typedef DelayedAnim::iterator DelayedAnimIter;
+
/**
* A class for loading and managing resources.
*/
@@ -139,6 +144,10 @@ class ResourceManager
*/
Resource *get(const std::string &idPath, generator fun, void *data);
+ Resource *getFromCache(const std::string &idPath);
+
+ Resource *getFromCache(const std::string &filename, int variant);
+
/**
* Loads a resource from a file and adds it to the resource map.
*
@@ -269,13 +278,19 @@ class ResourceManager
void cleanOrphans(bool always = false);
+ static void addDelayedAnimation(AnimationDelayLoad *animation)
+ { mDelayedAnimations.push_back(animation); }
+
+ static void delayedLoad();
+
+ static void removeDelayLoad(AnimationDelayLoad *delayedLoad);
+
private:
/**
* Deletes the resource after logging a cleanup message.
*/
static void cleanUp(Resource *resource);
-
static ResourceManager *instance;
std::set<SDL_Surface*> deletedSurfaces;
Resources mResources;
@@ -284,6 +299,7 @@ class ResourceManager
std::string mSelectedSkin;
std::string mSkinName;
bool mDestruction;
+ static DelayedAnim mDelayedAnimations;
};
#endif