File: ThingList.pm

package info (click to toggle)
perlmoo 0.045
  • links: PTS
  • area: main
  • in suites: slink
  • size: 404 kB
  • ctags: 242
  • sloc: perl: 5,211; makefile: 111; sh: 77
file content (112 lines) | stat: -rw-r--r-- 2,668 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# This package provides a list of all things in the moo, and allows you
# to look up things by number and by type, etc. (Actually, it's not a 
# list, it's a hash, but don't tell anyone outside this package. ;-)

package ThingList;
use UNIVERSAL qw(isa);
use strict;

# Here's the hash of things.
my %thinglist=();

# This is a function that just returns a reference to the thing that has
# a specified id number.
sub FindByNum {
	my $num=shift;
	return $thinglist{$num};
}

# Given the name of a thing, and (optionally) that thing's type, returns
# the things of that type with that name or alias. If called in a scalar
# context, returns only the first one found. If called in a list context,
# returns all of them. This is a case insensitive search.
sub FindByName {
	my $name=lc(shift);
	my $type=shift;

	my @ret=();
	my $id;
	foreach $id (sort {$a <=> $b} keys %thinglist) {
		next if ($type && ! isa($thinglist{$id},$type));
		if ($thinglist{$id}->isalias($name)) {
			if (!wantarray) {
				return $thinglist{$id}
			}
			else {
				push @ret,$thinglist{$id};
			}	
		}
	}

	if (!wantarray) {
		return undef;
	}
	else {
		return @ret;
	}	
}

# Returns all things, (or just the first if called in scalar context).
sub All {
	FindByType();
}

# Given an object type, returns things of that type. If called in a scalar
# context, returns only the first one found. If called in a list context,
# returns all of them. If you don't pass it a type, it operates on all things.
sub FindByType {
	my $type=shift || "Thing";

	# Minor optimization..
	if ($type eq "Thing" && wantarray) {
		return values %thinglist
	}

	my @ret=();
	my $id;
	foreach $id (sort {$a <=> $b} keys %thinglist) {
		if (isa($thinglist{$id},$type)) {
			if (!wantarray) {
				return $thinglist{$id};
			}
			else {
				push @ret,$thinglist{$id};
			}
		}
	}
	
	if (!wantarray) {
		return undef;
	}
	else {
		return @ret;
	}
}

# Passed a new thing, adds it to the list. The things should already have it's
# id set. Returns the thing.
sub add {
	my $thing=shift;
	$thinglist{$thing->id}=$thing;
}

# Remove the thing from the list. Note that if this isn't called, an object
# will never really go away, since there will still be a reference to it
# on the list.
sub remove {
	my $thing=shift;
	delete $thinglist{$thing->id};
}

# This just returns a suggested id that's free on the thinglist, for objects
# that don't care what their id is.
sub GetId {
	# TODO: Should do this more efficiently - I know i can do it in
	# O(n), and I suspect it's possible to do it quicker than that.
	# This is O(n log n), of course:
	my @list=sort { $a <=> $b } (keys %thinglist);

	return $list[$#list]+1;
}

1