So sources of MIDI messages now look like your everyday class that just happens to have one or more events. NET events are something very familiar to us. There are two advantages here: First, sources no longer have to implement an ISource interface, and second. Instead of implementing an interface and having Connect and Disconnect methods for hooking to sinks, they would simply have events. Sources of MIDI messages raise events when they have messages to send. I decided to do away with the sink/source infrastructure and use something more idiomatic. This worked well but it was a little confusing because the implementation looked a little "funny." That is to say, a C# programmer looking at the code for the first time might be confused as to what is going on. "Sinks" were represented by delegates that could be connected to sources a sink is simply a method capable of receiving a MIDI message. I created an interface representing "Sources." A source represents a source of MIDI messages. In version four of the toolkit, I settled on the idea of using a source/sink abstraction. I found myself going round in circles on this. You can read a bit about the different ways I tried to achieve this by reading my blog. Well, this is something I really struggled with. Top Implementing flow-based programming in C# Here they are sent to an external MIDI device. Finally, the messages reach the output device. When the message flow stops, the channel stopper can turn off all sounding notes so that none of them hang. This component simply keeps track of all currently sounding notes. Then the messages pass through the channel stopper. This component might want to do something like change the MIDI channel, transpose note messages, or change the messages in some way. Next, the messages flow through a user component. An input device receives MIDI messages from an external source. The flow of messages begins with the input device. A component is simply an object in a chain of objects designed to process the flow of messages.)īelow is a very basic network of components designed to handle the flow of MIDI channel messages: (Just to be clear: when I say "component," I'm not necessarily talking about classes that implement the IComponent interface. Paul Morrison's excellent book for more information. In design pattern terms, this approach is most like the Pipe and Filter pattern and is also similar to the Chain of Responsibility pattern. Each component can do something interesting with the data before passing it along to the next component. The idea is simple and will probably seem familiar to most: Data flows through a network of components. He has written a book on the subject, which can be found on his website as well as at Amazon. Paul Morrison's excellent website on flow-based programming. In other words, the toolkit should be customizable and configurable. It should be easy to simply plug the harmonizer into the toolkit without affecting other classes. For example, say you wanted to write a harmonizer, a class capable of transposing notes in a specified key to create harmony parts automatically. It would be nice, I thought, if users could plug their own classes into the flow of MIDI messages to do whatever they want. I wanted an approach that would be versatile and allow customization. With each version of the toolkit, I have struggled with how to structure the flow of messages through the system. Not exactly the attitude one wants to adopt in a professional setting, but since the toolkit is free and since I have used it as a learning experience to improve my craft, my priorities are different.īefore I get into the specifics of the toolkit, I would like to talk about its architecture. This has led me to revise the earlier designs of the toolkit without regard to how these revisions will break code. As I have grown as a programmer, I have improved my skills and understanding of software design. However, my goal in creating this toolkit has been to provide the best design possible. When writing software, it is usually a bad idea to make updates that break software using previous versions. Each revision has been an almost total rewrite of the previous one. The toolkit has seen many revisions over the past two to three years. I'm hoping that this will make the toolkit easier to use and understand. I wasn't comfortable with version four's implementation along these lines, so I took a step back and made changes that keep the flow-based approach while remaining within C#/.NET accepted idioms. This version takes a more traditional C#/.NET approach to flow-based programming, which I'll describe below. I had thought that the previous version was the final one, but I have made many changes that have warranted a new version. Implementing flow-based programming in C#.
0 Comments
Leave a Reply. |