21std::string extensionOf(
const std::string &path) {
22 const auto pos = path.find_last_of(
'.');
23 if (
pos == std::string::npos)
return {};
24 std::string ext = path.substr(
pos);
25 for (
char &
c : ext)
c = static_cast<char>(std::tolower(static_cast<unsigned char>(
c)));
29bool isImagePath(
const std::string &path) {
30 const std::string ext = extensionOf(path);
31 return ext ==
".png" || ext ==
".jpg" || ext ==
".jpeg" || ext ==
".bmp" || ext ==
".tga" ||
32 ext ==
".gif" || ext ==
".webp" || ext ==
".exr" || ext ==
".hdr";
36std::string normalize(std::string path) {
37 for (
char &
c : path) {
38 if (
c ==
'\\')
c =
'/';
40 while (path.size() >= 2 && path[0] ==
'.' && path[1] ==
'/') path.erase(0, 2);
41 while (path.size() > 1 && path.back() ==
'/') path.pop_back();
47 const char *reloadKind()
const override {
return "particle"; }
49 bool handlesPath(
const std::string &normPath)
const override {
50 const std::string ext = extensionOf(normPath);
51 return ext ==
".json" || isImagePath(normPath);
54 bool reload(
const std::string &normPath)
override {
55 if (ecs::current()->getManager<ParticleEmitter>() ==
nullptr)
return false;
56 return isImagePath(normPath) ? rebindTexture(normPath) : reloadConfig(normPath);
60 static bool reloadConfig(
const std::string &normPath) {
62 auto view = ecs::View<ParticleEmitter, ParticleEmitter::Config, ParticleEmitter::Resource>();
63 for (
auto it =
view.begin(); it !=
view.end(); ++it) {
64 auto [cfg, res] = *it;
65 if (!cfg->entity || res->path.empty())
continue;
66 if (normalize(res->path) != normPath)
continue;
72 static bool rebindTexture(
const std::string &normPath) {
73 auto *gfx = eve::ModuleManager::getInstance<eve::graphics::Graphics>(
"Graphics");
74 if (!gfx)
return false;
77 auto view = ecs::View<ParticleEmitter, ParticleEmitter::Config, ParticleEmitter::Resource>();
78 for (
auto it =
view.begin(); it !=
view.end(); ++it) {
79 auto [cfg, res] = *it;
80 if (!cfg->entity || res->texturePath.empty())
continue;
81 if (normalize(res->texturePath) != normPath)
continue;
83 cfg->entity->setTexture(gfx->newTextureFromFile(normPath));
94 static ParticleReloader reloader;
bool reloadConfigFile(ParticleEmitter *emitter, std::string *error)
Re-read Resource.path if set; updates modtime.