tsc_EventArgs

The tsc_EventArgs class is used in conjunction with tsc_Event and tsc_EventDelegate to pass information from the producer of an event to the event handlers.  It may also be used to pass information back from handlers to the producer.

tsc_EventArgs is not useful on its own.  It should be subclassed to include any extra information that is to be passed to or from the handlers.

When tsc_Event::Invoke() is used to raise an event, the tsc_EventArgs subclass may be simply constructed and passed to Invoke, which will pass it to each handler in turn.  All handlers receive the same pointer to the same object, and it will be accessed sequentially.  When Invoke returns, the object may be disposed of, if that is necessary.  Information may be passed in either direction using tsc_EventArgs, but remember that the same object is shared by all handlers; if a member is modified by multiple handlers, all values except the last will have been overwritten.

When tsc_Event::BeginInvoke() is used to raise the event (as opposed to Invoke()), the lifetime of the tsc_EventArgs subclass becomes problematic, since BeginInvoke returns immediately, usually before any handlers have been called.  This means the tsc_EventArgs object can not be local to the function that calls BeginInvoke, since the object may go out of scope before the event handlers have finished.

Ideally, the tsc_EventArgs object will be allocated on the heap using new, so that the pointer remains valid while the handlers are called.  When the last handler has finished, the virtual OnInvokeCompleted method in the tsc_EventArgs object will be called by the system.  This method should be overidden in the subclass to dispose of the object, probably by executing "delete this". Because the object will cease to exist at this time, it is important that the delete be the last statement in OnInvokeCompleted.

Public members

tsc_EventArgs();
Constructs an empty object.

virtual void OnInvokeCompleted () { };
Override this method in a subclass to perform any actions required when all handlers have run to completion.  If not overidden, the function does nothing.

Sample code

This example is incomplete but shows how to subclass tsc_EventArgs and use it to pass a message (a tsc_String) from the event's producer to any handlers which subscribe to the event.

// A subclass to transport a message to the event handlers. 

class MessageArgs : public tsc_EventArgs 

public: 

    tsc_String  Message;

    

    MessageArgs (tsc_String msg) : Message(msg) 

    { 

    } 

    

private: 

    void OnInvokeComplete(void* sender) 

    { 

        delete this;  // All handlers have been called, delete the object. 

    } 

}; 


// This is a class that produces events with a message in them. 

class MyEventProducer 

public:

    tsc_Event  MessageEvent;

    

    void SendMessageEvent (tsc_String msg)

    {

        MessageEvent.BeginInvoke (this, new MessageArgs(msg));   // Raise an event.

    }

};


// A class to consume a message event. 

class Consumer

public:

    Consumer(MyEventProducer* producer)

    {

        NewMessage.Bind(this);                 // Bind the delegate to our handler class.

        producer->MessageEvent += NewMessage;  // Subscribe to the message event.

    }

     

private:

    void OnNewMessage (void* sender, tsc_EventArgs* eargs)

    {

        MessageArgs* margs = (MessageArgs*)eargs;                // Cast to our subclass. (NOT type-safe!)

        tsc_MessageBox::Show("New message", margs->Message);

    }

    

    tsc_EventDelegate (NewMessage, Consumer);

 };