rs-tiled icon indicating copy to clipboard operation
rs-tiled copied to clipboard

Allow obtaining the path of tilemaps that have been loaded

Open LuckyTurtleDev opened this issue 1 year ago • 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.

LuckyTurtleDev avatar May 03 '23 10:05 LuckyTurtleDev

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.

aleokdev avatar May 03 '23 10:05 aleokdev

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?

bjorn avatar May 04 '23 08:05 bjorn

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

aleokdev avatar May 04 '23 08:05 aleokdev

@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)
		}
	}

LuckyTurtleDev avatar May 04 '23 10:05 LuckyTurtleDev

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.

aleokdev avatar May 04 '23 11:05 aleokdev

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.

LuckyTurtleDev avatar May 19 '23 17:05 LuckyTurtleDev

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 avatar Jun 19 '24 21:06 aleokdev

@aleokdev Yeah, feel free to just add it!

bjorn avatar Jun 20 '24 08:06 bjorn

Done in #303. Will close on next release

aleokdev avatar Jun 21 '24 16:06 aleokdev