A lot of modern languages supports optional parameters, or parameters with default values. I've read in this article that .net actually supports them, but for some inane reasons, the C# designers did not build support for it. The article mention something about optional arguments being just syntactic sugar that can be emulated using overloaded methods. This might be true, but the code you have to write to do this workaround is usually too much, and quite frankly just silly.
Consider constructors. It's true you can write overloaded constructors anyway, but what if I have to do some initialization that's quite involved? What I usually do in these cases is that I create a private CommonInit() method to handle the involved initializations, and the constructors call to it as it's first, and usually only, line of code. Here's an, admittedly, contrived example:
class Contrived
{
public Contrived(int maxLines)
{ _maxLines = maxLines; }
public Contrived()
{ _maxLines = 5; }
private int _maxLines;
}
In the example above, using the parameterless constructor actually provides a default value of 5. Imagine if prior to assigning to _maxLines, we have to do more stuff, whatever they are. Where do you put this code? This is usually what I do:
class Contrived
{
private void CommonInit(int maxLines)
{
// involved code here
_maxLines = maxLines;
}
public Contrived(int maxLines)
{ CommonInit(maxLines); }
public Contrived()
{ CommonInit(5); }
private int _maxLines;
}
Looks ok, but imagine if default values are supported: we won't have to go through all this hoops just to support multiple ways of constructing the object from this class. Had optional arguments been supported, things would be this clean:
class Contrived
{
public Contrived(int maxLines = 5)
{
// involved code here
_maxLines = maxLines;
}
private int _maxLines;
}
See how short and concise it is now? Here's hoping that later versions of C# will support this type of declarations. Having to do all those CommonInits for all my classes that I want to be constructed in various ways consumes more time that I'm willing to waste working around 'syntactic sugars', or lack of it.
Saturday, December 30, 2006
Tuesday, December 5, 2006
A Page On Properties
Whew! Was it two weeks since my last post? Time sure flies fast when you're busy doing interesting things... As for my schedule change, it got a bit chaotic due to unforeseen natural events (typhoons and family events). However, I can say that it's now successful. I did, however, toned down playing basketball from everyday to 4-5 times a week. I find that I can't quite sustain the physical abuse seven mornings a week -- not if I want to spend some time with my wife and son.
I've been re-building my personal code libraries for the past two months, and have been doing well for the most part. Because of this, building some common libraries for work wasn't that much harder. I mostly just break them down to reuseable classes so I don't have to write the same thing more than once -- ok, twice. But along the way, I encountered this weird property thing. In Delphi and C++, it's powerful and straightforward. Turned out it wasn't so simple and/or elegant in C# and VB.
In VB, it kinds looks ugly to use the () pair to index stuff, as opposed to the [] pair I got used to, but I can adapt to a lot of style. What surprised my was that in C#, which I thought was a pretty good language to begin with, does not have an indexed property! Wow! I wasn't quite prepared for that one. I know, I know, you can create a class indexer as this[], but it's not the same thing. What I really wanted was something like this.sublist[] - and, well, it's not built-in. I did find a way around it however, thanks to a bit of google`ing.
For anyone interested at all, what you do is just create some sort of class whose main purpose is to do the indexing. This indexer class gets instantiated inside the host class and will be returned as a regular property. Hmmm, wasn't quite as clear as I wanted to say, so let's have an example.
In my case, I was doing a class to act as a section of an *.ini file (yeah, quaint compared to xml, but it's simpler) and I wanted to be able to do the following at a minimum:
In order to support the likes of s.keys[] stuff, I created extra classes to be indexers. Here's how I did it:
The host object simply declares an instance of this one and returns it whenever the property Keys is accessed. From the host class, this is how it's utilized:
With this done, you can do things like s.Keys[index] to get the key at index! It's a lot more code that I would have like, but it's what it took to make the client code much more readable. Just like most everyone else I read about, I have no idea why C# do not have indexed properties. It sounds like a major oversight not to have one considering that array-like properties are not that rare.
I've been re-building my personal code libraries for the past two months, and have been doing well for the most part. Because of this, building some common libraries for work wasn't that much harder. I mostly just break them down to reuseable classes so I don't have to write the same thing more than once -- ok, twice. But along the way, I encountered this weird property thing. In Delphi and C++, it's powerful and straightforward. Turned out it wasn't so simple and/or elegant in C# and VB.
In VB, it kinds looks ugly to use the () pair to index stuff, as opposed to the [] pair I got used to, but I can adapt to a lot of style. What surprised my was that in C#, which I thought was a pretty good language to begin with, does not have an indexed property! Wow! I wasn't quite prepared for that one. I know, I know, you can create a class indexer as this[], but it's not the same thing. What I really wanted was something like this.sublist[] - and, well, it's not built-in. I did find a way around it however, thanks to a bit of google`ing.
For anyone interested at all, what you do is just create some sort of class whose main purpose is to do the indexing. This indexer class gets instantiated inside the host class and will be returned as a regular property. Hmmm, wasn't quite as clear as I wanted to say, so let's have an example.
In my case, I was doing a class to act as a section of an *.ini file (yeah, quaint compared to xml, but it's simpler) and I wanted to be able to do the following at a minimum:
section s = new section(sectionName)
s[keyName] -> returns key=value pair where key=keyName
s[index as int] -> returns key=value pair at position index
s.keys[index as int] -> returns the key at position index
s.values[keyName] -> returns value for keyName
s.values[index as int] -> returns value at position index
In order to support the likes of s.keys[] stuff, I created extra classes to be indexers. Here's how I did it:
public class KeyIndexer
{
public KeyIndexer(section owner)
{
_owner = owner;
}
public string this[int index]
{
// KeyAt() is a function declared in section
get { return _owner.KeyAt(index); }
}
private section _owner;
}
The host object simply declares an instance of this one and returns it whenever the property Keys is accessed. From the host class, this is how it's utilized:
public class section
{
public section(...)
{
...
_ki = new KeyIndexer(this)
...
}
...
public string KeyAt(int index)
{
... code to find and return key value at index ...
}
...
public property Keys as KeyIndexer
{ get { return _ki; } }
...
private KeyIndexer _ki;
}
With this done, you can do things like s.Keys[index] to get the key at index! It's a lot more code that I would have like, but it's what it took to make the client code much more readable. Just like most everyone else I read about, I have no idea why C# do not have indexed properties. It sounds like a major oversight not to have one considering that array-like properties are not that rare.
Monday, November 20, 2006
Almost Normal
The schedule change is going very well. I'm now getting up a little before six in the morning. My first activity is a one-hour exercise, sort of. I'm actually playing basketball every first hour of my day. I figured that doing routine exercise will bore me to death and I won't be able to sustain the activity. Basketball at least is something I enjoy doing. I've played more basketball the last six days as compared to the last six months! What can I say? Programming is too chair-bound a career.
In other areas, I finally got a working arkanoid clone. It only has one level, but it is easy to modify since the layout is just a text file listing positions where bricks ought to be. However, it is enough to validate that the engine port is doing good. The next module up for porting is the windowing system. Or maybe I should do the sound modules first? I'm not sure yet.
In other areas, I finally got a working arkanoid clone. It only has one level, but it is easy to modify since the layout is just a text file listing positions where bricks ought to be. However, it is enough to validate that the engine port is doing good. The next module up for porting is the windowing system. Or maybe I should do the sound modules first? I'm not sure yet.
Friday, November 17, 2006
Wrapping the Windows message loop
Back when my engine was created in Delphi, I created the Application class. It's job is to wrap the Windows message loop such that I won't have to worry about it elsewhere. It's basically a thin wrapper though, which is useful if you want to work at a lower level. The problem with that version is you have to sub-class it to actually use it. It wasn't much trouble then since I'm the only one using it.
Now in C++, I have redesigned it to make use of patterns. It's still a thin-wrapper. However, instead of the dispatching being embedded and useable only by sub-classing, it now uses an observer model. There is another class whose job is to manage a list of multiple observers. This made the Application class design cleaner. It also has better support for multiple target when dispatching just by registering multiple observers.
Part of the design is to insulate the code using it from caring how the application window changes state (minimized, selected, etc). To facilitate this, an enum was created which is what gets passed around during observer-registration and event-dispatching. The windows messages are still available for interception -- though the observers must explicitly be registered to expect it.
If anyone at all is interested, I may post the code. I probably have to clean it up some since it has dependencies I may not necessarily want to post. My library/engine is mostly unicode configured using UTF32 characters so it may not mesh instantly with anybody else's code.
Now in C++, I have redesigned it to make use of patterns. It's still a thin-wrapper. However, instead of the dispatching being embedded and useable only by sub-classing, it now uses an observer model. There is another class whose job is to manage a list of multiple observers. This made the Application class design cleaner. It also has better support for multiple target when dispatching just by registering multiple observers.
Part of the design is to insulate the code using it from caring how the application window changes state (minimized, selected, etc). To facilitate this, an enum was created which is what gets passed around during observer-registration and event-dispatching. The windows messages are still available for interception -- though the observers must explicitly be registered to expect it.
If anyone at all is interested, I may post the code. I probably have to clean it up some since it has dependencies I may not necessarily want to post. My library/engine is mostly unicode configured using UTF32 characters so it may not mesh instantly with anybody else's code.
What to post, what to post....
Hmmm, there doesn't seem to be enough time in a day to do all my stuff and still post about it. But I did promise this blog to be used so I will. I will.
I've been busy recoding my old isometric engine to C++ -- it was originally written in Delphi. Some of the code have to be rethought, some practically unchanged, and still others just get discarded (those delphi classes I wrote to support containers seemed to have gotten the worst of the shafting). I'm already at the stage where the port is useable. I have written the beginnings of an arkanoid clone, and it's running. And as this library/engine is quite a big project, I'll just discuss them in chunks in upcoming posts. Maybe start with how I wrapped the Windows application message loop?
I've been busy recoding my old isometric engine to C++ -- it was originally written in Delphi. Some of the code have to be rethought, some practically unchanged, and still others just get discarded (those delphi classes I wrote to support containers seemed to have gotten the worst of the shafting). I'm already at the stage where the port is useable. I have written the beginnings of an arkanoid clone, and it's running. And as this library/engine is quite a big project, I'll just discuss them in chunks in upcoming posts. Maybe start with how I wrapped the Windows application message loop?
Wednesday, November 15, 2006
Scheduling
Before I go on and post about code, I decided to fix my schedule. I'm normally a late-day person -- I've done my best work during late afternoons, or just before going to bed (3am or so). But then I recently re-examined this assumption and I believe I just trained myself to do it this way. Way back in secondary school, I usually wake up at 5am no matter what time I sleep. I trained myself to wake up that early because I have lots of school activities to attend to, and the extra time I get were invaluable. So now I'm training myself to wake up around 530am. I'm sure I can put the extra time to better use this time.
On top of that, I'm also inserting a daily 1-hour exercise activity to get and keep me physically fit. Being a programmer, physical exertion is something of a foreign concept. And this is slowly weakening me physically. This wasn't a big deal a few years earlier since I still have some youth in me. These days, it doesn't help enough. I need to be pro-active in maintaining my health. I still haven't decided on whether or not I should trade in my soda for water though... :)
On top of that, I'm also inserting a daily 1-hour exercise activity to get and keep me physically fit. Being a programmer, physical exertion is something of a foreign concept. And this is slowly weakening me physically. This wasn't a big deal a few years earlier since I still have some youth in me. These days, it doesn't help enough. I need to be pro-active in maintaining my health. I still haven't decided on whether or not I should trade in my soda for water though... :)
Tuesday, November 14, 2006
Initial Post
I've read lots of blogs the past two months or so. Some for information, some for entertainment, and still others for general enlightment. But what actually influenced me to start my own is a blog by an aspiring game developer chronicling his development activities. I found that I'm picking up new things to add to my knowledge store, and I'm also picking up links here and there to gobble up even more information.
So today I'm starting this blog in the hope that I can contribute to the cyber knowledge-store. Failing that, I would hope I can help myself streamline my own thought processes and be a more efficient developer.
I will probably discuss various topics that interest me, but I'm gearing towards journaling my game development adventures. I program those on the side way back when I was programming business applications and/or tools. And even though a game dev shop hired me, I just can't get enough of it. Part of this is because I have a game I want to create, but I still lack the tools and codebase to make it happen. I'm hoping that putting my ideas into words could kickstart me into actually coding them.
So today I'm starting this blog in the hope that I can contribute to the cyber knowledge-store. Failing that, I would hope I can help myself streamline my own thought processes and be a more efficient developer.
I will probably discuss various topics that interest me, but I'm gearing towards journaling my game development adventures. I program those on the side way back when I was programming business applications and/or tools. And even though a game dev shop hired me, I just can't get enough of it. Part of this is because I have a game I want to create, but I still lack the tools and codebase to make it happen. I'm hoping that putting my ideas into words could kickstart me into actually coding them.
Subscribe to:
Posts (Atom)