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 end
function reloadScripts() function reloadScripts()
g_textures.clearTexturesCache() g_textures.clearCache()
g_modules.reloadModules() g_modules.reloadModules()
local script = '/' .. g_app.getCompactName() .. 'rc' local script = '/' .. g_app.getCompactName() .. 'rc'

View File

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

View File

@ -297,6 +297,11 @@ std::string ResourceManager::getRealDir(const std::string& path)
return dir; return dir;
} }
std::string ResourceManager::getRealPath(const std::string& path)
{
return getRealDir(path) + "/" + path;
}
std::string ResourceManager::getBaseDir() std::string ResourceManager::getBaseDir()
{ {
return PHYSFS_getBaseDir(); return PHYSFS_getBaseDir();
@ -320,3 +325,8 @@ bool ResourceManager::isFileType(const std::string& filename, const std::string&
return true; return true;
return false; 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 resolvePath(const std::string& path);
std::string getRealDir(const std::string& path); std::string getRealDir(const std::string& path);
std::string getRealPath(const std::string& path);
std::string getBaseDir(); std::string getBaseDir();
std::string getUserDir(); std::string getUserDir();
std::string getWriteDir() { return m_writeDir; } std::string getWriteDir() { return m_writeDir; }
@ -72,6 +73,7 @@ public:
std::string guessFilePath(const std::string& filename, const std::string& type); std::string guessFilePath(const std::string& filename, const std::string& type);
bool isFileType(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: private:
std::string m_workDir; std::string m_workDir;

View File

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

View File

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

View File

@ -27,6 +27,7 @@
#include <framework/core/resourcemanager.h> #include <framework/core/resourcemanager.h>
#include <framework/core/clock.h> #include <framework/core/clock.h>
#include <framework/core/eventdispatcher.h>
#include <framework/graphics/apngloader.h> #include <framework/graphics/apngloader.h>
TextureManager g_textures; TextureManager g_textures;
@ -38,6 +39,10 @@ void TextureManager::init()
void TextureManager::terminate() void TextureManager::terminate()
{ {
if(m_liveReloadEvent) {
m_liveReloadEvent->cancel();
m_liveReloadEvent = nullptr;
}
m_textures.clear(); m_textures.clear();
m_animatedTextures.clear(); m_animatedTextures.clear();
m_emptyTexture = nullptr; m_emptyTexture = nullptr;
@ -56,12 +61,32 @@ void TextureManager::poll()
animatedTexture->updateAnimation(); animatedTexture->updateAnimation();
} }
void TextureManager::clearTexturesCache() void TextureManager::clearCache()
{ {
m_animatedTextures.clear(); m_animatedTextures.clear();
m_textures.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 TextureManager::getTexture(const std::string& fileName)
{ {
TexturePtr texture; TexturePtr texture;
@ -83,13 +108,14 @@ TexturePtr TextureManager::getTexture(const std::string& fileName)
// load texture file data // load texture file data
std::stringstream fin; std::stringstream fin;
g_resources.readFileStream(filePathEx, fin); g_resources.readFileStream(filePathEx, fin);
texture = loadPNG(fin); texture = loadTexture(fin);
} catch(stdext::exception& e) { } catch(stdext::exception& e) {
g_logger.error(stdext::format("Unable to load texture '%s': %s", fileName, e.what())); g_logger.error(stdext::format("Unable to load texture '%s': %s", fileName, e.what()));
texture = g_textures.getEmptyTexture(); texture = g_textures.getEmptyTexture();
} }
if(texture) { if(texture) {
texture->setTime(stdext::time());
texture->setSmooth(true); texture->setSmooth(true);
m_textures[filePath] = texture; m_textures[filePath] = texture;
} }
@ -98,7 +124,7 @@ TexturePtr TextureManager::getTexture(const std::string& fileName)
return texture; return texture;
} }
TexturePtr TextureManager::loadPNG(std::stringstream& file) TexturePtr TextureManager::loadTexture(std::stringstream& file)
{ {
TexturePtr texture; TexturePtr texture;

View File

@ -24,6 +24,7 @@
#define TEXTUREMANAGER_H #define TEXTUREMANAGER_H
#include "texture.h" #include "texture.h"
#include <framework/core/declarations.h>
class TextureManager class TextureManager
{ {
@ -32,17 +33,20 @@ public:
void terminate(); void terminate();
void poll(); void poll();
void clearTexturesCache(); void clearCache();
void liveReload();
void preload(const std::string& fileName) { getTexture(fileName); } void preload(const std::string& fileName) { getTexture(fileName); }
TexturePtr getTexture(const std::string& fileName); TexturePtr getTexture(const std::string& fileName);
const TexturePtr& getEmptyTexture() { return m_emptyTexture; } const TexturePtr& getEmptyTexture() { return m_emptyTexture; }
private: private:
TexturePtr loadPNG(std::stringstream& file); TexturePtr loadTexture(std::stringstream& file);
std::unordered_map<std::string, TexturePtr> m_textures; std::unordered_map<std::string, TexturePtr> m_textures;
std::vector<AnimatedTexturePtr> m_animatedTextures; std::vector<AnimatedTexturePtr> m_animatedTextures;
TexturePtr m_emptyTexture; TexturePtr m_emptyTexture;
ScheduledEventPtr m_liveReloadEvent;
}; };
extern TextureManager g_textures; 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", "readFileContents", &ResourceManager::readFileContents, &g_resources);
g_lua.bindSingletonFunction("g_resources", "guessFilePath", &ResourceManager::guessFilePath, &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", "isFileType", &ResourceManager::isFileType, &g_resources);
g_lua.bindSingletonFunction("g_resources", "getFileTime", &ResourceManager::getFileTime, &g_resources);
// Module // Module
g_lua.registerClass<Module>(); g_lua.registerClass<Module>();
@ -304,7 +305,8 @@ void Application::registerLuaFunctions()
// Textures // Textures
g_lua.registerSingletonClass("g_textures"); g_lua.registerSingletonClass("g_textures");
g_lua.bindSingletonFunction("g_textures", "preload", &TextureManager::preload, &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 // UI
g_lua.registerSingletonClass("g_ui"); g_lua.registerSingletonClass("g_ui");

View File

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

View File

@ -108,6 +108,14 @@ bool Platform::removeFile(std::string file)
return false; 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) void Platform::openUrl(std::string url)
{ {
if(url.find("http://") == std::string::npos) if(url.find("http://") == std::string::npos)
@ -160,15 +168,5 @@ std::string Platform::getOSName()
return std::string(); 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 #endif

View File

@ -132,6 +132,19 @@ bool Platform::removeFile(std::string file)
return true; 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) void Platform::openUrl(std::string url)
{ {
if(url.find("http://") == std::string::npos) if(url.find("http://") == std::string::npos)
@ -401,13 +414,4 @@ std::string Platform::getOSName()
return ret; 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 #endif

View File

@ -28,6 +28,10 @@ namespace stdext {
const static auto startup_time = boost::chrono::high_resolution_clock::now(); const static auto startup_time = boost::chrono::high_resolution_clock::now();
ticks_t time() {
return std::time(NULL);
}
ticks_t millis() ticks_t millis()
{ {
return boost::chrono::duration_cast<boost::chrono::milliseconds>(boost::chrono::high_resolution_clock::now() - startup_time).count(); 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 { namespace stdext {
ticks_t time();
ticks_t millis(); ticks_t millis();
ticks_t micros(); ticks_t micros();
void millisleep(size_t ms); void millisleep(size_t ms);