Add live_textures_reload command

This commit is contained in:
Eduardo Bart 2013-03-01 05:46:55 -03:00
parent e85afd4b63
commit 8314b84f69
15 changed files with 93 additions and 31 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

View File

@ -11,7 +11,7 @@ function setMusic(filename)
end
function reloadScripts()
g_textures.clearTexturesCache()
g_textures.clearCache()
g_modules.reloadModules()
local script = '/' .. g_app.getCompactName() .. 'rc'

View File

@ -15,6 +15,10 @@ function show_map()
modules.game_interface.getMapPanel():show()
end
function live_textures_reload()
g_textures.liveReload()
end
function auto_reload_module(name)
local function reloadEvent()
reloadModule(name)

View File

@ -297,6 +297,11 @@ std::string ResourceManager::getRealDir(const std::string& path)
return dir;
}
std::string ResourceManager::getRealPath(const std::string& path)
{
return getRealDir(path) + "/" + path;
}
std::string ResourceManager::getBaseDir()
{
return PHYSFS_getBaseDir();
@ -320,3 +325,8 @@ bool ResourceManager::isFileType(const std::string& filename, const std::string&
return true;
return false;
}
ticks_t ResourceManager::getFileTime(const std::string& filename)
{
return g_platform.getFileModificationTime(getRealPath(filename));
}

View File

@ -64,6 +64,7 @@ public:
std::string resolvePath(const std::string& path);
std::string getRealDir(const std::string& path);
std::string getRealPath(const std::string& path);
std::string getBaseDir();
std::string getUserDir();
std::string getWriteDir() { return m_writeDir; }
@ -72,6 +73,7 @@ public:
std::string guessFilePath(const std::string& filename, const std::string& type);
bool isFileType(const std::string& filename, const std::string& type);
ticks_t getFileTime(const std::string& filename);
private:
std::string m_workDir;

View File

@ -30,11 +30,13 @@
Texture::Texture()
{
m_id = 0;
m_time = 0;
}
Texture::Texture(const Size& size)
{
m_id = 0;
m_time = 0;
if(!setupSize(size))
return;
@ -49,9 +51,7 @@ Texture::Texture(const Size& size)
Texture::Texture(const ImagePtr& image, bool buildMipmaps, bool compress)
{
m_id = 0;
if(!setupSize(image->getSize(), buildMipmaps))
return;
m_time = 0;
createTexture();
@ -70,6 +70,9 @@ Texture::~Texture()
void Texture::uploadPixels(const ImagePtr& image, bool buildMipmaps, bool compress)
{
if(!setupSize(image->getSize(), buildMipmaps))
return;
ImagePtr glImage = image;
if(m_size != m_glSize) {
glImage = ImagePtr(new Image(m_glSize, image->getBpp()));

View File

@ -41,8 +41,10 @@ public:
virtual void setSmooth(bool smooth);
virtual void setRepeat(bool repeat);
void setUpsideDown(bool upsideDown);
void setTime(ticks_t time) { m_time = time; }
uint getId() { return m_id; }
ticks_t getTime() { return m_time; }
int getWidth() { return m_size.width(); }
int getHeight() { return m_size.height(); }
const Size& getSize() { return m_size; }
@ -62,6 +64,7 @@ protected:
void setupPixels(int level, const Size& size, uchar *pixels, int channels = 4, bool compress = false);
uint m_id;
ticks_t m_time;
Size m_size;
Size m_glSize;
Matrix3 m_transformMatrix;

View File

@ -27,6 +27,7 @@
#include <framework/core/resourcemanager.h>
#include <framework/core/clock.h>
#include <framework/core/eventdispatcher.h>
#include <framework/graphics/apngloader.h>
TextureManager g_textures;
@ -38,6 +39,10 @@ void TextureManager::init()
void TextureManager::terminate()
{
if(m_liveReloadEvent) {
m_liveReloadEvent->cancel();
m_liveReloadEvent = nullptr;
}
m_textures.clear();
m_animatedTextures.clear();
m_emptyTexture = nullptr;
@ -56,12 +61,32 @@ void TextureManager::poll()
animatedTexture->updateAnimation();
}
void TextureManager::clearTexturesCache()
void TextureManager::clearCache()
{
m_animatedTextures.clear();
m_textures.clear();
}
void TextureManager::liveReload()
{
if(m_liveReloadEvent)
return;
m_liveReloadEvent = g_dispatcher.cycleEvent([this] {
for(auto& it : m_textures) {
const std::string& path = g_resources.guessFilePath(it.first, "png");
const TexturePtr& tex = it.second;
if(tex->getTime() >= g_resources.getFileTime(path))
continue;
ImagePtr image = Image::load(path);
if(!image)
continue;
tex->uploadPixels(image, tex->hasMipmaps());
tex->setTime(stdext::time());
}
}, 1000);
}
TexturePtr TextureManager::getTexture(const std::string& fileName)
{
TexturePtr texture;
@ -83,13 +108,14 @@ TexturePtr TextureManager::getTexture(const std::string& fileName)
// load texture file data
std::stringstream fin;
g_resources.readFileStream(filePathEx, fin);
texture = loadPNG(fin);
texture = loadTexture(fin);
} catch(stdext::exception& e) {
g_logger.error(stdext::format("Unable to load texture '%s': %s", fileName, e.what()));
texture = g_textures.getEmptyTexture();
}
if(texture) {
texture->setTime(stdext::time());
texture->setSmooth(true);
m_textures[filePath] = texture;
}
@ -98,7 +124,7 @@ TexturePtr TextureManager::getTexture(const std::string& fileName)
return texture;
}
TexturePtr TextureManager::loadPNG(std::stringstream& file)
TexturePtr TextureManager::loadTexture(std::stringstream& file)
{
TexturePtr texture;

View File

@ -24,6 +24,7 @@
#define TEXTUREMANAGER_H
#include "texture.h"
#include <framework/core/declarations.h>
class TextureManager
{
@ -32,17 +33,20 @@ public:
void terminate();
void poll();
void clearTexturesCache();
void clearCache();
void liveReload();
void preload(const std::string& fileName) { getTexture(fileName); }
TexturePtr getTexture(const std::string& fileName);
const TexturePtr& getEmptyTexture() { return m_emptyTexture; }
private:
TexturePtr loadPNG(std::stringstream& file);
TexturePtr loadTexture(std::stringstream& file);
std::unordered_map<std::string, TexturePtr> m_textures;
std::vector<AnimatedTexturePtr> m_animatedTextures;
TexturePtr m_emptyTexture;
ScheduledEventPtr m_liveReloadEvent;
};
extern TextureManager g_textures;

View File

@ -192,6 +192,7 @@ void Application::registerLuaFunctions()
g_lua.bindSingletonFunction("g_resources", "readFileContents", &ResourceManager::readFileContents, &g_resources);
g_lua.bindSingletonFunction("g_resources", "guessFilePath", &ResourceManager::guessFilePath, &g_resources);
g_lua.bindSingletonFunction("g_resources", "isFileType", &ResourceManager::isFileType, &g_resources);
g_lua.bindSingletonFunction("g_resources", "getFileTime", &ResourceManager::getFileTime, &g_resources);
// Module
g_lua.registerClass<Module>();
@ -304,7 +305,8 @@ void Application::registerLuaFunctions()
// Textures
g_lua.registerSingletonClass("g_textures");
g_lua.bindSingletonFunction("g_textures", "preload", &TextureManager::preload, &g_textures);
g_lua.bindSingletonFunction("g_textures", "clearTexturesCache", &TextureManager::clearTexturesCache, &g_textures);
g_lua.bindSingletonFunction("g_textures", "clearCache", &TextureManager::clearCache, &g_textures);
g_lua.bindSingletonFunction("g_textures", "liveReload", &TextureManager::liveReload, &g_textures);
// UI
g_lua.registerSingletonClass("g_ui");

View File

@ -25,6 +25,7 @@
#include <string>
#include <vector>
#include <framework/stdext/types.h>
class Platform
{
@ -39,11 +40,11 @@ public:
bool copyFile(std::string from, std::string to);
bool fileExists(std::string file);
bool removeFile(std::string file);
ticks_t getFileModificationTime(std::string file);
void openUrl(std::string url);
std::string getCPUName();
double getTotalSystemMemory();
std::string getOSName();
time_t getFileModificationTime(const std::string& filename);
};
extern Platform g_platform;

View File

@ -108,6 +108,14 @@ bool Platform::removeFile(std::string file)
return false;
}
ticks_t Platform::getFileModificationTime(std::string file)
{
struct stat attrib;
if(stat(file.c_str(), &attrib) == 0)
return attrib.st_mtime;
return 0;
}
void Platform::openUrl(std::string url)
{
if(url.find("http://") == std::string::npos)
@ -160,15 +168,5 @@ std::string Platform::getOSName()
return std::string();
}
time_t Platform::getFileModificationTime(const std::string& filename)
{
struct stat attrib;
if(stat(filename.c_str(), &attrib))
perror(filename.c_str());
else
return attrib.st_mtime;
return 0;
}
#endif

View File

@ -132,6 +132,19 @@ bool Platform::removeFile(std::string file)
return true;
}
ticks_t Platform::getFileModificationTime(std::string file)
{
boost::replace_all(file, "/", "\\");
std::wstring wfile = stdext::utf8_to_utf16(file);
WIN32_FILE_ATTRIBUTE_DATA fileAttrData;
memset(&fileAttrData, 0, sizeof(fileAttrData));
GetFileAttributesExW(wfile.c_str(), GetFileExInfoStandard, &fileAttrData);
ULARGE_INTEGER uli;
uli.LowPart = fileAttrData.ftLastWriteTime.dwLowDateTime;
uli.HighPart = fileAttrData.ftLastWriteTime.dwHighDateTime;
return uli.QuadPart;
}
void Platform::openUrl(std::string url)
{
if(url.find("http://") == std::string::npos)
@ -401,13 +414,4 @@ std::string Platform::getOSName()
return ret;
}
time_t Platform::getFileModificationTime(const std::string& filename)
{
//TODO
/*WIN32_FILE_ATTRIBUTE_DATA fileAttrData = {0};
GetFileAttributesEx(filename.c_str(), GetFileExInfoStandard, &fileAttrData);
return fileAttrData.ftLastWriteTime;*/
return 0;
}
#endif

View File

@ -28,6 +28,10 @@ namespace stdext {
const static auto startup_time = boost::chrono::high_resolution_clock::now();
ticks_t time() {
return std::time(NULL);
}
ticks_t millis()
{
return boost::chrono::duration_cast<boost::chrono::milliseconds>(boost::chrono::high_resolution_clock::now() - startup_time).count();

View File

@ -27,6 +27,7 @@
namespace stdext {
ticks_t time();
ticks_t millis();
ticks_t micros();
void millisleep(size_t ms);