Skip to content

Commit da5ad67

Browse files
benni-tecspydon
benni-tec
authored andcommitted
added providers to Parser // implemented provider for templates // adjusted tests
1 parent b201831 commit da5ad67

File tree

8 files changed

+115
-55
lines changed

8 files changed

+115
-55
lines changed

packages/tiled/lib/src/layer.dart

+5-2
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ abstract class Layer {
112112
this.properties = CustomProperties.empty,
113113
});
114114

115-
static Layer parse(Parser parser) {
115+
static Layer parse(Parser parser, {List<ParserProvider>? templateProviders}) {
116116
final type = parser.formatSpecificParsing(
117117
(json) => json.getLayerType('type'),
118118
(xml) => LayerTypeExtension.parseFromTmx(xml.element.name.toString()),
@@ -272,7 +272,10 @@ abstract class Layer {
272272

273273
static List<Layer> parseLayers(Parser parser) {
274274
return parser.formatSpecificParsing(
275-
(json) => json.getChildrenAs('layers', Layer.parse),
275+
(json) => json.getChildrenAs(
276+
'layers',
277+
Layer.parse,
278+
),
276279
(xml) {
277280
// It's very important not change the order of the layers
278281
// during parsing!

packages/tiled/lib/src/objects/tiled_object.dart

+21-2
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,9 @@ class TiledObject {
5959
bool point;
6060
bool rectangle;
6161

62+
String? templatePath;
6263
Template? template;
64+
6365
Text? text;
6466
bool visible;
6567

@@ -84,6 +86,7 @@ class TiledObject {
8486
this.ellipse = false,
8587
this.point = false,
8688
this.rectangle = false,
89+
this.templatePath,
8790
this.template,
8891
this.text,
8992
this.visible = true,
@@ -93,12 +96,17 @@ class TiledObject {
9396
});
9497

9598
bool get isPolyline => polyline.isNotEmpty;
99+
96100
bool get isPolygon => polygon.isNotEmpty;
101+
97102
bool get isPoint => point;
103+
98104
bool get isEllipse => ellipse;
105+
99106
bool get isRectangle => rectangle;
100107

101-
factory TiledObject.parse(Parser parser) {
108+
factory TiledObject.parse(
109+
Parser parser) {
102110
final x = parser.getDouble('x', defaults: 0);
103111
final y = parser.getDouble('y', defaults: 0);
104112
final height = parser.getDouble('height', defaults: 0);
@@ -126,7 +134,17 @@ class TiledObject {
126134
(xml) => xml.getChildren('point').isNotEmpty,
127135
);
128136
final text = parser.getSingleChildOrNullAs('text', Text.parse);
129-
final template = parser.getSingleChildOrNullAs('template', Template.parse);
137+
final templatePath = parser.getStringOrNull('template');
138+
final templateProvider = templatePath == null
139+
? null
140+
: parser.templateProviders?.firstWhere((e) => e.canProvide(templatePath));
141+
final template = templateProvider == null
142+
? null
143+
: Template.parse(
144+
templateProvider.getCachedSource(templatePath!) ??
145+
templateProvider.getSource(templatePath),
146+
);
147+
130148
final properties = parser.getProperties();
131149

132150
final polygon = parsePointList(parser, 'polygon');
@@ -147,6 +165,7 @@ class TiledObject {
147165
ellipse: ellipse,
148166
point: point,
149167
rectangle: rectangle,
168+
templatePath: templatePath,
150169
template: template,
151170
text: text,
152171
visible: visible,

packages/tiled/lib/src/parser.dart

+44-9
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,18 @@ class ParsingException implements Exception {
1111
class XmlParser extends Parser {
1212
final XmlElement element;
1313

14-
XmlParser(this.element);
15-
16-
factory XmlParser.fromString(String string) =>
17-
XmlParser(XmlDocument.parse(string).rootElement);
14+
XmlParser(this.element, {super.tsxProviders, super.templateProviders});
15+
16+
factory XmlParser.fromString(
17+
String string, {
18+
List<ParserProvider>? tsxProviders,
19+
List<ParserProvider>? templateProviders,
20+
}) =>
21+
XmlParser(
22+
XmlDocument.parse(string).rootElement,
23+
tsxProviders: tsxProviders,
24+
templateProviders: templateProviders,
25+
);
1826

1927
@override
2028
String? getInnerTextOrNull() =>
@@ -30,15 +38,23 @@ class XmlParser extends Parser {
3038
return element.children
3139
.whereType<XmlElement>()
3240
.where((e) => e.name.local == name)
33-
.map(XmlParser.new)
41+
.map((e) => XmlParser(
42+
e,
43+
templateProviders: templateProviders,
44+
tsxProviders: tsxProviders,
45+
))
3446
.toList();
3547
}
3648

3749
List<Parser> getChildrenWithNames(Set<String> names) {
3850
return element.children
3951
.whereType<XmlElement>()
4052
.where((e) => names.contains(e.name.local))
41-
.map(XmlParser.new)
53+
.map((e) => XmlParser(
54+
e,
55+
tsxProviders: tsxProviders,
56+
templateProviders: templateProviders,
57+
))
4258
.toList();
4359
}
4460

@@ -54,8 +70,18 @@ class XmlParser extends Parser {
5470
class JsonParser extends Parser {
5571
final Map<String, dynamic> json;
5672

57-
JsonParser(this.json);
58-
factory JsonParser.fromString(String string) => JsonParser(jsonDecode(string) as Map<String, dynamic>);
73+
JsonParser(this.json, {super.tsxProviders, super.templateProviders});
74+
75+
factory JsonParser.fromString(
76+
String string, {
77+
List<ParserProvider>? tsxProviders,
78+
List<ParserProvider>? templateProviders,
79+
}) =>
80+
JsonParser(
81+
jsonDecode(string) as Map<String, dynamic>,
82+
tsxProviders: tsxProviders,
83+
templateProviders: templateProviders,
84+
);
5985

6086
@override
6187
String? getInnerTextOrNull() => null;
@@ -71,7 +97,11 @@ class JsonParser extends Parser {
7197
return [];
7298
}
7399
return (json[name] as List<dynamic>)
74-
.map((dynamic e) => JsonParser(e as Map<String, dynamic>))
100+
.map((dynamic e) => JsonParser(
101+
e as Map<String, dynamic>,
102+
templateProviders: templateProviders,
103+
tsxProviders: tsxProviders,
104+
))
75105
.toList();
76106
}
77107

@@ -89,6 +119,11 @@ class JsonParser extends Parser {
89119
}
90120

91121
abstract class Parser {
122+
final List<ParserProvider>? templateProviders;
123+
final List<ParserProvider>? tsxProviders;
124+
125+
Parser({this.tsxProviders, this.templateProviders});
126+
92127
String? getInnerTextOrNull();
93128

94129
String? getStringOrNull(String name, {String? defaults});

packages/tiled/lib/src/provider.dart

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
part of tiled;
22

33
abstract class Provider<T> {
4-
bool canProvide(String filename);
4+
bool canProvide(String path);
55

6-
T getSource(String filename);
7-
T? getCachedSource(String filename);
6+
T getSource(String path);
7+
T? getCachedSource(String path);
88
}
99

1010
typedef ParserProvider = Provider<Parser>;

packages/tiled/lib/src/template.dart

+4
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,7 @@ class Template {
3434
object: parser.getSingleChildOrNullAs('object', TiledObject.parse),
3535
);
3636
}
37+
38+
class TemplateReference {
39+
40+
}

packages/tiled/lib/src/tiled_map.dart

+18-16
Original file line numberDiff line numberDiff line change
@@ -314,40 +314,41 @@ class TiledMap {
314314
);
315315
}
316316

317-
static TiledMap parseJson(String json) {
318-
final parser = JsonParser(jsonDecode(json) as Map<String, dynamic>);
317+
static TiledMap parseJson(
318+
String json, {
319+
List<ParserProvider>? tsxProviders,
320+
List<ParserProvider>? templateProviders,
321+
}) {
322+
final parser = JsonParser(
323+
jsonDecode(json) as Map<String, dynamic>,
324+
templateProviders: templateProviders,
325+
tsxProviders: tsxProviders,
326+
);
319327
return TiledMap.parse(parser);
320328
}
321329

322330
/// Parses the provided map xml.
323331
///
324332
/// Accepts an optional list of external TsxProviders for external tilesets
325333
/// referenced in the map file.
326-
static TiledMap parseTmx(
334+
factory TiledMap.parseTmx(
327335
String xml, {
328336
List<ParserProvider>? tsxProviders,
329337
List<ParserProvider>? templateProviders,
330-
List<ImagePathProvider>? imageProviders,
331338
}) {
332339
final xmlElement = XmlDocument.parse(xml).rootElement;
333340
if (xmlElement.name.local != 'map') {
334341
throw 'XML is not in TMX format';
335342
}
336-
final parser = XmlParser(xmlElement);
337-
return TiledMap.parse(
338-
parser,
343+
final parser = XmlParser(
344+
xmlElement,
339345
tsxProviders: tsxProviders,
340346
templateProviders: templateProviders,
341-
imageProviders: imageProviders,
342347
);
348+
return TiledMap.parse(parser);
343349
}
344350

345-
factory TiledMap.parse(
346-
Parser parser, {
347-
List<ParserProvider>? tsxProviders,
348-
List<ParserProvider>? templateProviders,
349-
List<ImagePathProvider>? imageProviders,
350-
}) {
351+
factory TiledMap.parse(Parser parser) {
351352
final backgroundColorHex = parser.getStringOrNull('backgroundcolor');
352353
final backgroundColor = parser.getColorOrNull('backgroundcolor');
353354
final compressionLevel = parser.getInt('compressionlevel', defaults: -1);
@@ -374,10 +375,11 @@ class TiledMap {
374375
'tileset',
375376
(tilesetData) {
376377
final tilesetSource = tilesetData.getStringOrNull('source');
377-
if (tilesetSource == null || tsxProviders == null) {
378+
if (tilesetSource == null || parser.tsxProviders == null) {
378379
return Tileset.parse(tilesetData);
379380
}
380-
final matchingTsx = tsxProviders.where(
381+
382+
final matchingTsx = parser.tsxProviders!.where(
381383
(tsx) => tsx.canProvide(tilesetSource),
382384
);
383385

packages/tiled/lib/src/tileset/tile.dart

+5-3
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class Tile {
5050
/// Will be same as [type].
5151
String? get class_ => type;
5252

53-
Tile.parse(Parser parser)
53+
Tile.parse(Parser parser, {List<ParserProvider>? templateProviders})
5454
: this(
5555
localId: parser.getInt('id'),
5656

@@ -72,8 +72,10 @@ class Tile {
7272
parser.getDoubleOrNull('width') ?? 0,
7373
parser.getDoubleOrNull('height') ?? 0,
7474
),
75-
objectGroup:
76-
parser.getSingleChildOrNullAs('objectgroup', Layer.parse),
75+
objectGroup: parser.getSingleChildOrNullAs(
76+
'objectgroup',
77+
(e) => Layer.parse(e, templateProviders: templateProviders),
78+
),
7779
animation: parser.formatSpecificParsing(
7880
(json) => json.getChildrenAs('animation', Frame.parse),
7981
(xml) =>

packages/tiled/test/parser_test.dart

+15-20
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ void main() {
255255
return File('./test/fixtures/map_images.tmx').readAsString().then((xml) {
256256
map = TiledMap.parseTmx(
257257
xml,
258-
tsxProviders: [FixtureTsxProvider.all('./test/fixtures')],
258+
tsxProviders: [FixtureTsxProvider.all()],
259259
);
260260
});
261261
});
@@ -316,7 +316,7 @@ void main() {
316316
.then((xml) {
317317
final map = TiledMap.parseTmx(
318318
xml,
319-
tsxProviders: [FixtureTsxProvider.all('./test/fixtures')],
319+
tsxProviders: [FixtureTsxProvider.all()],
320320
);
321321
expect(map.tilesets[0].tileCount, 137);
322322
final tile = map.tileByGid(1)!;
@@ -331,7 +331,7 @@ void main() {
331331
return File('./test/fixtures/map_images.tmx').readAsString().then((xml) {
332332
map = TiledMap.parseTmx(
333333
xml,
334-
tsxProviders: [FixtureTsxProvider.all('./test/fixtures')],
334+
tsxProviders: [FixtureTsxProvider.all()],
335335
);
336336
expect(
337337
map.tilesetByName('external').image!.source,
@@ -346,7 +346,7 @@ void main() {
346346
return File('./test/fixtures/map_images.tmx').readAsString().then((xml) {
347347
map = TiledMap.parseTmx(
348348
xml,
349-
tsxProviders: [FixtureTsxProvider.all('./test/fixtures')],
349+
tsxProviders: [FixtureTsxProvider.all()],
350350
);
351351
expect(map.layers.length, equals(2));
352352
});
@@ -361,7 +361,7 @@ void main() {
361361
.then((xml) {
362362
map = TiledMap.parseTmx(
363363
xml,
364-
tsxProviders: [FixtureTsxProvider.all('./test/fixtures')],
364+
tsxProviders: [FixtureTsxProvider.all()],
365365
);
366366
return;
367367
});
@@ -434,7 +434,7 @@ class FixtureTsxProvider extends ParserProvider {
434434

435435
FixtureTsxProvider(this.root, this.files);
436436

437-
factory FixtureTsxProvider.all(String directory) {
437+
factory FixtureTsxProvider.all([String directory = './test/fixtures']) {
438438
final dir = Directory(directory);
439439
if (!dir.existsSync()) {
440440
throw '[FixtureTsxProvider] Supplied directory does not exist!';
@@ -447,27 +447,22 @@ class FixtureTsxProvider extends ParserProvider {
447447
.map((e) => paths.basename(e.path))
448448
.toList();
449449

450-
return FixtureTsxProvider(directory, names);
451-
}
452-
453-
factory FixtureTsxProvider.file(String path) {
454-
final file = File(path);
455-
if (!file.existsSync()) {
456-
throw '[FixtureTsxProvider] Supplied path does not match any file!';
457-
}
458-
459-
return FixtureTsxProvider(paths.dirname(path), [paths.basename(path)]);
450+
return FixtureTsxProvider(paths.absolute(directory), names);
460451
}
461452

462453
final Map<String, String> cache = {};
463454

464455
@override
465-
bool canProvide(String filename) => true;
456+
bool canProvide(String filename) {
457+
return files.contains(filename);
458+
}
466459

467460
@override
468-
Parser? getCachedSource(String filename) => cache.containsKey(filename)
469-
? XmlParser.fromString(cache[filename]!)
470-
: null;
461+
Parser? getCachedSource(String filename) {
462+
return cache.containsKey(filename)
463+
? XmlParser.fromString(cache[filename]!)
464+
: null;
465+
}
471466

472467
@override
473468
Parser getSource(String filename) {

0 commit comments

Comments
 (0)