Add live_textures_reload command
This commit is contained in:
parent
e85afd4b63
commit
8314b84f69
Binary file not shown.
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 1.3 MiB |
|
@ -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'
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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));
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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()));
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue