# The registry module can be extended into a class to enable # by name and by id registry storage and lookup module Registry # Sets up the registry def prepare_registry @registry_by_id ||= {} @registry_by_name ||= {} end def registry_by_name prepare_registry return @registry_by_name end # Gets the id and name for the object for use with the registry def get_registry_id_and_name(obj, id = nil, name = nil) id = obj.id if obj.respond_to? :id name = obj.name if obj.respond_to? :name name = (name ? name.to_s.to_sym : id.to_s.to_sym) return id, name end # Registers the object with the given numeric ID and name # The obj should respond to :name and :id def register(obj, id = nil, name = nil) prepare_registry id, name = get_registry_id_and_name(obj, id, name) @registry_by_id[id] = obj @registry_by_name[name.to_sym] = obj end # Unregisters the object def unregister(obj, id = nil, name = nil) prepare_registry id, name = get_registry_id_and_name(obj, id, name) @registry_by_id[id] = nil @registry_by_name[name.to_sym] = nil end # Looks up an item in the registry by name or by id. # If thing responds to :to_sym it's looked up as a name, # otherwise it's looked up by numerical def [](name_or_id) prepare_registry if name_or_id.respond_to? :to_sym return @registry_by_name[name_or_id.to_sym] else return @registry_by_id[name_or_id] end end # Other way to say self[] def lookup(name_or_id) return self[name_or_id] end # Calls a callback for each registry item with name, item def registry_each_name @registry_by_name.each do | n, e | yield n, e end end # Calls a callback for each registry item with id, item def registry_each_id @registry_by_id.each do | id, e | yield id, e end end end