Skip to content

Commit 838bb52

Browse files
author
benni-tec
committed
added providers to Parser // implemented provider for templates // adjusted tests
1 parent 6bf2527 commit 838bb52

File tree

8 files changed

+115
-55
lines changed

8 files changed

+115
-55
lines changed

packages/tiled/lib/src/layer.dart

Lines changed: 5 additions & 2 deletions
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

Lines changed: 21 additions & 2 deletions
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

Lines changed: 44 additions & 9 deletions
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? getStringOrNull(String name, {String? defaults}) {
@@ -26,15 +34,23 @@ class XmlParser extends Parser {
2634
return element.children
2735
.whereType<XmlElement>()
2836
.where((e) => e.name.local == name)
29-
.map(XmlParser.new)
37+
.map((e) => XmlParser(
38+
e,
39+
templateProviders: templateProviders,
40+
tsxProviders: tsxProviders,
41+
))
3042
.toList();
3143
}
3244

3345
List<Parser> getChildrenWithNames(Set<String> names) {
3446
return element.children
3547
.whereType<XmlElement>()
3648
.where((e) => names.contains(e.name.local))
37-
.map(XmlParser.new)
49+
.map((e) => XmlParser(
50+
e,
51+
tsxProviders: tsxProviders,
52+
templateProviders: templateProviders,
53+
))
3854
.toList();
3955
}
4056

@@ -50,8 +66,18 @@ class XmlParser extends Parser {
5066
class JsonParser extends Parser {
5167
final Map<String, dynamic> json;
5268

53-
JsonParser(this.json);
54-
factory JsonParser.fromString(String string) => JsonParser(jsonDecode(string) as Map<String, dynamic>);
69+
JsonParser(this.json, {super.tsxProviders, super.templateProviders});
70+
71+
factory JsonParser.fromString(
72+
String string, {
73+
List<ParserProvider>? tsxProviders,
74+
List<ParserProvider>? templateProviders,
75+
}) =>
76+
JsonParser(
77+
jsonDecode(string) as Map<String, dynamic>,
78+
tsxProviders: tsxProviders,
79+
templateProviders: templateProviders,
80+
);
5581

5682
@override
5783
String? getStringOrNull(String name, {String? defaults}) {
@@ -64,7 +90,11 @@ class JsonParser extends Parser {
6490
return [];
6591
}
6692
return (json[name] as List<dynamic>)
67-
.map((dynamic e) => JsonParser(e as Map<String, dynamic>))
93+
.map((dynamic e) => JsonParser(
94+
e as Map<String, dynamic>,
95+
templateProviders: templateProviders,
96+
tsxProviders: tsxProviders,
97+
))
6898
.toList();
6999
}
70100

@@ -82,6 +112,11 @@ class JsonParser extends Parser {
82112
}
83113

84114
abstract class Parser {
115+
final List<ParserProvider>? templateProviders;
116+
final List<ParserProvider>? tsxProviders;
117+
118+
Parser({this.tsxProviders, this.templateProviders});
119+
85120
String? getStringOrNull(String name, {String? defaults});
86121

87122
List<Parser> getChildren(String name);

packages/tiled/lib/src/provider.dart

Lines changed: 3 additions & 3 deletions
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

Lines changed: 4 additions & 0 deletions
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

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -289,40 +289,41 @@ class TiledMap {
289289
);
290290
}
291291

292-
static TiledMap parseJson(String json) {
293-
final parser = JsonParser(jsonDecode(json) as Map<String, dynamic>);
292+
static TiledMap parseJson(
293+
String json, {
294+
List<ParserProvider>? tsxProviders,
295+
List<ParserProvider>? templateProviders,
296+
}) {
297+
final parser = JsonParser(
298+
jsonDecode(json) as Map<String, dynamic>,
299+
templateProviders: templateProviders,
300+
tsxProviders: tsxProviders,
301+
);
294302
return TiledMap.parse(parser);
295303
}
296304

297305
/// Parses the provided map xml.
298306
///
299307
/// Accepts an optional list of external TsxProviders for external tilesets
300308
/// referenced in the map file.
301-
static TiledMap parseTmx(
309+
factory TiledMap.parseTmx(
302310
String xml, {
303311
List<ParserProvider>? tsxProviders,
304312
List<ParserProvider>? templateProviders,
305-
List<ImagePathProvider>? imageProviders,
306313
}) {
307314
final xmlElement = XmlDocument.parse(xml).rootElement;
308315
if (xmlElement.name.local != 'map') {
309316
throw 'XML is not in TMX format';
310317
}
311-
final parser = XmlParser(xmlElement);
312-
return TiledMap.parse(
313-
parser,
318+
final parser = XmlParser(
319+
xmlElement,
314320
tsxProviders: tsxProviders,
315321
templateProviders: templateProviders,
316-
imageProviders: imageProviders,
317322
);
323+
return TiledMap.parse(parser);
318324
}
319325

320-
factory TiledMap.parse(
321-
Parser parser, {
322-
List<ParserProvider>? tsxProviders,
323-
List<ParserProvider>? templateProviders,
324-
List<ImagePathProvider>? imageProviders,
325-
}) {
326+
factory TiledMap.parse(Parser parser) {
326327
final backgroundColorHex = parser.getStringOrNull('backgroundcolor');
327328
final backgroundColor = parser.getColorOrNull('backgroundcolor');
328329
final compressionLevel = parser.getInt('compressionlevel', defaults: -1);
@@ -349,10 +350,11 @@ class TiledMap {
349350
'tileset',
350351
(tilesetData) {
351352
final tilesetSource = tilesetData.getStringOrNull('source');
352-
if (tilesetSource == null || tsxProviders == null) {
353+
if (tilesetSource == null || parser.tsxProviders == null) {
353354
return Tileset.parse(tilesetData);
354355
}
355-
final matchingTsx = tsxProviders.where(
356+
357+
final matchingTsx = parser.tsxProviders!.where(
356358
(tsx) => tsx.canProvide(tilesetSource),
357359
);
358360

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

Lines changed: 5 additions & 3 deletions
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

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ void main() {
244244
return File('./test/fixtures/map_images.tmx').readAsString().then((xml) {
245245
map = TiledMap.parseTmx(
246246
xml,
247-
tsxProviders: [FixtureTsxProvider.all('./test/fixtures')],
247+
tsxProviders: [FixtureTsxProvider.all()],
248248
);
249249
});
250250
});
@@ -305,7 +305,7 @@ void main() {
305305
.then((xml) {
306306
final map = TiledMap.parseTmx(
307307
xml,
308-
tsxProviders: [FixtureTsxProvider.all('./test/fixtures')],
308+
tsxProviders: [FixtureTsxProvider.all()],
309309
);
310310
expect(map.tilesets[0].tileCount, 137);
311311
final tile = map.tileByGid(1)!;
@@ -320,7 +320,7 @@ void main() {
320320
return File('./test/fixtures/map_images.tmx').readAsString().then((xml) {
321321
map = TiledMap.parseTmx(
322322
xml,
323-
tsxProviders: [FixtureTsxProvider.all('./test/fixtures')],
323+
tsxProviders: [FixtureTsxProvider.all()],
324324
);
325325
expect(
326326
map.tilesetByName('external').image!.source,
@@ -335,7 +335,7 @@ void main() {
335335
return File('./test/fixtures/map_images.tmx').readAsString().then((xml) {
336336
map = TiledMap.parseTmx(
337337
xml,
338-
tsxProviders: [FixtureTsxProvider.all('./test/fixtures')],
338+
tsxProviders: [FixtureTsxProvider.all()],
339339
);
340340
expect(map.layers.length, equals(2));
341341
});
@@ -350,7 +350,7 @@ void main() {
350350
.then((xml) {
351351
map = TiledMap.parseTmx(
352352
xml,
353-
tsxProviders: [FixtureTsxProvider.all('./test/fixtures')],
353+
tsxProviders: [FixtureTsxProvider.all()],
354354
);
355355
return;
356356
});
@@ -423,7 +423,7 @@ class FixtureTsxProvider extends ParserProvider {
423423

424424
FixtureTsxProvider(this.root, this.files);
425425

426-
factory FixtureTsxProvider.all(String directory) {
426+
factory FixtureTsxProvider.all([String directory = './test/fixtures']) {
427427
final dir = Directory(directory);
428428
if (!dir.existsSync()) {
429429
throw '[FixtureTsxProvider] Supplied directory does not exist!';
@@ -436,27 +436,22 @@ class FixtureTsxProvider extends ParserProvider {
436436
.map((e) => paths.basename(e.path))
437437
.toList();
438438

439-
return FixtureTsxProvider(directory, names);
440-
}
441-
442-
factory FixtureTsxProvider.file(String path) {
443-
final file = File(path);
444-
if (!file.existsSync()) {
445-
throw '[FixtureTsxProvider] Supplied path does not match any file!';
446-
}
447-
448-
return FixtureTsxProvider(paths.dirname(path), [paths.basename(path)]);
439+
return FixtureTsxProvider(paths.absolute(directory), names);
449440
}
450441

451442
final Map<String, String> cache = {};
452443

453444
@override
454-
bool canProvide(String filename) => true;
445+
bool canProvide(String filename) {
446+
return files.contains(filename);
447+
}
455448

456449
@override
457-
Parser? getCachedSource(String filename) => cache.containsKey(filename)
458-
? XmlParser.fromString(cache[filename]!)
459-
: null;
450+
Parser? getCachedSource(String filename) {
451+
return cache.containsKey(filename)
452+
? XmlParser.fromString(cache[filename]!)
453+
: null;
454+
}
460455

461456
@override
462457
Parser getSource(String filename) {

0 commit comments

Comments
 (0)