Skip to content

Commit

Permalink
No more rebuilding dict on every getResource
Browse files Browse the repository at this point in the history
  • Loading branch information
njooma committed Nov 21, 2024
1 parent 11dcb20 commit c1f7a4a
Showing 1 changed file with 18 additions and 18 deletions.
36 changes: 18 additions & 18 deletions lib/src/resource/manager.dart
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
import 'package:protobuf/protobuf.dart';

import '../gen/common/v1/common.pb.dart';
import 'base.dart';

/// [ResourceManager] manages the state of all currently available resources of a robot
class ResourceManager {
/// The available resources
Map<ResourceName, Resource> resources = {};
final Map<String, List<ResourceName>> _shortToLongName = {};
final Map<ResourceName, List<ResourceName>> _resourceNamesWithoutRemotes = {};

/// Register a new [Resource] with the manager.
void register(ResourceName name, Resource resource) {
if (resources.containsKey(name)) {
throw Exception('Duplicate registration of resource in manager');
}
final shortName = name.name.split(':').last;
final names = _shortToLongName[shortName] ?? [];
final rnWithoutRemote = name.deepCopy()
..remotePath.clear()
..name = name.localName;
final names = _resourceNamesWithoutRemotes[rnWithoutRemote] ?? [];
names.add(name);
_shortToLongName[shortName] = names;
_resourceNamesWithoutRemotes[rnWithoutRemote] = names;
resources[name] = resource;
}

Expand All @@ -25,22 +29,18 @@ class ResourceManager {
if (resources.containsKey(name)) {
resource = resources[name];
} else {
final resourcesWithoutRemotes = resources.map((rn, res) {
final rnWithoutRemote = rn
..remotePath.clear()
..name = rn.localName;
return MapEntry(rnWithoutRemote, res);
});
resource = resourcesWithoutRemotes[name];
final resourceNames = _resourceNamesWithoutRemotes[name] ?? [];
// If multiple name-without-remotes map to this resource name,
// that means there are multiple remote resources with this same short name.
// Without any means to disambiguate, we should not select any.
if (resourceNames.length > 1) {
throw Exception('Multiple remote resources with found with the name ${name.name}: $resourceNames');
}
if (resourceNames.length == 1) {
resource = resources[resourceNames.first];
}
}
if (resource == null) throw Exception('Resource not found in manager');
return resource as T;
}

/// Get a resource by its name only
T getResourceByName<T>(String name) {
final names = _shortToLongName[name] ?? [];
if (names.isEmpty) throw Exception('Resource not found in manager');
return getResource(names.first);
}
}

0 comments on commit c1f7a4a

Please sign in to comment.