1 type Multimap<K, V> @abstract = 2 let multimap = StdMultimap<K, V>.new 3 let mut is_invoking_callbacks = false 4 let on_added_callbacks = StdList<K * V -> Unit>.new 5 let on_removed_callbacks = StdList<K * V -> Unit>.new 6 let tokens = List<Token>.new 7 8 def subscribe (f : K * V -> Unit 9 g : K * V -> Unit) = 10 assert not is_invoking_callbacks 11 12 on_added_callbacks.add f 13 on_removed_callbacks.add g 14 15 Token { assert not is_invoking_callbacks 16 on_added_callbacks.remove f 17 on_removed_callbacks.remove g } 18 19 def bind (f : K * V -> Unit) (g : K * V -> Unit) = 20 assert not is_invoking_callbacks 21 22 on_added_callbacks.add f 23 on_removed_callbacks.add g 24 25 for k, v in multimap do 26 f k v 27 28 Token { assert not is_invoking_callbacks 29 on_added_callbacks.remove f 30 on_removed_callbacks.remove g 31 32 for k, v in multimap do 33 g k v } 34 35 def contains (k : K) = multimap.contains k 36 fun get (k : K) = multimap[k] 37 38 def push_token (token : Token) = 39 tokens.add token 40 41 type MutMultimap<K, V> @[mut_of Multimap] = 42 inherit Multimap<K, V> 43 44 let invoke_callbacks (callbacks : StdList<K * V -> Unit> 45 k : K 46 v : V) = 47 assert not is_invoking_callbacks 48 is_invoking_callbacks = true 49 50 for f in callbacks do 51 f k v 52 53 is_invoking_callbacks = false 54 55 def add (k : K) (v : V) = 56 multimap.add k v 57 invoke_callbacks on_added_callbacks k v 58 59 def remove (k : K) (v : V) = 60 multimap.remove k v 61 invoke_callbacks on_removed_callbacks k v 62 63 def as_readonly = self as Multimap<K, V> 64