devNotes 5-03-16 midi specs, delegates and events

MIDI WORLD – VIDEO GAME THEMES

tones_in_tune

dfghfgdhgf6

TIME BREAKDOWN – MIDI Unified

 

Helmholtz-Pitch-Naming-And-Octave-Numbering-Grand-Staff

sdfgfdsgfdg

shim_50

The Basic Delegate

(from)

An interesting and useful property of a delegate is that it does not know or care about the class of the object that it references. Any object will do; all that matters is that the method’s argument types and return type match the delegate’s. This makes delegates perfectly suited for “anonymous” invocation.

The signature of a single cast delegate is shown below:

where:

result-type: The result type, which matches the return type of the function.
identifier: The delegate name.
parameters: The Parameters, that the function takes.

shim_50
Examples:

This declaration defines a delegate named SimpleDelegate, which will encapsulate any method that takes
no parameters and returns no value.

 

This declaration defines a delegate named ButtonClickHandler, which will encapsulate any method that takes
two objects as parameters and returns an int.

 

A delegate will allow us to specify what the function we’ll be calling looks like without having to specify which function to call. The declaration for a delegate looks just like the declaration for a function, except that in this case, we’re declaring the signature of functions that this delegate can reference.

 

There are three steps in defining and using delegates:

  • Declaration
  • Instantiation
  • Invocation

 

A very basic example (SimpleDelegate1.cs):

 

Compile and test:

 

 shim_50

Calling Static Functions

For our next, more advanced example (SimpleDelegate2.cs), declares a delegate that takes a single string parameter and has no return type:

 

Compile and test:

 

 shim_50

Calling Member Functions

 

In the simple example above, the Logger( ) function merely writes the string out. A different function might want to log the information to a file, but to do this, the function needs to know what file to write the information to (SimpleDelegate3.cs)

 

The cool part here is that we didn’t have to change the Process() function; the code to all the delegate is the same regardless of whether it refers to a static or member function.

Compile an test:

 shim_50

Multicasting

 

Being able to point to member functions is nice, but there are more tricks you can do with delegates. In C#, delegates are multicast, which means that they can point to more than one function at a time (that is, they’re based off the System.MulticastDelegate type). A multicast delegate maintains a list of functions that will all be called when the delegate is invoked. We can add back in the logging function from the first example, and call both delegates. Here’s what the code looks like:

 

Compile and test:

 shim_50

Events

The Event model in C# finds its roots in the event programming model that is popular in asynchronous programming. The basic foundation behind this programming model is the idea of “publisher and subscribers.” In this model, you have publishers who will do some logic and publish an “event.” Publishers will then send out their event only to subscribers who have subscribed to receive the specific event.

In C#, any object can publish a set of events to which other applications can subscribe. When the publishing class raises an event, all the subscribed applications are notified. The following figure shows this mechanism.

dotnet_user_control_1

Conventions

The following important conventions are used with events:

Event Handlers in the .NET Framework return void and take two parameters.
The first paramter is the source of the event; that is the publishing object.
The second parameter is an object derived from EventArgs.
Events are properties of the class publishing the event.
The keyword event controls how the event property is accessed by the subscribing classes.

shim_50

Simple Event

 

Let’s modify our logging example from above to use an event rather than a delegate:

 

Compile and Test:

shim_50

The Second Change Event Example

Suppose you want to create a Clock class that uses events to notify potential subscribers whenever the local time changes value by one second. Here is the complete, documented example:

shim_50

Conclusion

The Clock class from the last sample could simply print the time rather than raising an event, so why bother with the introduction of using delegates? The advantage of the publish / subscribe idiom is that any number of classes can be notified when an event is raised. The subscribing classes do not need to know how the Clock works, and the Clock does not need to know what they are going to do in response to the event. Similarly a button can publish an Onclick event, and any number of unrelated objects can subscribe to that event, receiving notification when the button is clicked.

The publisher and the subscribers are decoupled by the delegate. This is highly desirable as it makes for more flexible and robust code. The clock can change how it detects time without breaking any of the subscribing classes. The subscribing classes can change how they respond to time changes without breaking the Clock. The two classes spin independently of one another, which makes for code that is easier to maintain.

MIDI_Unified

 

 

Midid-1