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 "tilemap"; }
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<TileLayer>() ==
nullptr)
return false;
56 return isImagePath(normPath) ? rebindTileset(normPath) : reloadConfig(normPath);
60 static bool reloadConfig(
const std::string &normPath) {
62 auto view = ecs::View<TileLayer, TileLayer::Config, TileLayer::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 rebindTileset(
const std::string &normPath) {
73 auto *gfx = eve::ModuleManager::getInstance<eve::graphics::Graphics>(
"Graphics");
74 if (!gfx)
return false;
77 auto view = ecs::View<TileLayer, TileLayer::Config, TileLayer::Resource, TileLayer::Tileset>();
78 for (
auto it =
view.begin(); it !=
view.end(); ++it) {
79 auto [cfg, res, ts] = *it;
80 if (!cfg->entity || res->texturePath.empty())
continue;
81 if (normalize(res->texturePath) != normPath)
continue;
83 cfg->entity->setTileset(gfx->newTextureFromFile(normPath), ts->firstGid,
84 ts->columns, ts->margin, ts->spacing);
95 static TileLayerReloader reloader;
放置世界:格子占用(多通道)+ 地形语义 + 已放置建筑实例。 行为由 PlacementSystem 提供;本类暴露便于脚本绑定的薄封装方法。 坐标换算统一走 eve::grid(支持 rectang...
bool reloadConfigFile(TileLayer *layer, std::string *error)