Skip to content

Commit

Permalink
rebased and some fine tuning
Browse files Browse the repository at this point in the history
  • Loading branch information
benni-tec committed Dec 21, 2024
1 parent 45a99af commit 7ec1e65
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 74 deletions.
69 changes: 52 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<Parser>
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;
Expand All @@ -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<String, Parser?> 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
Expand Down
2 changes: 1 addition & 1 deletion packages/tiled/lib/src/common/property.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class Property<T> {
case PropertyType.color:
return ColorProperty(
name: name,
value: parser.getColor('value', defaults: ColorData.hex(0x00000000)),
value: parser.getColor('value', defaults: const ColorData.hex(0x00000000)),

Check notice on line 40 in packages/tiled/lib/src/common/property.dart

View workflow job for this annotation

GitHub Actions / analyze

The line length exceeds the 80-character limit.

Try breaking the line across multiple lines. See https://dart.dev/lints/lines_longer_than_80_chars to learn more about this problem.
hexValue: parser.getString('value', defaults: '#00000000'),
);

Expand Down
29 changes: 8 additions & 21 deletions packages/tiled/lib/src/parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,10 @@ class XmlParser extends Parser {

XmlParser(this.element, {super.tsxProviders, super.templateProviders});

factory XmlParser.fromString(
String string, {
List<ParserProvider>? tsxProviders,
List<ParserProvider>? 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() =>
Expand Down Expand Up @@ -61,7 +55,7 @@ class XmlParser extends Parser {
@override
T formatSpecificParsing<T>(
T Function(JsonParser) json,
T Function(XmlParser) xml,
T Function(XmlParser) xml
) {
return xml(this);
}
Expand All @@ -72,16 +66,9 @@ class JsonParser extends Parser {

JsonParser(this.json, {super.tsxProviders, super.templateProviders});

factory JsonParser.fromString(
String string, {
List<ParserProvider>? tsxProviders,
List<ParserProvider>? templateProviders,
}) =>
JsonParser(
jsonDecode(string) as Map<String, dynamic>,
tsxProviders: tsxProviders,
templateProviders: templateProviders,
);
JsonParser.fromString(String string, {
super.tsxProviders, super.templateProviders,
}) : json = jsonDecode(string) as Map<String, dynamic>;

@override
String? getInnerTextOrNull() => null;
Expand Down
4 changes: 0 additions & 4 deletions packages/tiled/lib/src/template.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,3 @@ class Template {
object: parser.getSingleChildOrNullAs('object', TiledObject.parse),
);
}

class TemplateReference {

}
36 changes: 5 additions & 31 deletions packages/tiled/lib/src/tiled_map.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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<TiledMap> fromString(
// String contents, {
// List<ParserProvider>? tsxProviders,
// List<ParserProvider>? templateProviders,
// List<ImagePathProvider>? imageProviders,
// }) async {
// final tsxSourcePaths = XmlDocument.parse(contents)
// .rootElement
// .children
// .whereType<XmlElement>()
// .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) {
Expand Down Expand Up @@ -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<ParserProvider>? tsxProviders,
List<ParserProvider>? templateProviders,
Expand Down

0 comments on commit 7ec1e65

Please sign in to comment.