Skip to content

Commit 4faf43b

Browse files
authored
feat: Adding a method to get any object in a map by its unique ID (#75)
* feat: Adding a method to get any object in a map by its unique ID * adding comment about caching
1 parent 628f1f6 commit 4faf43b

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed

packages/tiled/lib/src/tiled_map.dart

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ class TiledMap {
9191
List<EditorSetting> editorSettings;
9292
CustomProperties properties;
9393

94+
// Cache the object by ID when accessed.
95+
Map<int, TiledObject>? _cachedObjects;
96+
9497
// only for hexagonal maps:
9598
int? hexSideLength;
9699
StaggerAxis? staggerAxis;
@@ -279,6 +282,27 @@ class TiledMap {
279282
throw ArgumentError('Layer $name not found');
280283
}
281284

285+
/// Finds the [TiledObject] in this map with the unique [id].
286+
/// Objects have map wide unique IDs which are never reused.
287+
/// https://doc.mapeditor.org/en/stable/reference/tmx-map-format/#object
288+
///
289+
/// This reads through a cached map of all the objects so it does not
290+
/// need to loop through all the object layers each time.
291+
///
292+
/// Returns null if not found.
293+
TiledObject? objectById(int id) {
294+
if (_cachedObjects == null) {
295+
_cachedObjects = {};
296+
layers.whereType<ObjectGroup>().forEach((objectGroup) {
297+
for (final object in objectGroup.objects) {
298+
_cachedObjects![object.id] = object;
299+
}
300+
});
301+
}
302+
303+
return _cachedObjects?[id];
304+
}
305+
282306
Tileset tilesetByName(String name) {
283307
return tilesets.firstWhere(
284308
(element) => element.name == name,

packages/tiled/test/map_test.dart

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,4 +380,55 @@ void main() {
380380
expect(map.tilesetByName('Humans'), equals(tileset));
381381
});
382382
});
383+
384+
group('Map.objectById', () {
385+
late TiledMap map;
386+
setUp(() {
387+
map = TiledMap(
388+
width: 2,
389+
height: 2,
390+
tileWidth: 8,
391+
tileHeight: 8,
392+
layers: [
393+
TileLayer(
394+
name: 'tile layer 1',
395+
width: 2,
396+
height: 2,
397+
data: [1, 0, 2, 0],
398+
),
399+
ObjectGroup(
400+
name: 'object layer 1',
401+
objects: [
402+
TiledObject(id: 1, name: 'object one'),
403+
TiledObject(id: 5, name: 'object five'),
404+
],
405+
),
406+
],
407+
tilesets: [
408+
Tileset(
409+
name: 'TileSet_1',
410+
image: const TiledImage(source: 'tileset_1.png'),
411+
firstGid: 1,
412+
columns: 1,
413+
tileCount: 2,
414+
tiles: [
415+
Tile(localId: 0),
416+
Tile(localId: 1),
417+
],
418+
),
419+
],
420+
);
421+
});
422+
423+
test('gets images only in use on each TileLayer', () {
424+
final object1 = map.objectById(1);
425+
expect(object1?.name, equals('object one'));
426+
427+
final object5 = map.objectById(5);
428+
expect(object5?.name, equals('object five'));
429+
430+
final object3 = map.objectById(3);
431+
expect(object3, equals(null));
432+
});
433+
});
383434
}

0 commit comments

Comments
 (0)