>> but it does have references to a hardcoded list of types of subclasses.
I don't see where it has any hardcoded references to sub classes. StoredVideo, StoredAudio, LiveTV, InternetRadio are not sub classes. They are the types of media that any of the sub classes can handle.
The base class is MediaStream. The subclasses (so far) are XineMediaStream, VDRMediaStream, MythTVMediaStream, now MPlayerMediaStream, in the future GStreamerMediaStream, and so on.
All of them share the same list of media types, and play one or more of those types. They can all play a subset of Video, Audio, LiveTV, InternetRadio, etc. And whether you're using Xine, MPlayer, VDR, Myth, etc., the type 'Video' and 'LiveTV' always contain video, and the type 'Audio' and 'InternetRadio' do not. The purpose of ContainsVideo is simple. It's just to know if the TV should be turned on or not. I still don't see what's wrong with having this list in the base class as *a default fallback*. If you're creating your own media plugin and in your case InternetRadio does contain video, then in your derived media stream just define ContainsVideo and put your own logic in there.
I wrote the VDR Plugin, for example. It took me less than 1 hour to write VDR Plugin and get to the point where there's a VDR button on the menu and when you choose it, the TV comes on, goes to the right inputs, the stereo, etc., any other media in the zone is stopped, and the VDR device is started. And it took very little code. This is because 99% of the logic is the same between VDR, Myth, Xine, and the other media plugins. So having default behavior, like a function 'ContainsVideo' which knows that media type LiveTV has video, saved a ton of coding and time, and reduced the chance of errors a lot. If the base class didn't have this functionality and to add my VDR Plugin I had to write all the code all over again which, for example, determines that LiveTV has video, and to turn on the TV, and all that other stuff, it would have taken a lot longer and introduced a lot more possibilities for errors.
Note: I'm not saying the design is great, nor that VDR only took 1 hour to implement. I'm sure the design could be improved upon, and welcome all the feedback. It just seems the function in question is very, very trivial and insignificant. It's a tiny piece of logic that just that returns true for Video and LiveTV since there's a video component, and for Music and Internet Radio returns false. A lot of the code in Media Plugin does get really complex. And there's a lot of spaghetti code that could be much improved. This 'ContainsVideo' function represents 0.000001% of the work and logic in Media Plugin, and is just a tiny trivial function. So I humbly suggest that while it may be possible to improve it, spending this much effort engineering an OO to a function that is so simple is really over-engineering. I still have trouble understanding how it could possibly get in anybody's way. Again, if you're doing your own derived Media Stream and don't like the hardcoded list, just change it in your derived class. It can't possibly get in your way since you can change it if you like. But since Xine, Myth, VDR, VLC, MPlayer, etc. all use the same list the same way (ie in all of them Video and LiveTV have video, and Audio and InternetRadio do not), why remove this code from change the base class, forcing us to copy/paste the same identical code into each of the derived classes?
BTW, there was already a media type for games anyway, which you'll see is in the list. So if you just give your derived MediaStream for games that media type, the TV should come on without you needing to write any code. But back to Thom's original post that he can't create a new plugin because he doesn't like the behavior of ContainsVideo in the base class, just override it in your derived class and then this much maligned code in the base class will never get called.