3 use overload '""' => 'ID';
5 our $PI = 3.1415926535;
16 my ($class, $id) = @_;
20 !defined $known_objs{$id} or die "Object $id already defined";
21 $known_objs{$id} = $o;
22 print "Created object $id\n" if $debug;
23 return bless $o, $class;
27 my ($class, $id) = @_;
28 defined $known_objs{$id} or die "Object $id not known";
29 return $known_objs{$id};
35 while ($o = shift @pending_recalcs) {
36 print "Going to recalculate object $o\n" if $debug;
37 my $pend = $o->{PENDING};
38 foreach my $a (keys %$pend) {
46 my ($class, $cairo) = @_;
48 print "Redrawing the scene...\n" if $debug;
49 foreach my $o (values %known_objs) {
50 push @q, $o if defined $o->{'a:d'};
52 foreach my $o (sort { $a->{'a:d'} <=> $b->{'a:d'} } @q) {
53 print "Drawing $o at depth ", $o->{'a:d'}, "\n" if $debug;
59 return (shift @_)->{ID};
64 !exists $o->{"a:$a"} or die "Redefining attribute $a of object $o";
65 $o->{"a:$a"} = undef; # attribute value
66 # $o->{"f:$a"} = undef; # binding function
67 $o->{"d:$a"} = { }; # depends on (obj:attr => obj)
68 $o->{"n:$a"} = { }; # notify (obj:attr => obj)
84 my ($o, $a, $v, $b) = @_;
86 $o->Bind($a, sub { $v->Get($b); });
91 return defined $o->{"a:$a"};
96 defined $o->{"a:$a"} or die "Getting undefined attribute $a of object $o";
98 # record the dependency
100 if (!defined $record_deps->{$did}) {
101 $record_deps->{$did} = $o;
102 my $rid = "$record_dep_obj:$record_dep_attr";
103 $o->{"n:$a"}->{$rid} = $record_dep_obj;
104 print "Added automatic dependency $rid -> $did\n" if $debug;
111 my ($o, $a, $v) = @_;
112 exists $o->{"a:$a"} or die "Setting undefined attribute $a of object $o";
113 print "Setting $o:$a = $v\n" if $debug;
115 !defined $o->{"f:$a"} or $o->UnBind($a);
120 my ($o, $a, $f) = @_;
121 exists $o->{"a:$a"} or die "Binding undefined attribute $a of object $o";
122 print "Binding $o:$a\n" if $debug;
131 $record_deps = $o->{"d:$a"};
132 $record_dep_obj = $o;
133 $record_dep_attr = $a;
135 $o->{"a:$a"} = undef;
136 $o->{"a:$a"} = &{$o->{"f:$a"}} ($o);
138 $record_deps = undef;
139 $record_dep_obj = undef;
140 $record_dep_attr = undef;
142 print "Recalculated $o:$a = ", $o->{"a:$a"}, "\n" if $debug;
149 foreach my $dep (keys %{$o->{"d:$a"}}) {
150 my ($deponame, $depa) = split(/:/, $dep);
151 my $depo = $o->{"d:$a"}->{$dep};
152 delete $depo->{"n:$depa"}->{$aid};
153 print "Removed notify $aid -> $depo:$depa\n" if $debug;
161 foreach my $dep (keys %{$o->{"n:$a"}}) {
162 my ($deponame, $depa) = split(/:/, $dep);
163 my $depo = $o->{"n:$a"}->{$dep};
164 print "Sending notify $o:$a -> $deponame:$depa\n" if $debug;
165 if (!defined $depo->{PENDING}) {
166 $depo->{PENDING} = { };
167 push @pending_recalcs, $depo;
168 print "\tPending object $deponame\n" if $debug;
170 $depo->{PENDING}->{$depa} = 1;