1# 2# tk/virtevent.rb : treats virtual events 3# 1998/07/16 by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp> 4# 5require 'tk' 6 7class TkVirtualEvent<TkObject 8 extend Tk 9 10 TkCommandNames = ['event'.freeze].freeze 11 12 (TkVirtualEventID = ["VirtEvent".freeze, TkUtil.untrust("00000")]).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.empty? 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 137end 138 139TkNamedVirtualEvent = TkVirtualEvent::PreDefVirtEvent 140