ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/ext/widget.ext
Revision: 1.6
Committed: Mon Jul 16 09:07:12 2007 UTC (16 years, 10 months ago) by root
Branch: MAIN
Changes since 1.5: +1 -1 lines
Log Message:
hardcode map start paths for now (and likely forever)

File Contents

# Content
1 #! perl # mandatory depends=login
2
3 # sends the following ext message types
4 # ws_n id # widgetset new
5 # ws_d id # widgetset destroy
6 # ws_c ws id class args # widgetset create
7 # w_c id [rid] name args # widget method call
8 # w_s id name value # widget member set
9 # w_g id rid name # widget member get
10 #
11 # and expects the following exti message types
12 # w_r rid res # widget call return
13 # w_e id name args # widget_event
14
15 cf::client->attach (
16 on_connect => sub {
17 my ($ns) = @_;
18
19 Scalar::Util::weaken (my $weakns = $ns);
20
21 $ns->{id} = "a";
22 $ns->{json_coder}->filter_json_single_key_object (__widget_ref__ => sub {
23 # cannot deserialise ATM
24 undef
25 });
26 },
27 );
28
29 sub csc_update_stats {
30 my ($ns) = @_;
31
32 while (my ($k, $v) = each %{ $ns->{csc}{stat} }) {
33 $v->set_text ($ns->pl->ob->stats->$k);
34 }
35 }
36
37 sub demo_map {
38 my ($ns) = @_;
39
40 my $ws = $ns->{csc} = $ns->new_widgetset;
41
42 my $w = $ws->new (Toplevel =>
43 w => 200,
44 h => 200,
45 x => "center",
46 y => "center",
47 title => "Worldmap",
48 has_close_button => 1,
49 on_delete => sub {
50 $ws->destroy;
51 },
52 );
53
54 my $face = cf::face::find "res/worldmap.jpg";
55 $ns->send_face ($face);
56
57 $w->add (my $sw = $ws->new (ScrolledWindow => scroll_x => 1, scroll_y => 1));
58 $sw->add (my $vb = $ws->new (VBox => expand => 1));
59 #$vb->add ($ws->new (Label => text => "lb1"));
60 $vb->add ($ws->new (Face => expand => 1, size_w => undef, size_h => undef, face => $face));
61 $sw->show;
62 $vb->show;
63
64 $w->show;
65 }
66
67 sub csc_start {
68 my ($ns) = @_;
69
70 my $ws = $ns->{csc} = $ns->new_widgetset;
71
72 my $w = $ws->new (Toplevel =>
73 min_w => 600,
74 min_h => 400,
75 x => "center",
76 y => "center",
77 title => "Character Creation",
78 has_close_button => 1,
79 on_delete => sub {
80 $ws->destroy;
81 },
82 );
83
84 $w->add (my $ntb = $ws->new (Notebook => expand => 1));
85
86 $ntb->add (Statistics => (my $stats = $ws->new (Table => expand => 1)), "Basic statistics of your new character");
87
88 $stats->add (0, 0, (my $statstable = $ws->new ("Table")));
89
90 for (
91 [0, "Str"],
92 [1, "Dex"],
93 [2, "Con"],
94 [3, "Int"],
95 [4, "Wis"],
96 [5, "Pow"],
97 [6, "Cha"],
98 ) {
99 my ($x, $label) = @$_;
100
101 $statstable->add ($x, 0, $ws->new (Label =>
102 can_hover => 1, can_events => 1,
103 align => +1, text => $label, tooltip => "#stat_$label",
104 ));
105 $statstable->add ($x, 1, $ws->{stat}{$label} = $ws->new (Label =>
106 can_hover => 1, can_events => 1,
107 align => +1, template => "88", tooltip => "#stat_$label",
108 ));
109 }
110
111 csc_update_stats $ns;
112
113 $w->show;
114 }
115
116 cf::player->attach (
117 on_login => sub {
118 my ($pl) = @_;
119
120 #return unless $cf::CFG{devel};
121
122 my $ns = $pl->ns;
123
124 return unless $ns->{can_widget};
125
126 demo_map $ns;
127 #csc_start $ns;
128 },
129 );
130
131 cf::register_exticmd w_e => sub {
132 my ($ns, $pkt) = @_;
133
134 if (my $w = $ns->{widget}{$pkt->{id}}) {
135 if (my $cb = $w->{ev}{$pkt->{name}}) {
136 $_->($w, @{ $pkt->{args} || [] })
137 for @$cb;
138 }
139 }
140
141 ()
142 };
143
144 cf::register_exticmd w_r => sub {
145 my ($ns, $pkt) = @_;
146
147 if (my $cb = delete $ns->{widget_return}{$pkt->{rid}}) {
148 $cb->(@{$pkt->{res} || [] });
149 }
150
151 ()
152 };
153
154 sub cf::client::new_widgetset {
155 my ($self) = @_;
156
157 my $id = ++$self->{id};
158
159 my $ws = bless {
160 id => $id,
161 ns => $self,
162 w => {},
163 }, "ext::widget::set";
164
165 $ws->msg (ws_n => id => $id);
166
167 $ws
168 }
169
170 #############################################################################
171
172 package ext::widget::set;
173
174 sub DESTROY {
175 $_[0]->destroy;
176 }
177
178 sub destroy {
179 my ($self) = @_;
180
181 $self->msg (ws_d => id => $self->{id});
182 delete $self->{ns};
183 $_->destroy
184 for values %{ $self->{w} };
185 }
186
187 sub msg {
188 my ($self, $type, %msg) = @_;
189
190 if (my $ns = shift->{ns}) {
191 $msg{msgtype} = $type;
192 $ns->send_packet ("ext " . $ns->{json_coder}->encode (\%msg));
193 }
194 }
195
196 sub new {
197 my ($self, $class, %args) = @_;
198
199 my $id = ++$self->{ns}{id};
200
201 my $proxy = $self->{w}{$id} = bless {
202 id => $id,
203 }, "ext::widget::proxy";
204
205 Scalar::Util::weaken ($proxy->{ws} = $self);
206 Scalar::Util::weaken ($proxy->{ns} = $self->{ns});
207 Scalar::Util::weaken ($self->{ns}{widget}{$id} = $proxy);
208
209 for my $ev (grep /^on_/, keys %args) {
210 push @{$proxy->{ev}{$ev}}, $args{$ev};
211 $args{$ev} = 0;
212 }
213
214 $self->msg (ws_c =>
215 ws => $self->{w}{id},
216 id => $id,
217 class => $class,
218 args => \%args,
219 );
220
221 $proxy
222 }
223
224 #############################################################################
225
226 package ext::widget::proxy;
227
228 sub DESTROY {
229 my ($self) = @_;
230
231 delete $self->{ns}{widget}{$self->{id}};
232
233 if (my $ws = $self->{ws}) {
234 delete $ws->{w}{$self->{id}};
235 $self->msg (w_c => name => "destroy");
236 }
237 }
238
239 sub msg {
240 my ($self, $type, %msg) = @_;
241
242 if (my $ws = $self->{ws}) {
243 $ws->msg ($type,
244 %msg,
245 id => $self->{id},
246 );
247 }
248 }
249
250 sub msg_cb {
251 my ($self, $cb, $type, %msg) = @_;
252
253 if (my $ws = $self->{ws}) {
254
255 my $rid = ++$ws->{ns}{id};
256
257 $self->msg ($type, %msg, rid => $rid);
258
259 if ($cb) {
260 $ws->{ns}{widget_return}{$rid} = $cb;
261 } else {
262 # synchronous case
263 my $wait = new Coro::Signal;
264 my @res;
265
266 $ws->{ns}{widget_return}{$rid} = sub {
267 @res = @_;
268 $wait->send;
269 };
270 $wait->wait;
271
272 return @res;
273 }
274 }
275
276 ()
277 }
278
279 sub set {
280 my ($self, $member, $value) = @_;
281
282 $self->msg (w_s => name => $member, value => $value);
283 }
284
285 sub get {
286 my ($self, $member, $cb) = @_;
287
288 $self->msg_cb ($cb, w_g => name => $member);
289 }
290
291 sub TO_JSON {
292 { __widget_ref__ => $_[0]{id} }
293 }
294
295 our $AUTOLOAD;
296
297 sub AUTOLOAD {
298 $AUTOLOAD =~ s/^.*://
299 or return;
300
301 my $self = shift;
302
303 $self->msg (w_c => name => $AUTOLOAD, args => \@_);
304
305 ()
306 }
307