Skip to content

Commit

Permalink
feat: Adding a method to get any object in a map by its unique ID (#75)
Browse files Browse the repository at this point in the history
* feat: Adding a method to get any object in a map by its unique ID

* adding comment about caching
  • Loading branch information
kurtome committed Dec 6, 2023
1 parent 628f1f6 commit 4faf43b
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 0 deletions.
24 changes: 24 additions & 0 deletions packages/tiled/lib/src/tiled_map.dart
Expand Up @@ -91,6 +91,9 @@ class TiledMap {
List<EditorSetting> editorSettings;
CustomProperties properties;

// Cache the object by ID when accessed.
Map<int, TiledObject>? _cachedObjects;

// only for hexagonal maps:
int? hexSideLength;
StaggerAxis? staggerAxis;
Expand Down Expand Up @@ -279,6 +282,27 @@ class TiledMap {
throw ArgumentError('Layer $name not found');
}

/// Finds the [TiledObject] in this map with the unique [id].
/// Objects have map wide unique IDs which are never reused.
/// https://doc.mapeditor.org/en/stable/reference/tmx-map-format/#object
///
/// This reads through a cached map of all the objects so it does not
/// need to loop through all the object layers each time.
///
/// Returns null if not found.
TiledObject? objectById(int id) {
if (_cachedObjects == null) {
_cachedObjects = {};
layers.whereType<ObjectGroup>().forEach((objectGroup) {
for (final object in objectGroup.objects) {
_cachedObjects![object.id] = object;
}
});
}

return _cachedObjects?[id];
}

Tileset tilesetByName(String name) {
return tilesets.firstWhere(
(element) => element.name == name,
Expand Down
51 changes: 51 additions & 0 deletions packages/tiled/test/map_test.dart
Expand Up @@ -380,4 +380,55 @@ void main() {
expect(map.tilesetByName('Humans'), equals(tileset));
});
});

group('Map.objectById', () {
late TiledMap map;
setUp(() {
map = TiledMap(
width: 2,
height: 2,
tileWidth: 8,
tileHeight: 8,
layers: [
TileLayer(
name: 'tile layer 1',
width: 2,
height: 2,
data: [1, 0, 2, 0],
),
ObjectGroup(
name: 'object layer 1',
objects: [
TiledObject(id: 1, name: 'object one'),
TiledObject(id: 5, name: 'object five'),
],
),
],
tilesets: [
Tileset(
name: 'TileSet_1',
image: const TiledImage(source: 'tileset_1.png'),
firstGid: 1,
columns: 1,
tileCount: 2,
tiles: [
Tile(localId: 0),
Tile(localId: 1),
],
),
],
);
});

test('gets images only in use on each TileLayer', () {
final object1 = map.objectById(1);
expect(object1?.name, equals('object one'));

final object5 = map.objectById(5);
expect(object5?.name, equals('object five'));

final object3 = map.objectById(3);
expect(object3, equals(null));
});
});
}

0 comments on commit 4faf43b

Please sign in to comment.