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";
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);
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)
continue;
81 const bool albedo = !res->texturePath.empty() &&
normalize(res->texturePath) == normPath;
82 const bool normal = !res->normalTexturePath.empty() &&
normalize(res->normalTexturePath) == normPath;
85 auto* texture = gfx->newTextureFromFile(normPath);
86 if (
albedo) cfg->entity->setTexture(texture);
87 if (
normal) cfg->entity->setNormalTexture(texture);
98 static ParticleReloader reloader;
99 eve::cap::addListener<eve::caps::IAssetReloader>(&reloader,
graphics::Texture * albedo
Move-only operation result carrying either a value or Status.
static Result success(T value)
Construct a successful result owning value.
EVENGINE_API_FOUNDATION public API.
bool reloadConfigFile(ParticleEmitter *emitter, std::string *error)
Re-read Resource.path if set; updates modtime.
Vec2 normalize(const Vec2 &a)
Normalize.