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

# 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     );
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 root 1.1 cf::player->attach (
77     on_login => sub {
78     my ($pl) = @_;
79    
80 root 1.2 return unless $cf::CFG{devel};
81 root 1.1
82     my $ns = $pl->ns;
83    
84 root 1.2 return unless $ns->{can_widget};
85 root 1.1
86 root 1.2 csc_start $ns;
87 root 1.1 },
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