ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/gde/GCE/ArchRef.pm
Revision: 1.9
Committed: Wed May 28 19:39:35 2008 UTC (16 years ago) by elmex
Branch: MAIN
CVS Tags: pre_cursor_branch
Branch point for: cursor
Changes since 1.8: +5 -4 lines
Log Message:
the bool attributes are only removed if they are 0.

File Contents

# Content
1 package GCE::ArchRef;
2 =head1 NAME
3
4 GCE::ArchRef - a intelligent reference to an arch instance on/in the map
5
6 =head1 SYNOPSIS
7
8 GCE::ArchRef->new (arch => <hashref>, cb => <changecb>)
9
10 =over 4
11
12 =cut
13
14 use Storable qw/dclone/;
15 use Deliantra;
16 use Carp;
17 use GCE::Util;
18
19 sub getarch {
20 my ($ar) = @_;
21
22 if (ref $ar eq 'GCE::ArchRef') {
23 return $ar->{arch}
24 } else {
25 return $ar
26 }
27 }
28
29 sub new {
30 my $class = shift;
31 my $self = { @_ };
32 bless $self, $class;
33
34 unless (defined $self->{arch}) {
35 Carp::confess ("arch not defined when making new ArchRef")
36 }
37 unless (defined $Deliantra::ARCH{$self->getarch->{_name}}) {
38 quick_msg (
39 $::MAINWIN,
40 "ERROR: No such archetype '" . ($self->getarch->{_name})
41 ."' replacing it's type with 'empty_archetype'.",
42 0
43 );
44 }
45
46 return $self;
47 }
48
49 sub type {
50 my ($self) = @_;
51 Deliantra::arch_attr $self->getarch;
52 }
53
54 sub archetype {
55 my ($self) = @_;
56
57 $Deliantra::ARCH{$self->getarch->{_name}} || $Deliantra::ARCH{empty_archetype};
58 }
59
60 sub picker_folder {
61 my ($self) = @_;
62 my $folder = $self->archetype->{editor_folder};
63 my @a = split /\//, $folder;
64 $a[0]
65 }
66
67 sub longname {
68 my ($self) = @_;
69
70 my $name = $self->get ('_name');
71 my $rname = $self->get ('name');
72 my $t = $self->type;
73
74 $name . ($rname ? " - $rname" : "") . " ($t->{name})"
75 }
76
77 sub field_value_is_default {
78 my ($self, $key, $val) = @_;
79 my $al_arch = $self->archetype;
80
81 # XXX: Was '... and $val', does this fix problems?
82 (defined ($al_arch->{$key}) && $al_arch->{$key} ne $val)
83 || (not (defined $al_arch->{$key}) and $val)
84 }
85
86 sub add_inv {
87 my ($self, $arch) = @_;
88 push @{$self->{arch}->{inventory}}, dclone (getarch $arch);
89
90 $self->{cb}->($self)
91 if defined $self->{cb};
92
93 $self->exec_change_cbs (qw/inventory/);
94 }
95
96 sub swap_inv {
97 my ($self, $swapidx, $ownidx) = @_;
98 my $inv = $self->getarch->{inventory};
99
100 ($inv->[$swapidx], $inv->[$ownidx])
101 = ($inv->[$ownidx], $inv->[$swapidx]);
102
103 $self->{cb}->($self)
104 if defined $self->{cb};
105
106 $self->exec_change_cbs (qw/inventory/);
107 }
108
109 sub get_inv_refs {
110 my ($self) = @_;
111
112 my $cb = sub {
113 $self->{cb}->($self)
114 if defined $self->{cb};
115
116 $self->exec_change_cbs (qw/inventory/);
117 };
118
119 [ map { GCE::ArchRef->new (arch => $_, source => 'inventory', cb => $cb) } @{$self->get ('inventory') || []} ]
120 }
121
122 sub replace_inv {
123 my ($self, $idx, $new) = @_;
124 splice @{$self->getarch->{'inventory'}}, $idx, 1, $new;
125
126 $self->{cb}->($self)
127 if defined $self->{cb};
128
129 $self->exec_change_cbs (qw/inventory/);
130 }
131
132 sub remove_inv {
133 my ($self, $idx) = @_;
134 splice @{$self->getarch->{'inventory'}}, $idx, 1;
135
136 $self->{cb}->($self)
137 if defined $self->{cb};
138
139 $self->exec_change_cbs (qw/inventory/);
140 }
141
142 sub reset_to_defaults {
143 my ($self) = @_;
144
145 my $arch = $self->getarch;
146 for (keys %$arch) {
147 delete $arch->{$_} if $_ ne '_name'
148 }
149
150 $self->{cb}->($self)
151 if defined $self->{cb};
152
153 $self->exec_change_cbs;
154 }
155
156 sub get {
157 my ($self, $key) = @_;
158 $self->getarch->{$key}
159 }
160
161 sub get_or_default {
162 my ($self, $key) = @_;
163 def ($self->get ($key), $self->archetype->{$key})
164 }
165
166 sub set_silent {
167 my ($self, $key, $value, $type) = @_;
168
169 my $arch = $self->getarch;
170 my $al_arch = $self->archetype;
171
172 if (ref $value) {
173 $arch->{$key} = $value;
174
175 } else {
176 if (not defined $al_arch->{$key}) {
177 if ((not defined $value) || $value eq ''
178 || ($type eq 'bool' && $value eq '0')) {
179 # try to normalize
180 delete $arch->{$key};
181 } else {
182 # try to normalize
183 $arch->{$key} = $value;
184 }
185 } else {
186 if ($al_arch->{$key} ne $value) {
187 $arch->{$key} = $value;
188 } else {
189 # try to normalize
190 delete $arch->{$key};
191 }
192 }
193 }
194
195 $self->{cb}->($arch)
196 if defined $self->{cb};
197 }
198
199 sub set {
200 my ($self, $key, $value, $type) = @_;
201 $self->set_silent ($key, $value, $type);
202
203 $self->exec_change_cbs ($key);
204 }
205
206 sub remove_on_change {
207 my ($self, $key) = @_;
208 delete $self->{change_cbs}->{$key};
209 }
210
211 sub add_on_change {
212 my ($self, $key, $cb) = @_;
213 $self->{change_cbs}->{$key} = $cb;
214 }
215
216 sub exec_change_cbs {
217 my ($self, @a) = @_;
218 $_->($self, @a) for (values %{$self->{change_cbs}});
219 }
220
221 =head1 AUTHOR
222
223 Marc Lehmann <schmorp@schmorp.de>
224 http://home.schmorp.de/
225
226 Robin Redeker <elmex@ta-sa.org>
227 http://www.ta-sa.org/
228
229 =cut
230 1;