250 likes | 325 Views
Follow Dan Stevens' journey in creating Gnomoradio as an alternative to GarageBand. Learn about the network architecture, C# implementation, and insights from a Ruby fan. Discover why Ruby is a great choice for TRGnomoradio and its web-based UI, which enhances user experience. Dive into the challenges and merits of Ruby, making it a versatile tool for various projects.
E N D
Development of TRGnomoradio By Dan Stevens
Alternatives to the GarageBand rating system • iRate, Gnomoradio, Indy • All based on finding music that you like, rather than what everyone else likes. • Gnomoradio was the only one available at the time that allowed me to submit my music.
TCGnomoradio • Official Gnomoradio client is Linux only! • So I’ll write my own client. • I can make it play stuff through Winamp! • It’ll be an excuse to better learn C# • Windows users will love me.
Winamp • Playback is central – do this first. • Ripped off some dude’s IPC code. • IP API Missing functionality! • No reasonable way to find filename of currently playing song • Use a plugin that can get that information • HttpQ – a simple HTTP interface to Winamp • Now I can talk to Winamp. Yay!
Gnomoradio Consists of • Client • Protocols • Song info • Servers • I only need to worry about interfacing with existing protocols, and designing my own client.
Bu7 what iz t3h pr0tocal? • Anything but documented. • Use the source, Luke. • And then if you’re still confused, use the mailing list. • Then write it up and stick it on http://www.uwplatt.edu/~stevenda/projects/TCGnomoradio/protocols.html
Network architecture A.k.a. TOGoS learns about PowerPoint diagrams. http / xml
Implementaion Time! • First, write a front end that allows me to test things. • Write protocol mod-ules and test usingthe GUI. • … • Profit!
C# is a pain #region RainbowHubSearch private string[] RainbowHubSearch( string resourcename ) { string[] results; try { this.RainbowHubClient.Lock(); results = this.RainbowHubClient.FindResource( resourcename ); } finally { this.RainbowHubClient.Unlock(); } return results; } private delegate string[] RainbowHubSearchDelegate( string resourcename ); private void RainbowHubSearchButton_Click(object sender, System.EventArgs e) { RainbowHubSearchDelegate del = new RainbowHubSearchDelegate( this.RainbowHubSearch ); del.BeginInvoke( this.RainbowHubSearchBox.Text, new AsyncCallback( this.RainbowHubSearchDone ), null ); } private void RainbowHubSearchDone( IAsyncResult result ) { AsyncResult aresult = (AsyncResult)result; RainbowHubSearchDelegate del = (RainbowHubSearchDelegate)(aresult.AsyncDelegate); string[] results = (string[])del.EndInvoke( result ); if( (results != null) && (results.Length > 0) ) { this.RainbowHubSearchResultsBox.Items.AddRange( results ); } } #endregion
Insight from a Ruby Fan • People need design documents because their languages are not HL enough. • C# kinda sucks: • Why do I have to declare delegate types? • Or event types? • Why do I have to do any static typing? • Why do I have to declare new methods instead of using inline code blocks? • I will rewrite in Ruby!
Why Ruby is Grate # String processing (as in Perl) line.strip =~ /^thing #(\d+)$/ # Objects (like Smalltalk, Java, or C#) class FooBar def initialize( num ) @num = num end end FooBar.new( someobject.someproperty )
Why Ruby is Grate (part 2) # Easy to write # * No static typing # * No semicolons # Easily pass code blocks around MyObject.method do |arg1,arg2| # Inline callback! arg1.to_i + arg2 / 5 End # Good for loops Dir.each(‘/home/tog’) do |fn| puts “found file: #{fn}” end
Why Ruby is Grate (part 3) class MyClass def initialize( &proc ) @proc = proc end def result @result ||= @proc.call() end end o = MyClass.new { # expensive operation } p o.result p o.result
Why Ruby is Grate (part 4) require 'TOGoS/Event‘ class MyClass event :sandwich_eaten def eat_sandwich() @sandwich_eaten.trigger( self,1,2,3 ) end End myobj = MyClass.new() myobj.sandwich_eaten.subscribe() do |sender,*args| puts “Teh sandwich was eaten. Here are some args: #{args}” end myobj.eat_sandwich() Teh sandwich was eaten. Here are some args: 123
Why Ruby ain’t perfect • No kernel-level threads • Causes problems when making calls into C code that may take a long time • Developer community not as large as for other languages (Perl, Python) • This is not really a big problem • Slow • Lack of static typing and stack-allocated structures • But it’s still great for a lot of things. • Web servers, page generators, WAD compilers.
TRGnomoradio • Written in Ruby • Because I am more experienced • And because Ruby is grate • Uses a web-based UI • Because I am more experienced • More flexibly generate tables and display data structures in HTML than with GUI widgets • No expectation of fields updating in real time • Let the browser worry about multiple tabs • I need a web server, anyway! • Ruby + Web interface => Cross platform
SS4 and TRServ2 • Libraries that grew out of a file-sharing project I started in 11th grade called “SpookShare” • My big ‘learn Perl but totally misunderstand references, then re-write in PHP and MySQL’ project. • SS2 was written in Ruby and included it’s own web server, TRServ • SS3: SS2 but using different peer-discovery protocols • Became a hacky framework for selecting modules and setting options (TRVousor LiveJournal, advertise or not, etc) • Re-wrote TRServ into TRServ2 to better support HTTP/1.1 • SS4: a well-designed framework for selecting modules and setting options • Easy to write plugin modules for anything ruby • Basically a big hashtable and a configuration language
TRGnomoradio (part 2) • Embedded TRServ2 as an SS4 module • Wrote libraries, made forms and links to test various functions • Wrote some back-end logic to download information on recommended songs • Wrote some front-end logic to display that information • Tried to run on my Windows box to try with Winamp…
TRGnomoradio (part 3) • resolv-replace doesn’t seem to work on Win. • Might have something to do with me being behind a firewall? • I’m busy doing homework. • This project got boring. • The Gnomoradio project seems to be a bit deadish. • Gnomoradio.org has annoying bugs that I can’t work around
Comparing to a standard development model • TOGoS-style development • Emphasizes getting something to work • Good for short-term projects • Good for single developer, or a small team if work can be split up easily • Rowe-style development • Emphasizes design and documentation • Good for long-term projects • Good for large teams, especially when components will have complex interfaces
Comparing to a standard development model (part 2) • TOGoS-style development • Very little overhead. • Requires programmers to know what they’re doing. • Involves a lot of re-factoring. • Generalize functionality for later use so that the next project is easier • Rowe-style development • Loads of overhead. • Programmers can be total idiots, because they are not necessarily doing design. • Involves following the friggin’ design.
Comparing to a standard development model • TOGoS-style development • We love Ruby • Grunt work is frustrating and is a distraction from high-level architecture • Rowe-style development • Clunkier languages like Java or C# are not such a problem • Make the code monkeys do the grunt work of typing “public static void” a million times. • Static typing is more useful for ensuring sanity
Fin Unless I forgot to say something