ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/ext/widget.ext
Revision: 1.3
Committed: Tue Jun 26 04:50:05 2007 UTC (17 years ago) by root
Branch: MAIN
Changes since 1.2: +12 -8 lines
Log Message:
shstr is utf-8

File Contents

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