Wiki

Changes between Initial Version and Version 1 of Events

Show
Ignore:
Timestamp:
05/13/10 11:52:16 (15 years ago)
Author:
hopscc
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Events

    v1 v1  
     1= Events =  
     2 
     3An event is a message sent by an object to signal the occurrence of an action.  
     4 
     5The object that raises (triggers) the event is called the event sender or event source.[[BR]]  
     6The object that receives the event and responds to it is called the event receiver or Listener 
     7 
     8An event is declared with a type corresponding to a method signature ('''sig''') 
     9 
     10Objects that have an interest in the event register to '''listen''' to the event[[BR]]  
     11(more specifically provide to the event a reference to one of their methods matching the [[BR]] 
     12event signature).  
     13 
     14When the event is '''raised''' (or fires) any and all objects that registered an interest in [[BR]] 
     15the event (listeners) get their (registered) method called with the arguments provided[[BR]] 
     16when raising the event. 
     17 
     18Objects may unregister a prior interest in an event by subsequently '''ignoring''' the event[[BR]] 
     19specifying the same method reference they previously listened with. 
     20 
     21On these constructs decoupled notification and handling can be built.[[BR]]  
     22All that is required is that an objects events of interest are exposed and[[BR]] 
     23the signature of the events are known to interested parties 
     24(or a registration interface is available) . 
     25 
     26== Grammar == 
     27{{{ 
     28 
     29# specify the signature of an event 
     30sig SIG_TYPENAME(ARGS) as TYPE 
     31 
     32# declare an event 
     33event EVENT_NAME as SIG_TYPENAME 
     34 
     35#register handler/listener method for an event 
     36listen EVENT_NAME, ref METHODNAME 
     37 
     38#unregister handler/listener for an event 
     39ignore EVENT_NAME, ref METHODNAME 
     40 
     41# raise/fire an event 
     42raise EVENT_NAME, [sender,] arg [, arg ...] 
     43}}} 
     44 
     45== Platform == 
     46 
     47== Examples == 
     48This (large) example does it all.[[BR]] 
     49Declare Event arguments, declare signature and events[[BR]] 
     50Raise events in response to something happening, define receivers/listeners that are[[BR]] 
     51interested in the event ('something happening'), bind event senders and listeners  together. 
     52 
     53(FWIW its the C# example at [http://msdn.microsoft.com/en-us/library/9aackb16%28v=VS.71%29.aspx Event Sample] converted to cobra.) 
     54{{{ 
     55namespace EventSample 
     56 
     57    # Data for the alarm event. Derives from System.EventArgs. 
     58    class AlarmEventArgs inherits EventArgs  
     59      
     60        var __snoozePressed as bool #is private #,readonly 
     61        var _nrings        as int is private    #,readonly 
     62       
     63        cue init(snoozePressed as bool, nrings as int)  
     64            base.init 
     65            __snoozePressed = snoozePressed 
     66            _nrings = nrings 
     67       
     68        # number of rings that the alarm clock has sounded when the alarm event is generated. 
     69        get numRings from _nrings 
     70       
     71        # indicates whether the snooze button is pressed on the alarm when the alarm event is generated. 
     72        get snoozePressed from __snoozePressed 
     73       
     74        # alarmText property that contains the wake-up message. 
     75        get alarmText  
     76            return if(__snoozePressed, 'Wake Up!!! Snooze time is over.', 'Wake Up!') 
     77    
     78    
     79    # Delegate declaration. 
     80    sig AlarmEventHandler(sender as Object, e as AlarmEventArgs ) 
     81 
     82    # The Alarm class that raises the alarm event. 
     83    class AlarmClock  
     84        var _snoozePressed = false  
     85            is private 
     86        var _nrings = 0i32  # int32 
     87            is private  
     88        var _stop = false 
     89            is private 
     90         
     91        # The Stop property indicates whether the alarm should be turned off. 
     92        pro stop from _stop 
     93       
     94        # The SnoozePressed property indicates whether the snooze 
     95        # button is pressed on the alarm when the alarm event is generated. 
     96        pro snoozePressed from var  
     97       
     98        # The event member that is of type AlarmEventHandler. 
     99        event alarm as AlarmEventHandler  
     100 
     101        # The protected OnAlarm method raises the event by invoking the delegate.  
     102        # The sender is always .this, the current instance of the class. 
     103        def onAlarm(e as AlarmEventArgs) is protected 
     104            # Invokes the delegate.  
     105            raise .alarm, e 
     106       
     107        # Alarm clock does not have a user interface.  
     108        # To simulate the alarm mechanism it has a loop that raises the alarm event at every iteration 
     109        # with a time delay of 300 milliseconds, if snooze is not pressed.  
     110        # If snooze is pressed, the time delay is 1000 milliseconds. 
     111        def start 
     112            while true 
     113                _nrings += 1 
     114                if _stop 
     115                    break 
     116                else if _snoozePressed 
     117                    System.Threading.Thread.sleep(1000) 
     118                    e = AlarmEventArgs(_snoozePressed, _nrings) 
     119                    .onAlarm(e) 
     120                else 
     121                    System.Threading.Thread.sleep(300) 
     122                    e = AlarmEventArgs(_snoozePressed, _nrings) 
     123                    .onAlarm(e) 
     124    
     125        # The WakeMeUp class that has a method AlarmRang that handles the alarm event. 
     126        class WakeMeUp 
     127            def alarmRang(sender as Object, e as AlarmEventArgs) 
     128                print e.alarmText 
     129                if not e.snoozePressed 
     130                    if e.numRings % 10 == 0 
     131                        print ' Let alarm ring? Enter Y' 
     132                        print ' Press Snooze? Enter N' 
     133                        print ' Stop Alarm? Enter Q' 
     134                        input = Console.readLine 
     135                        if input.equals('Y') or input.equals('y') 
     136                            return 
     137                        else if input.equals('N') or input.equals('n') 
     138                            (sender to AlarmClock).snoozePressed = true 
     139                            return 
     140                        else 
     141                            (sender to AlarmClock).stop = true 
     142                            return 
     143                else 
     144                    print ' Let alarm ring? Enter Y' 
     145                    print ' Stop Alarm? Enter Q' 
     146                    input = Console.readLine 
     147                    if input.equals('y') or input.equals('y') 
     148                        return 
     149                    else  
     150                        (sender to AlarmClock).stop = true 
     151                        return 
     152    
     153        # The driver class that hooks up the event handling method of 
     154        # WakeMeUp to the alarm event of an Alarm object using a delegate. 
     155        class AlarmDriver 
     156            def main is shared 
     157                # args = CobraCore.commandLineArgs 
     158                w = WakeMeUp()  # Instantiates the event receiver. 
     159 
     160                clock = AlarmClock() # Instantiates the event source. 
     161 
     162                # Wires the AlarmRang method to the Alarm event. 
     163                listen clock.alarm, ref w.alarmRang 
     164                # clock.alarm += new AlarmEventHandler(w.AlarmRang) 
     165 
     166                clock.start 
     167       
     168}}} 
     169 
     170Perhaps more commonly the sigs, events and senders are already defined (in a library or framework)[[BR]] 
     171and we are only interested in registering for an event and reacting when the event is raised. 
     172 
     173Heres an example of that around some GUI components:[[BR]] 
     174The buttons and form have Keypress and !MouseClick events and associated machinery already defined for them.[[BR]] 
     175The example just sets up binding to the listener methods and 'does something' when the events fire [[BR]] 
     176(print some of the args fields in this case). 
     177{{{ 
     178%% args -target:exe 
     179 
     180use System.Windows.Forms 
     181use System.Drawing 
     182 
     183class MyForm 
     184    inherits Form 
     185 
     186    cue init 
     187        base.init 
     188 
     189        b = Button() 
     190        b.text="press me" 
     191        .controls.add(b) 
     192 
     193        listen b.mouseClick, ref .handleMouseClick 
     194        listen b.keyPress, ref .handleKey 
     195        listen .keyPress, ref .handleKey 
     196 
     197    def handleClick(sender as Object, args as EventArgs) 
     198        m = args to MouseEventArgs 
     199        print 'btn=[m.button]' 
     200        print "Locn=[m.location]" 
     201        print m 
     202 
     203    def handleMouseClick(sender as Object, m as MouseEventArgs) 
     204        print 'btn    =[m.button]' 
     205        print 'mb=[Control.mouseButtons]' 
     206        print 'delta =[m.delta]' 
     207        print 'clicks =[m.clicks]' 
     208        print "Locn   =[m.location]" 
     209        print m 
     210 
     211    def handleKey(sender as Object, kp as KeyPressEventArgs) 
     212        print 'KeyPressed', 'key=', kp.keyChar 
     213                 
     214class Program 
     215 
     216    def main is shared has STAThread 
     217        Application.run(MyForm()) 
     218}}} 
     219 
     220== Notes == 
     221 
     222With reference to C# nomenclature  
     223    * a cobra '''sig''' is roughly comparable to a C# delegate 
     224    * An event is an event in both 
     225    * 'wiring method to event' or 'instantiating an event delegate' is done in cobra via a '''listen''' statement 
     226    * 'Invoking a delegate' is done in cobra via the '''raise''' statement. 
     227 
     228Declaration/execution flow is  
     229    '''sig''' - '''event''' - '''listen''' - '''raise'''  - '''(ignore)''' 
     230 
     231 
     232== See Also == 
     233[http://msdn.microsoft.com/en-us/library/edzehd2t%28v=VS.71%29.aspx Handling and raising events] 
     234in .Net Framework Developers Guide 
     235 
     236 
     237[wiki:LanguageTopics Back to LanguageTopics]