diff --git a/README.md b/README.md index 874776a..f12fb70 100644 --- a/README.md +++ b/README.md @@ -26,14 +26,19 @@ Load a TMX file into a string by any means, and then pass the string to TileMapP ```dart final String tmxBody = /* ... */; - final TiledMap mapTmx = TileMapParser.parseTmx(tmxBody); + final TiledMap mapTmx = TiledMap.parseTmx(tmxBody); ``` -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. +If your tmx file includes external reference, e.g. for .tsx files, you have to add providers. +These providers are then used to find these files and load their contents as a string, +as well as maybe caching them. + +To construct a provider for tsx files for example you can just extend the Provider +or ParserProvider class, which is just a type alias. ```dart -class MultipleTsxProvider extends TsxProviderBase { +class MultipleTsxProvider extends ParserProvider { @override - bool checkProvidable(String filename) => ["external1.tsx", "external2.tsx"].contains(filename); + bool canProvide(String filename) => ["external1.tsx", "external2.tsx"].contains(filename); @override Parser? getCachedSource(String filename) => null; @@ -47,34 +52,64 @@ class MultipleTsxProvider extends TsxProviderBase { } ``` +If, for example, all your tsx files are in one directory, +adding only one RelativeTsxProvider can allow the Parser to find all of them. + ```dart -class SingleTsxProvider extends TsxProvider { +class RelativeTsxProvider extends TsxProviderBase { + final String root; + + RelativeTsxProvider(this.root); + @override - String get filename => "external.tsx"; - + bool canProvide(String filename) { + if (cache.containsKey(filename)) return true; + + final exists = File(paths.join(root, filename)).existsSync(); + if (exists) cache[filename] = null; + + return exists; + } + + Map cache = {}; + @override - Parser? getCachedSource() => null; - + Parser? getCachedSource(String filename) => cache[filename]; + @override - Parser getSource(String _) { - final xml = File(filename).readAsStringSync(); - final node = XmlDocument.parse(xml).rootElement; - return XmlParser(node); + Parser getSource(String filename) { + final xml = XmlDocument.parse(File(paths.join(root, filename)).readAsStringSync()); + final element = xml.getElement("tileset"); + if (element == null) { + throw ParsingException( + "tileset", + null, + "This tsx file does not seem to contain a top-level tileset tag", + ); + } + + cache[filename] = XmlParser(element); + return cache[filename]!; } } ``` -And use it in the parseTmx method. Keep in mind that the first TsxProvider that can provide a source is used! + +These providers are passed to the parseTmx or parseJson method. +Keep in mind that the first Provider that can provide a source is used! + ```dart final String tmxBody = /* ... */; - final TiledMap mapTmx = TileMapParser.parseTmx(tmxBody, tsxProviders: [SingleTsxProvider(), MultipleTsxProvider()]); - + final TiledMap mapTmx = TiledMap.parseTmx( + tmxBody, + tsxProviders: [SingleTsxProvider(), MultipleTsxProvider()], + ); ``` ### Load Json Files Alternatively load a json file. ```dart final String jsonBody = /* ... */; - final TiledMap mapTmx = TileMapParser.parseJson(jsonBody); + final TiledMap mapTmx = TiledMap.parseJson(jsonBody); ``` ### Implementation diff --git a/packages/tiled/lib/src/common/property.dart b/packages/tiled/lib/src/common/property.dart index 45ff173..bf07bb0 100644 --- a/packages/tiled/lib/src/common/property.dart +++ b/packages/tiled/lib/src/common/property.dart @@ -37,7 +37,7 @@ class Property { case PropertyType.color: return ColorProperty( name: name, - value: parser.getColor('value', defaults: ColorData.hex(0x00000000)), + value: parser.getColor('value', defaults: const ColorData.hex(0x00000000)), hexValue: parser.getString('value', defaults: '#00000000'), ); diff --git a/packages/tiled/lib/src/parser.dart b/packages/tiled/lib/src/parser.dart index c56a9df..673c9d0 100644 --- a/packages/tiled/lib/src/parser.dart +++ b/packages/tiled/lib/src/parser.dart @@ -13,16 +13,10 @@ class XmlParser extends Parser { XmlParser(this.element, {super.tsxProviders, super.templateProviders}); - factory XmlParser.fromString( - String string, { - List? tsxProviders, - List? templateProviders, - }) => - XmlParser( - XmlDocument.parse(string).rootElement, - tsxProviders: tsxProviders, - templateProviders: templateProviders, - ); + XmlParser.fromString(String string, { + super.tsxProviders, + super.templateProviders, + }) : element = XmlDocument.parse(string).rootElement; @override String? getInnerTextOrNull() => @@ -61,7 +55,7 @@ class XmlParser extends Parser { @override T formatSpecificParsing( T Function(JsonParser) json, - T Function(XmlParser) xml, + T Function(XmlParser) xml ) { return xml(this); } @@ -72,16 +66,9 @@ class JsonParser extends Parser { JsonParser(this.json, {super.tsxProviders, super.templateProviders}); - factory JsonParser.fromString( - String string, { - List? tsxProviders, - List? templateProviders, - }) => - JsonParser( - jsonDecode(string) as Map, - tsxProviders: tsxProviders, - templateProviders: templateProviders, - ); + JsonParser.fromString(String string, { + super.tsxProviders, super.templateProviders, + }) : json = jsonDecode(string) as Map; @override String? getInnerTextOrNull() => null; diff --git a/packages/tiled/lib/src/template.dart b/packages/tiled/lib/src/template.dart index 3fc77a3..b0ac9c5 100644 --- a/packages/tiled/lib/src/template.dart +++ b/packages/tiled/lib/src/template.dart @@ -34,7 +34,3 @@ class Template { object: parser.getSingleChildOrNullAs('object', TiledObject.parse), ); } - -class TemplateReference { - -} \ No newline at end of file diff --git a/packages/tiled/lib/src/tiled_map.dart b/packages/tiled/lib/src/tiled_map.dart index 11a5efd..46a60c0 100644 --- a/packages/tiled/lib/src/tiled_map.dart +++ b/packages/tiled/lib/src/tiled_map.dart @@ -124,36 +124,6 @@ class TiledMap { this.properties = CustomProperties.empty, }); - /// Takes a string [contents] and converts it to a [TiledMap] with the help of - /// the [TsxProvider]s returned from the [tsxProviderFunction]. - /// The [tsxProviderFunction] is most commonly your static [TsxProvider.parse] - /// implementation. - // TODO: why is this here? same as parseTmx??? - // static Future fromString( - // String contents, { - // List? tsxProviders, - // List? templateProviders, - // List? imageProviders, - // }) async { - // final tsxSourcePaths = XmlDocument.parse(contents) - // .rootElement - // .children - // .whereType() - // .where((element) => element.name.local == 'tileset') - // .map((e) => e.getAttribute('source')); - // - // final tsxProviders = await Future.wait( - // tsxSourcePaths - // .where((key) => key != null) - // .map((key) async => tsxProviderFunction(key!)), - // ); - // - // return TileMapParser.parseTmx( - // contents, - // tsxList: tsxProviders.isEmpty ? null : tsxProviders, - // ); - // } - // Convenience Methods Tile? tileByGid(int tileGid) { if (tileGid == 0) { @@ -314,7 +284,11 @@ class TiledMap { ); } - static TiledMap parseJson( + /// Parses the provided json. + /// + /// Accepts an optional list of external TsxProviders for external tilesets + /// referenced in the map file. + factory TiledMap.parseJson( String json, { List? tsxProviders, List? templateProviders,