1 #
2 # tk/virtevent.rb : treats virtual events
3 # 1998/07/16 by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp>
4 #
5 require 'tk'
6
7 class TkVirtualEvent<TkObject
8 extend Tk
9
10 TkCommandNames = ['event'.freeze].freeze
11
12 (TkVirtualEventID = ["VirtEvent".freeze, "00000".taint]).instance_eval{
13 @mutex = Mutex.new
14 def mutex; @mutex; end
15 freeze
16 }
17
18 TkVirtualEventTBL = TkCore::INTERP.create_table
19
20 TkCore::INTERP.init_ip_env{
21 TkVirtualEventTBL.mutex.synchronize{ TkVirtualEventTBL.clear }
22 }
23
24 class PreDefVirtEvent<self
25 def self.new(event, *sequences)
26 if event =~ /^<(<.*>)>$/
27 event = $1
28 elsif event !~ /^<.*>$/
29 event = '<' + event + '>'
30 end
31 TkVirtualEvent::TkVirtualEventTBL.mutex.synchronize{
32 if TkVirtualEvent::TkVirtualEventTBL.has_key?(event)
33 TkVirtualEvent::TkVirtualEventTBL[event]
34 else
35 # super(event, *sequences)
36 (obj = self.allocate).instance_eval{
37 initialize(event, *sequences)
38 TkVirtualEvent::TkVirtualEventTBL[@id] = self
39 }
40 end
41 }
42 end
43
44 def initialize(event, *sequences)
45 @path = @id = event
46 _add_sequences(sequences)
47 end
48 end
49
50 def TkVirtualEvent.getobj(event)
51 obj = nil
52 TkVirtualEventTBL.mutex.synchronize{
53 obj = TkVirtualEventTBL[event]
54 }
55 if obj
56 obj
57 else
58 if tk_call_without_enc('event', 'info').index("<#{event}>")
59 PreDefVirtEvent.new(event)
60 else
61 fail ArgumentError, "undefined virtual event '<#{event}>'"
62 end
63 end
64 end
65
66 def TkVirtualEvent.info
67 tk_call_without_enc('event', 'info').split(/\s+/).collect!{|seq|
68 TkVirtualEvent.getobj(seq[1..-2])
69 }
70 end
71
72 def initialize(*sequences)
73 TkVirtualEventID.mutex.synchronize{
74 # @path = @id = '<' + TkVirtualEventID.join('') + '>'
75 @path = @id = '<' + TkVirtualEventID.join(TkCore::INTERP._ip_id_) + '>'
76 TkVirtualEventID[1].succ!
77 }
78 _add_sequences(sequences)
79 end
80
81 def _add_sequences(seq_ary)
82 unless seq_ary.empty?
83 tk_call_without_enc('event', 'add', "<#{@id}>",
84 *(seq_ary.collect{|seq|
85 "<#{tk_event_sequence(seq)}>"
86 }) )
87 end
88 self
89 end
90 private :_add_sequences
91
92 def add(*sequences)
93 if sequences != []
94 _add_sequences(sequences)
95 TkVirtualEventTBL.mutex.synchronize{
96 TkVirtualEventTBL[@id] = self
97 }
98 end
99 self
100 end
101
102 def delete(*sequences)
103 if sequences == []
104 tk_call_without_enc('event', 'delete', "<#{@id}>")
105 TkVirtualEventTBL.mutex.synchronize{
106 TkVirtualEventTBL.delete(@id)
107 }
108 else
109 tk_call_without_enc('event', 'delete', "<#{@id}>",
110 *(sequences.collect{|seq|
111 "<#{tk_event_sequence(seq)}>"
112 }) )
113 if tk_call_without_enc('event','info',"<#{@id}>").empty?
114 TkVirtualEventTBL.mutex.synchronize{
115 TkVirtualEventTBL.delete(@id)
116 }
117 end
118 end
119 self
120 end
121
122 def info
123 tk_call_without_enc('event','info',"<#{@id}>").split(/\s+/).collect!{|seq|
124 lst = seq.scan(/<*[^<>]+>*/).collect!{|subseq|
125 case (subseq)
126 when /^<<[^<>]+>>$/
127 TkVirtualEvent.getobj(subseq[1..-2])
128 when /^<[^<>]+>$/
129 subseq[1..-2]
130 else
131 subseq.split('')
132 end
133 }.flatten
134 (lst.size == 1) ? lst[0] : lst
135 }
136 end
137 end
138
139 TkNamedVirtualEvent = TkVirtualEvent::PreDefVirtEvent