Skip to content

Commit 54c3878

Browse files
author
benni-tec
committed
transfer
1 parent 6b60e92 commit 54c3878

File tree

7 files changed

+221
-41
lines changed

7 files changed

+221
-41
lines changed

packages/tiled/lib/src/common/gid.dart

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,33 +32,29 @@ part of tiled;
3232
/// When rendering a tile, the order of operation matters. The diagonal flip
3333
/// (x/y axis swap) is done first, followed by the horizontal and vertical
3434
/// flips.
35-
class Gid {
35+
class Gid extends UnaryExportable {
3636
static const int flippedHorizontallyFlag = 0x80000000;
3737
static const int flippedVerticallyFlag = 0x40000000;
3838
static const int flippedDiagonallyFlag = 0x20000000;
3939
static const int flippedAntiDiagonallyFlag = 0x10000000;
4040

41+
static const int flagBits =
42+
flippedHorizontallyFlag | flippedVerticallyFlag | flippedDiagonallyFlag | flippedAntiDiagonallyFlag;
43+
4144
final int tile;
4245
final Flips flips;
4346

4447
const Gid(this.tile, this.flips);
4548

4649
factory Gid.fromInt(int gid) {
4750
// get flips from id
48-
final flippedHorizontally =
49-
(gid & flippedHorizontallyFlag) == flippedHorizontallyFlag;
50-
final flippedVertically =
51-
(gid & flippedVerticallyFlag) == flippedVerticallyFlag;
52-
final flippedDiagonally =
53-
(gid & flippedDiagonallyFlag) == flippedDiagonallyFlag;
54-
final flippedAntiDiagonally =
55-
gid & flippedAntiDiagonallyFlag == flippedAntiDiagonallyFlag;
51+
final flippedHorizontally = (gid & flippedHorizontallyFlag) == flippedHorizontallyFlag;
52+
final flippedVertically = (gid & flippedVerticallyFlag) == flippedVerticallyFlag;
53+
final flippedDiagonally = (gid & flippedDiagonallyFlag) == flippedDiagonallyFlag;
54+
final flippedAntiDiagonally = gid & flippedAntiDiagonallyFlag == flippedAntiDiagonallyFlag;
5655
// clear id from flips
57-
final tileId = gid &
58-
~(flippedHorizontallyFlag |
59-
flippedVerticallyFlag |
60-
flippedDiagonallyFlag |
61-
flippedAntiDiagonallyFlag);
56+
final tileId =
57+
gid & ~(flippedHorizontallyFlag | flippedVerticallyFlag | flippedDiagonallyFlag | flippedAntiDiagonallyFlag);
6258
final flip = Flips(
6359
flippedHorizontally,
6460
flippedVertically,
@@ -86,4 +82,12 @@ class Gid {
8682
});
8783
});
8884
}
85+
86+
@override
87+
String export() => ((tile & ~flagBits) |
88+
(flips.horizontally ? flippedHorizontallyFlag : 0) |
89+
(flips.vertically ? flippedVerticallyFlag : 0) |
90+
(flips.diagonally ? flippedDiagonallyFlag : 0) |
91+
(flips.antiDiagonally ? flippedAntiDiagonallyFlag : 0))
92+
.toString();
8993
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
extension Null<K, V> on Map<K, V?> {
2+
Map<K, V> nonNulls() => {for (final e in entries.where((e) => e.value is V)) e.key : e.value as V};
3+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
part of tiled;
2+
3+
abstract class Exportable {
4+
const Exportable();
5+
6+
String xml();
7+
String json();
8+
}
9+
10+
abstract class UnaryExportable extends Exportable {
11+
const UnaryExportable();
12+
13+
String export();
14+
15+
@override
16+
String json() => export();
17+
18+
@override
19+
String xml() => export();
20+
}
21+
22+
class PassThroughExportable extends Exportable {
23+
final Object value;
24+
25+
const PassThroughExportable(this.value);
26+
27+
@override
28+
String json() => value.toString();
29+
30+
@override
31+
String xml() => value.toString();
32+
}
33+
34+
extension ExportableString on String {
35+
Exportable toExport() => PassThroughExportable(this);
36+
}
37+
38+
extension ExportableNum on num {
39+
Exportable toExport() => PassThroughExportable(this);
40+
}
41+
42+
extension ExportableBool on bool {
43+
Exportable toExport() => PassThroughExportable(this);
44+
}
45+
46+
class _ExportableColor extends UnaryExportable {
47+
final Color color;
48+
49+
const _ExportableColor(this.color);
50+
51+
static String _hex(int value) {
52+
final str = value.toRadixString(16).padLeft(2, '0');
53+
return str.substring(str.length - 2, str.length - 1);
54+
}
55+
56+
@override
57+
String export() => '#${_hex(color.alpha)}${_hex(color.red)}${_hex(color.green)}${_hex(color.blue)}';
58+
}
59+
60+
extension ExportableColor on Color {
61+
Exportable toExport() => _ExportableColor(this);
62+
}
63+
64+
class FormatSpecificExportable extends Exportable {
65+
final String Function() xmlF;
66+
final String Function() jsonF;
67+
68+
const FormatSpecificExportable({required this.xmlF, required this.jsonF});
69+
70+
@override
71+
String json() => jsonF();
72+
73+
@override
74+
String xml() => xmlF();
75+
}

packages/tiled/lib/src/exporter.dart

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
part of tiled;
2+
3+
abstract class Exporter<T> {
4+
T exportValue(Exportable value);
5+
6+
T exportElement(String name, Map<String, Exportable> attributes, Map<String, Iterable<T>> children);
7+
8+
E formatSpecificExporting<E>(
9+
E Function(XmlExporter) xml,
10+
E Function(JsonExporter) json,
11+
);
12+
}
13+
14+
class XmlExporter extends Exporter<XmlNode> {
15+
@override
16+
XmlNode exportValue(Exportable value) => XmlText(value.xml());
17+
18+
@override
19+
XmlNode exportElement(
20+
String name,
21+
Map<String, Exportable> attributes,
22+
Map<String, Iterable<XmlNode>> children,
23+
) {
24+
final element = XmlElement(
25+
XmlName(name),
26+
attributes.entries.map(
27+
(e) => XmlAttribute(
28+
XmlName(e.key),
29+
e.value.xml(),
30+
),
31+
),
32+
children.values.flattened,
33+
);
34+
35+
return element;
36+
}
37+
38+
@override
39+
E formatSpecificExporting<E>(
40+
E Function(XmlExporter p1) xml,
41+
E Function(JsonExporter p1) json,
42+
) {
43+
return xml(this);
44+
}
45+
}
46+
47+
class JsonExporter extends Exporter<dynamic> {
48+
@override
49+
dynamic exportValue(dynamic value) => value;
50+
51+
@override
52+
Map<String, dynamic> exportElement(
53+
String name,
54+
Map<String, Exportable> attributes,
55+
Map<String, Iterable<dynamic>> children,
56+
) =>
57+
<String, dynamic>{
58+
...attributes,
59+
...children,
60+
};
61+
62+
@override
63+
E formatSpecificExporting<E>(
64+
E Function(XmlExporter p1) xml,
65+
E Function(JsonExporter p1) json,
66+
) {
67+
return json(this);
68+
}
69+
}
70+
71+
extension DataExport on List<int> {
72+
73+
}

packages/tiled/lib/src/layer.dart

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ abstract class Layer {
112112
this.properties = CustomProperties.empty,
113113
});
114114

115+
T export<T>(Exporter<T> exporter);
116+
115117
static Layer parse(Parser parser) {
116118
final type = parser.formatSpecificParsing(
117119
(json) => json.getLayerType('type'),
@@ -144,17 +146,13 @@ abstract class Layer {
144146
(json) => null, // data is just a string or list of int on JSON
145147
(xml) => xml.getSingleChildOrNull('data'),
146148
);
147-
final compression = parser.getCompressionOrNull('compression') ??
148-
dataNode?.getCompressionOrNull('compression');
149-
final encoding = parser.getFileEncodingOrNull('encoding') ??
150-
dataNode?.getFileEncodingOrNull('encoding') ??
151-
FileEncoding.csv;
149+
final compression = parser.getCompressionOrNull('compression') ?? dataNode?.getCompressionOrNull('compression');
150+
final encoding =
151+
parser.getFileEncodingOrNull('encoding') ?? dataNode?.getFileEncodingOrNull('encoding') ?? FileEncoding.csv;
152152
Chunk parseChunk(Parser e) => Chunk.parse(e, encoding, compression);
153-
final chunks = parser.getChildrenAs('chunks', parseChunk) +
154-
(dataNode?.getChildrenAs('chunk', parseChunk) ?? []);
155-
final data = dataNode != null
156-
? parseLayerData(dataNode, encoding, compression)
157-
: null;
153+
final chunks =
154+
parser.getChildrenAs('chunks', parseChunk) + (dataNode?.getChildrenAs('chunk', parseChunk) ?? []);
155+
final data = dataNode != null ? parseLayerData(dataNode, encoding, compression) : null;
158156
layer = TileLayer(
159157
id: id,
160158
name: name,
@@ -185,10 +183,8 @@ abstract class Layer {
185183
'draworder',
186184
defaults: DrawOrder.topDown,
187185
);
188-
final colorHex =
189-
parser.getString('color', defaults: ObjectGroup.defaultColorHex);
190-
final color =
191-
parser.getColor('color', defaults: ObjectGroup.defaultColor);
186+
final colorHex = parser.getString('color', defaults: ObjectGroup.defaultColorHex);
187+
final color = parser.getColor('color', defaults: ObjectGroup.defaultColor);
192188
final objects = parser.getChildrenAs('object', TiledObject.parse);
193189
layer = ObjectGroup(
194190
id: id,
@@ -417,6 +413,27 @@ class TileLayer extends Layer {
417413
}
418414
return Gid.generate(data, width, height);
419415
}
416+
417+
@override
418+
T export<T>(Exporter<T> exporter, {Compression compression = Compression.zlib, FileEncoding encoding = FileEncoding.base64}) => exporter.exportElement(
419+
'layer',
420+
{
421+
'class': class_?.toExport(),
422+
'name': name.toExport(),
423+
'height': height.toExport(),
424+
'width': width.toExport(),
425+
'x': x.toExport(),
426+
'y': y.toExport(),
427+
'opacity': opacity.toExport(),
428+
'type': type.name.toExport(),
429+
'visible': visible.toExport(),
430+
'compression': (data == null ? compression : null)?.name.toExport(),
431+
}.nonNulls(),
432+
{
433+
'chunks': chunks?.map((e) => e.export(exporter, compression: compression, encoding: encoding)),
434+
'data': da
435+
}.nonNulls(),
436+
);
420437
}
421438

422439
class ObjectGroup extends Layer {

packages/tiled/lib/src/tiled_map.dart

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,7 @@ class TiledMap {
137137
.map((e) => e.getAttribute('source'));
138138

139139
final tsxProviders = await Future.wait(
140-
tsxSourcePaths
141-
.where((key) => key != null)
142-
.map((key) async => tsxProviderFunction(key!)),
140+
tsxSourcePaths.where((key) => key != null).map((key) async => tsxProviderFunction(key!)),
143141
);
144142

145143
return TileMapParser.parseTmx(
@@ -216,10 +214,7 @@ class TiledMap {
216214
}
217215
}
218216
imageSet.addAll(
219-
layers
220-
.whereType<ImageLayer>()
221-
.map((e) => e.image)
222-
.where((e) => e.source != null),
217+
layers.whereType<ImageLayer>().map((e) => e.image).where((e) => e.source != null),
223218
);
224219
return imageSet.toList();
225220
}
@@ -232,17 +227,13 @@ class TiledMap {
232227
} else if (layer is TileLayer) {
233228
const emptyTile = 0;
234229
final rows = layer.tileData ?? <List<Gid>>[];
235-
final gids = rows
236-
.expand((row) => row.map((gid) => gid.tile))
237-
.where((gid) => gid != emptyTile)
238-
.toSet();
230+
final gids = rows.expand((row) => row.map((gid) => gid.tile)).where((gid) => gid != emptyTile).toSet();
239231

240232
return gids
241233
.map(tilesetByTileGId)
242234
.toSet() // The different gid can be in the same tileset
243235
.expand(
244-
(tileset) =>
245-
[tileset.image, ...tileset.tiles.map((tile) => tile.image)],
236+
(tileset) => [tileset.image, ...tileset.tiles.map((tile) => tile.image)],
246237
)
247238
.whereNotNull()
248239
.toList();
@@ -358,4 +349,18 @@ class TiledMap {
358349
properties: properties,
359350
);
360351
}
352+
353+
T export<T>(Exporter<T> exporter, {bool embedTilesets = true}) => exporter.exportElement(
354+
'map',
355+
{
356+
'backgroundColor': backgroundColor?.toExport(),
357+
'compressionlevel': compressionLevel.toExport(),
358+
'height': height.toExport(),
359+
'hexsidelength': hexSideLength?.toExport(),
360+
'infinite': infinite.toExport(),
361+
}.nonNulls(),
362+
{
363+
'layers': layers.map((e) => e.export()),
364+
},
365+
);
361366
}

packages/tiled/lib/tiled.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@ import 'dart:typed_data';
88
import 'package:archive/archive.dart';
99
import 'package:collection/collection.dart';
1010
import 'package:meta/meta.dart';
11+
import 'package:tiled/src/common/map.dart';
1112
import 'package:xml/xml.dart';
1213

1314
part 'src/chunk.dart';
15+
part 'src/exportable.dart';
16+
part 'src/exporter.dart';
1417
part 'src/common/enums.dart';
1518
part 'src/common/flips.dart';
1619
part 'src/common/frame.dart';

0 commit comments

Comments
 (0)