diff --git a/README.md b/README.md index a2f8002..41b163f 100644 --- a/README.md +++ b/README.md @@ -29,9 +29,15 @@ Load a TMX file into a string by any means, and then pass the string to TileMapP final TiledMap mapTmx = TileMapParser.parseTmx(tmxBody); ``` -If your tmx file includes a external tsx reference, you have to add a CustomParser +If your tmx file includes a external tsx reference, you have to add a CustomParser. This can either be done by using extending the TsxProviderBase, which can match multiple files, or by extending TsxProvider, which only matches on file by its name. ```dart -class CustomTsxProvider extends TsxProvider { +class MultipleTsxProvider extends TsxProviderBase { + @override + bool checkProvidable(String filename) => ["external1.tsx", "external2.tsx"].contains(filename); + + @override + Parser? getCachedSource(String filename) => null; + @override Parser getSource(String fileName) { final xml = File(fileName).readAsStringSync(); @@ -40,6 +46,23 @@ class CustomTsxProvider extends TsxProvider { } } ``` + +```dart +class SingleTsxProvider extends TsxProvider { + @override + String get filename => "external.tsx"; + + @override + Parser? getCachedSource() => null; + + @override + Parser getSource(String _) { + final xml = File(filename).readAsStringSync(); + final node = XmlDocument.parse(xml).rootElement; + return XmlParser(node); + } +} +``` And use it in the parseTmx method ```dart final String tmxBody = /* ... */; diff --git a/packages/tiled/lib/src/tile_map_parser.dart b/packages/tiled/lib/src/tile_map_parser.dart index 7c9b032..fcc37e5 100644 --- a/packages/tiled/lib/src/tile_map_parser.dart +++ b/packages/tiled/lib/src/tile_map_parser.dart @@ -10,7 +10,7 @@ class TileMapParser { /// /// Accepts an optional list of external TsxProviders for external tilesets /// referenced in the map file. - static TiledMap parseTmx(String xml, {List? tsxList}) { + static TiledMap parseTmx(String xml, {List? tsxList}) { final xmlElement = XmlDocument.parse(xml).rootElement; if (xmlElement.name.local != 'map') { throw 'XML is not in TMX format'; diff --git a/packages/tiled/lib/src/tiled_map.dart b/packages/tiled/lib/src/tiled_map.dart index 8576d1b..d7210e2 100644 --- a/packages/tiled/lib/src/tiled_map.dart +++ b/packages/tiled/lib/src/tiled_map.dart @@ -286,7 +286,7 @@ class TiledMap { ); } - factory TiledMap.parse(Parser parser, {List? tsxList}) { + factory TiledMap.parse(Parser parser, {List? tsxList}) { final backgroundColorHex = parser.getStringOrNull('backgroundcolor'); final backgroundColor = parser.getColorOrNull('backgroundcolor'); final compressionLevel = parser.getInt('compressionlevel', defaults: -1); @@ -317,7 +317,7 @@ class TiledMap { return Tileset.parse(tilesetData); } final matchingTsx = tsxList.where( - (tsx) => tsx.filename == tilesetSource, + (tsx) => tsx.checkProvidable(tilesetSource), ); return Tileset.parse( diff --git a/packages/tiled/lib/src/tileset/tileset.dart b/packages/tiled/lib/src/tileset/tileset.dart index 49d64f3..0df3ada 100644 --- a/packages/tiled/lib/src/tileset/tileset.dart +++ b/packages/tiled/lib/src/tileset/tileset.dart @@ -103,7 +103,7 @@ class Tileset { tileCount = this.tiles.length; } - factory Tileset.parse(Parser parser, {TsxProvider? tsx}) { + factory Tileset.parse(Parser parser, {TsxProviderBase? tsx}) { final backgroundColor = parser.getStringOrNull('backgroundcolor'); final columns = parser.getIntOrNull('columns'); final firstGid = parser.getIntOrNull('firstgid'); @@ -169,10 +169,10 @@ class Tileset { return result; } - void _checkIfExternalTsx(String? source, TsxProvider? tsx) { + void _checkIfExternalTsx(String? source, TsxProviderBase? tsx) { if (tsx != null && source != null) { final tileset = Tileset.parse( - tsx.getCachedSource() ?? tsx.getSource(source), + tsx.getCachedSourceBase(source) ?? tsx.getSourceBase(source), ); // Copy attributes if not null backgroundColor = tileset.backgroundColor ?? backgroundColor; diff --git a/packages/tiled/lib/src/tsx_provider.dart b/packages/tiled/lib/src/tsx_provider.dart index 5868e02..c408321 100644 --- a/packages/tiled/lib/src/tsx_provider.dart +++ b/packages/tiled/lib/src/tsx_provider.dart @@ -1,18 +1,44 @@ part of tiled; /// abstract class to be implemented for an external tileset data provider. -abstract class TsxProvider { +abstract class TsxProviderBase { + /// Given a filename this function should check whether this Provider + /// can provide this source. + bool checkProvidable(String filename); + + /// Retrieves the external tileset data given the tileset filename. + Parser getSourceBase(String filename); + + /// Used when provider implementations cache the data. Returns the cached + /// data for the external tileset by filename. + Parser? getCachedSourceBase(String filename); +} + +/// abstract convenience class to be implemented for an external tileset data +/// provider, which only provides one file and can therefore be matched by the +/// filename alone. +abstract class TsxProvider extends TsxProviderBase { /// Unique filename for the tileset to be loaded. This should match the - /// 'source' property in the map.tmx file. + /// 'source' property in the map.tmx file. This is used to check if this + /// Provider can provide a source! String get filename; - /// Retrieves the external tileset data given the tileset filename. - Parser getSource(String filename); + @override + bool checkProvidable(String filename) => filename == this.filename; /// Used when provider implementations cache the data. Returns the cached /// data for the exernal tileset. Parser? getCachedSource(); + @override + Parser? getCachedSourceBase(String _) => getCachedSource(); + + /// Retrieves the external tileset data given the tileset filename. + Parser getSource(String filename); + + @override + Parser getSourceBase(String filename) => getSource(filename); + /// Parses a file returning a [TsxProvider]. static Future parse(String key) { throw UnimplementedError();