mapeditor/rs-tiled

Allow obtaining the path of tilemaps that have been loaded

LuckyTurtleDev opened this issue · 9 comments

I would like to get the path of the tileset used at the map.
But it does look like Tileset does not provide this option.

You're right, this isn't possible currently. But since the path depends on the reader/cache used, it maybe makes more sense to include this as a ResourceCache method. Nevermind, as this would limit obtaining it only to intermediate resources. Perhaps it is OK to just store the path in Tileset.

bjorn commented

I don't really like the idea of adding the path to the Tileset struct, because I think it doesn't really belong there and for most use-cases it is enough to just be able to look up tilesets by their path in the ResourceCache. However, for those cases where you do need the path I have to admit that I don't know a nice alternative either and I have solved this issue the same way in Tiled itself.

@LuckyTurtleDev Just out of curiosity, what use-case do you have where you need to know the path?

BTW you theorically could create your own ResourceLoader and log the path of each tileset loaded that way.

@LuckyTurtleDev Just out of curiosity, what use-case do you have where you need to know the path?

@bjorn I have writen a proc macro, with does convert the tiled map to a more easy app internal map format and check some requirements at compile time.
This macro must rerun every time the map files has change. Regular this does not happen because the macro is cached.
But if you use the include_bytes!() macro inside your proc macro rust does automatically start watching the file and rerun the whole proc macro if the file has changed.

For the the main tmx map you can simple use the path from the input of the proc macro.

const _: &[u8] = ::core::include_bytes!(#path);

But this can not be done for the tileset, because the macro do not know where they are stored.
Currently I am using a workaround, to simple include all tileset of the workspace:

let mut tileset = quote!();
	for path in glob("./**/*.tsx").unwrap() {
		let path = path.unwrap().canonicalize().unwrap();
		let path = path.to_str().unwrap();
		tileset = quote! {
		#tileset;
		const _: &[u8] = ::core::include_bytes!(#path)
		}
	}

Have you considered using a build script insead to convert your maps? You can select when to rerun it, and you won't need any macro usage in your app code.

Have you considered using a build script insead to convert your maps?

I personal prefer using macros, because you can easier see, where the generated code is included. A build script instead does write in some "random" files and is run every time if I compile something.

However the current workaround does work for me.

After refactoring my sokoban clone I had the same issue here. I've thought about it once again and I don't see much issue in adding a source member that just stores the path that the ResourceReader first used to load the tileset/map. While it is true it doesn't really belong there it's really convenient to store the source for later use.

@aleokdev Yeah, feel free to just add it!

Done in #303. Will close on next release