5 class ['a] memo () = object
6 constraint 'a = #widget
7 val tbl = Hashtbl.create 7
8 method add (obj : 'a) =
9 Hashtbl.add tbl ~key:obj#get_id ~data:obj
10 method find (obj : widget) = Hashtbl.find tbl obj#get_id
11 method remove (obj : widget) = Hashtbl.remove tbl obj#get_id
16 let next_callback_id () : GtkSignal.id =
17 decr signal_id; Obj.magic (!signal_id : int)
19 class ['a] signal () = object (self)
20 val mutable callbacks : (GtkSignal.id * ('a -> unit)) list = []
21 method callbacks = callbacks
22 method connect ~after ~callback =
23 let id = next_callback_id () in
25 if after then callbacks @ [id,callback] else (id,callback)::callbacks;
28 List.exists callbacks ~f:
30 let old = GtkSignal.push_callback () in
31 try f arg; GtkSignal.pop_callback old
32 with exn -> GtkSignal.pop_callback old; raise exn
35 method disconnect key =
36 List.mem_assoc key callbacks &&
37 (callbacks <- List.remove_assoc key callbacks; true)
40 class virtual ml_signals disconnectors =
43 method after = {< after = true >}
44 val mutable disconnectors : (GtkSignal.id -> bool) list = disconnectors
45 method disconnect key =
46 ignore (List.exists disconnectors ~f:(fun f -> f key))
49 class virtual add_ml_signals obj disconnectors =
51 val mutable disconnectors : (GtkSignal.id -> bool) list = disconnectors
52 method disconnect key =
53 if List.exists disconnectors ~f:(fun f -> f key) then ()
54 else GtkSignal.disconnect obj key
57 class ['a] variable_signals ~(set : 'a signal) ~(changed : 'a signal) =
59 inherit ml_signals [changed#disconnect; set#disconnect]
60 method changed = changed#connect ~after
61 method set = set#connect ~after
64 class ['a] variable x =
66 val changed = new signal ()
67 val set = new signal ()
68 method connect = new variable_signals ~set ~changed
69 val mutable x : 'a = x
72 method private equal : 'a -> 'a -> bool = (=)
73 method private real_set y =
75 if changed#callbacks <> [] && not (self#equal x x0)
78 ignore (set#connect ~after:false ~callback:self#real_set)