koraktor / steam-condenser

A multi-language library for querying the Steam Community, Source, GoldSrc servers and Steam master servers
https://koraktor.de/steam-condenser
Other
359 stars 66 forks source link

Code generation #76

Closed txdv closed 12 years ago

txdv commented 13 years ago

I was coding along and I found myself writing the same code all over again. While ruby is dynamic enough to create all the methods needed on the fly or do something when a method is missing (method_missing), languages like Java are too static in nature. I think a code generator to generate all the interfaces needed would be the best solution for Java/C#2.0.

For now the a lot of the Java code uses one variable (a map) to hold a different variable values. I understand that in Java you have actually to create a lot of getters and setters if you do it the Java way and it is a world of pain if you actually do it by hand, but with code generation you can easily avoid is. The problem with Java and code generation, there are no partial classes. You have to create a Java file with the entire class specified. In C# there is a partial keyword, which let's one tell the compiler that this class is only partially defined making it very easy to incorporate generated code. Still, code generation would make maintaining the Set/Get(Function) madness easiest for Java.

C# 4.0 (the newest version) supports now the dynamic keyword, which makes C# just as powerful as ruby's method missing is. But I want to target the 2.0 platform which doesn't support it, because it's the most common platform. I even avoided the Reflection namespace, which let's you do a lot of dynamic ruby'ish stuff.

I have already done a lot of code generation with ruby and erb, so my question is, what do you think of this approach, Sebastian? I could create a new branch showing off my idea ...

koraktor commented 13 years ago

Sounds like a great idea. I already thought about something like that or at least a convenience wrapper for the XML parsers, so you don't have to write a monster like this:

Integer.parseInt(((Element) this.xmlData.getElementsByTagName("stats").item(0)).getElementsByTagName("someint").item(0).getTextContent());

And use a construct like the following instead:

this.getIntFromXML("stats/someint");

If you want to experiment with code generation (no matter for what implementation), feel free to do so.

txdv commented 13 years ago

That monster is really scary, C# has a nice ruby like features which let's you write extension methods for classes.

I replaced doc.GetElementsByTagName("stats").Item(0) with GetXmlElement("stats") in the C# code, for better redability, and .GetElementsByTagName("stats").Item(0).InnerText with GetInnerText("stats") (dunno if you looked into my code or not), but the leading int.Parse, as I think, aids better redability, since it makes very clear that the type of this is an Integer, especially if you format the text like i do: http://github.com/txdv/steam-condenser/blob/csharp/csharp/SteamCondenser/Steam/Community/GameStats/Left4Dead.cs#L43

koraktor commented 12 years ago

I decided to close this for now. I don't think real code generation will help much. The time needed to get this done will probably not pay off. The parts that really repeat often are already generalized in various base classes. And more special things can't be really automatized.

I think streamlining XML access (like done in XMLData) is the way to go here.