ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/ext/widget.ext
Revision: 1.2
Committed: Mon Jun 25 07:40:53 2007 UTC (16 years, 11 months ago) by root
Branch: MAIN
Changes since 1.1: +56 -33 lines
Log Message:
goofing around

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 $ns->{id} = "a";
20 },
21 );
22
23 sub csc_update_stats {
24 my ($ns) = @_;
25
26 while (my ($k, $v) = each %{ $ns->{csc}{stat} }) {
27 $v->set_text ($ns->pl->ob->stats->$k);
28 }
29 }
30
31 sub csc_start {
32 my ($ns) = @_;
33
34 my $ws = $ns->{csc} = $ns->new_widgetset;
35
36 my $w = $ws->new (Toplevel =>
37 min_w => 600,
38 min_h => 400,
39 x => "center",
40 y => "center",
41 title => "Character Creation",
42 );
43
44 $w->add (my $ntb = $ws->new (Notebook => expand => 1));
45
46 $ntb->add (Statistics => (my $stats = $ws->new (Table => expand => 1)), "Basic statistics of your new character");
47
48 $stats->add (0, 0, (my $statstable = $ws->new ("Table")));
49
50 for (
51 [0, "Str", "Strength"],
52 [1, "Dex", "Dexterity"],
53 [2, "Con", "Constitution"],
54 [3, "Int", "Intelligence"],
55 [4, "Wis", "Wisdom"],
56 [5, "Pow", "Power"],
57 [6, "Cha", "Charisma"],
58 ) {
59 my ($x, $label, $description) = @$_;
60
61 $statstable->add ($x, 0, $ws->new (Label =>
62 can_hover => 1, can_events => 1,
63 align => +1, text => $label, tooltip => "#stat_$label",
64 ));
65 $statstable->add ($x, 1, $ws->{stat}{$label} = $ws->new (Label =>
66 can_hover => 1, can_events => 1,
67 align => +1, template => "88", tooltip => "#stat_$label",
68 ));
69 }
70
71 csc_update_stats $ns;
72
73 $w->show;
74 }
75
76 cf::player->attach (
77 on_login => sub {
78 my ($pl) = @_;
79
80 return unless $cf::CFG{devel};
81
82 my $ns = $pl->ns;
83
84 return unless $ns->{can_widget};
85
86 csc_start $ns;
87 },
88 );
89
90 cf::register_exticmd w_e => sub {
91 my ($ns, $pkt) = @_;
92
93 if (my $w = $ns->{widget}{$pkt->{id}}) {
94 if (my $cb = $w->{ev}{$pkt->{name}}) {
95 $_->($w, @{ $pkt->{args} || [] })
96 for @$cb;
97 }
98 }
99
100 ()
101 };
102
103 cf::register_exticmd w_r => sub {
104 my ($ns, $pkt) = @_;
105
106 if (my $cb = delete $ns->{widget_return}{$pkt->{rid}}) {
107 $cb->(@{$pkt->{res} || [] });
108 }
109
110 ()
111 };
112
113 sub cf::client::new_widgetset {
114 my ($self) = @_;
115
116 my $id = ++$self->{id};
117
118 my $ws = bless {
119 id => $id,
120 ns => $self,
121 w => {},
122 }, "ext::widget::set";
123
124 $ws->msg (ws_n => id => $id);
125
126 $ws
127 }
128
129 #############################################################################
130
131 package ext::widget::set;
132
133 sub DESTROY {
134 $_[0]->destroy;
135 }
136
137 sub destroy {
138 my ($self) = @_;
139
140 $self->msg (ws_d => id => $self->{id});
141 delete $self->{ns};
142 $_->destroy
143 for values %{ $self->{w} };
144 }
145
146 sub msg {
147 my ($self, $type, %msg) = @_;
148
149 if (my $ns = shift->{ns}) {
150 $msg{msgtype} = $type;
151 $ns->send_packet ("ext " . cf::to_json \%msg);
152 }
153 }
154
155 sub new {
156 my ($self, $class, %args) = @_;
157
158 my $id = ++$self->{ns}{id};
159
160 my $proxy = $self->{w}{$id} = bless {
161 id => $id,
162 }, "ext::widget::proxy";
163
164 Scalar::Util::weaken ($proxy->{ws} = $self);
165 Scalar::Util::weaken ($proxy->{ns} = $self->{ns});
166 Scalar::Util::weaken ($self->{ns}{widget}{$id} = $proxy);
167
168 for my $ev (grep /^on_/, keys %args) {
169 push @{$proxy->{ev}{$ev}}, $args{$ev};
170 $args{$ev} = 0;
171 }
172
173 $self->msg (ws_c =>
174 ws => $self->{w}{id},
175 id => $id,
176 class => $class,
177 args => \%args,
178 );
179
180 $proxy
181 }
182
183 #############################################################################
184
185 package ext::widget::proxy;
186
187 sub DESTROY {
188 my ($self) = @_;
189
190 delete $self->{ns}{widget}{$self->{id}};
191
192 if (my $ws = $self->{ws}) {
193 delete $ws->{w}{$self->{id}};
194 $self->msg (w_c => name => "destroy");
195 }
196 }
197
198 sub msg {
199 my ($self, $type, %msg) = @_;
200
201 if (my $ws = $self->{ws}) {
202 $ws->msg ($type,
203 %msg,
204 id => $self->{id},
205 );
206 }
207 }
208
209 sub msg_cb {
210 my ($self, $cb, $type, %msg) = @_;
211
212 if (my $ws = $self->{ws}) {
213
214 my $rid = ++$ws->{ns}{id};
215
216 $self->msg ($type, %msg, rid => $rid);
217
218 if ($cb) {
219 $ws->{ns}{widget_return}{$rid} = $cb;
220 } else {
221 # synchronous case
222 my $wait = new Coro::Signal;
223 my @res;
224
225 $ws->{ns}{widget_return}{$rid} = sub {
226 @res = @_;
227 $wait->send;
228 };
229 $wait->wait;
230
231 return @res;
232 }
233 }
234
235 ()
236 }
237
238 sub set {
239 my ($self, $member, $value) = @_;
240
241 $self->msg (w_s => name => $member, value => $value);
242 }
243
244 sub get {
245 my ($self, $member, $cb) = @_;
246
247 $self->msg_cb ($cb, w_g => name => $member);
248 }
249
250 sub TO_JSON {
251 { __widget_ref__ => $_[0]{id} }
252 }
253
254 our $AUTOLOAD;
255
256 sub AUTOLOAD {
257 $AUTOLOAD =~ s/^.*://
258 or return;
259
260 my $self = shift;
261
262 $self->msg (w_c => name => $AUTOLOAD, args => \@_);
263
264 ()
265 }
266