2 # Node routing routines
4 # Copyright (c) 2001 Dirk Koopman G1TLH
17 use vars qw($VERSION $BRANCH);
18 $VERSION = sprintf( "%d.%03d", q$Revision$ =~ /(\d+)\.(\d+)/ );
19 $BRANCH = sprintf( "%d.%03d", q$Revision$ =~ /\d+\.\d+\.(\d+)\.(\d+)/ || (0,0));
20 $main::build += $VERSION;
21 $main::branch += $BRANCH;
23 use vars qw(%list %valid @ISA $max $filterdef);
27 dxchan => '0,DXChannel List,parray',
28 nodes => '0,Nodes,parray',
29 users => '0,Users,parray',
30 usercount => '0,User Count',
31 version => '0,Version',
34 $filterdef = $Route::filterdef;
40 my $n = scalar (keys %list);
41 $max = $n if $n > $max;
51 # link a node to this node and mark the route as available thru
52 # this dxchan, any users must be linked separately
54 # call as $node->link_node($neighbour, $dxchan);
59 my ($self, $neighbour, $dxchan) = @_;
61 my $r = $self->is_empty('dxchan');
62 $self->_addlist('nodes', $neighbour);
63 $neighbour->_addlist('nodes', $self);
64 $self->_addlist('dxchan', $dxchan);
65 $neighbour->_addlist('dxchan', $dxchan);
66 return $r ? ($self) : ();
69 # unlink a node from a neighbour and remove any
70 # routes, if this node becomes orphaned (no routes
71 # and no nodes) then return it
76 my ($self, $neighbour, $dxchan) = @_;
77 $self->_dellist('nodes', $neighbour);
78 $neighbour->_dellist('nodes', $self);
79 $self->_dellist('dxchan', $dxchan);
80 $neighbour->_dellist('dxchan', $dxchan);
81 return $self->is_empty('dxchan') ? ($self) : ();
84 # add a user to this node
85 # returns Route::User if it is a new user;
88 my ($self, $uref) = @_;
89 my $r = $uref->is_empty('nodes');
90 $self->_addlist('users', $uref);
91 $uref->_addlist('nodes', $self);
92 $self->{usercount} = scalar @{$self->{users}};
93 return $r ? ($uref) : ();
96 # delete a user from this node
99 my ($self, $uref) = @_;
101 $self->_dellist('users', $uref);
102 $uref->_dellist('nodes', $self);
103 $self->{usercount} = scalar @{$self->{users}};
104 return $uref->is_empty('nodes') ? ($uref) : ();
110 if (@_ && @{$self->{users}} == 0) {
111 $self->{usercount} = shift;
113 return $self->{usercount};
119 return @{$self->{users}};
125 return @{$self->{nodes}};
131 foreach my $u (${$self->{nodes}}) {
132 my $uref = Route::User::get($u);
133 $self->unlink_user($uref) if $uref;
142 confess "already have $call in $pkg" if $list{$call};
144 my $self = $pkg->SUPER::new($call);
145 $self->{dxchan} = ref $pkg ? [ $pkg->{call} ] : [ ];
146 $self->{version} = shift;
147 $self->{flags} = shift;
152 $list{$call} = $self;
153 dbg("creating Route::Node $self->{call}") if isdbg('routelow');
161 dbg("deleting Route::Node $self->{call}") if isdbg('routelow');
162 delete $list{$self->{call}};
168 $call = shift if ref $call;
169 my $ref = $list{uc $call};
170 dbg("Failed to get Node $call" ) if !$ref && isdbg('routerr');
183 my $call = $self->{call} || "Unknown";
185 dbg("destroying $pkg with $call") if isdbg('routelow');
186 $self->unlink_all_users if @{$self->{users}};
190 # generic AUTOLOAD for accessors
196 my $name = $AUTOLOAD;
197 return if $name =~ /::DESTROY$/;
200 confess "Non-existant field '$AUTOLOAD'" unless $valid{$name} || $Route::valid{$name};
202 # this clever line of code creates a subroutine which takes over from autoload
203 # from OO Perl - Conway
204 *$AUTOLOAD = sub {$_[0]->{$name} = $_[1] if @_ > 1; return $_[0]->{$name}};