Latest: adam_28apr2007.plan
Well. what follows is the meanderings of thoughts I have had during the past 2 weeks.
If ur not terribly interested in Black Engine / Software Engineering you’ll probably want to pass this one by. But I think for those of us that are new to trying to learn as we create, this should be of some interest.
So I began by tracking down a very intricate heap corruption bug involving a string of virtual destructors which after learning many many new techniques for debugging memory corruption I tracked it down to several places in my more basic code. Code that I had tested to my satisfaction. This was a big slap in the face. Some of the mistakes were minor and forgivable in my mind because of the huge time crunch it was all developed under. But some were more integral.
I found several rather severe faults. Some where in design, some were in general ideology.
Let me go into them.
The first, the Element class in my mind should handle and subsequently hide all of the interactions with the Element Manager Service. Essentially wrap all the functionality and provide higher level, task oriented access to the Service’s functionality. This all seemed logical to me. So in the constructor (all constructors are virtual) the Element class handles registration with the EMS. Now, if the EMS rejects the registration, which can happen if the Element Id is not unique for example, the instance of that element is not valid and should be deleted. Well, this constructor is being called from a much higher level virtual constructor. So neither the EMS register() function now the Element constructor it’s self can handle deleting the memory b/c at that point during the construction it only knows that it is an Element, there for the Element memory would be deleted, nothing else, and the rest of the constructors would proceed as normal. Even if you don’t delete it right then, you then have the issue of communicating back to the calling code the fact that it failed. Also the calling code must then have to take care of cleaning it up conditionally which I didn’t like.
Now I thought up several solutions but when pitching them to other programmers got the sense they were very uneasy about the whole thing as was I. It just indicated there was a deeper design flaw. Their general response was, it should be a 2 stage initialization. Construction, then initialization. This is probably something close to what I will be going with.
Another thing. I didn’t use exception any where in the design. I have used exception and understand them just fine. But I had never used them in C++, with the time constraints I had at the time and the amount of things I had to learn any way I decided to not tack on another unknown. That was a mistake. Exceptions would provide a very clean solution to the previous issue as well as many others. So some point soon I plan on developing the exception scheme and implementing it.
The last big thing is. I tracked the majority of my memory corruption bugs back to my hash table. Which. Christ. I should be able to code a freaking hash table. That was the big slap in the face. For many reasons though besides just the memory bugs, I decided to switch to STL::map which is a simple unique hash map. While doing so I learned a lot about 2 things which I had known existed but hadn’t spent time to get to know well. Iterator and References. The sad fact is, I was taught C and C++ together so until recently had a confused idea of what belonged to which language. If you don’t know already, while they can be used together, they shouldn’t be, and there is a clear separation between the two.
In C++, looping through arrays should when EVER possible be done with Iterators. And heap allocated objects should almost ALWAYS be passed by reference (which does NOT mean passing a pointer!), for speed, safety, everything. Use References!
So I plan at some point removing as many as possible (the VAST majority) of raw pointers and replacing them with references.
That being said, this is the view of my code through the most critical spot light possible. My own. I believe that when these things mentioned are refactored, the code base will be rock solid and modern well coded C++.
So takes a breath…
Any way, I started writing the 2nd tutorial which goes in depth about the Extension project which is the actually game and graphics engine portion of the whole framework. I’ll probably finish that tomorrow as well as hammer away at some more of the bugs and maybe a few of these refactoring tasks.
Well, if your still reading then you’re a freaking trooper lol.
That’s it for me.
- Adam
If ur not terribly interested in Black Engine / Software Engineering you’ll probably want to pass this one by. But I think for those of us that are new to trying to learn as we create, this should be of some interest.
So I began by tracking down a very intricate heap corruption bug involving a string of virtual destructors which after learning many many new techniques for debugging memory corruption I tracked it down to several places in my more basic code. Code that I had tested to my satisfaction. This was a big slap in the face. Some of the mistakes were minor and forgivable in my mind because of the huge time crunch it was all developed under. But some were more integral.
I found several rather severe faults. Some where in design, some were in general ideology.
Let me go into them.
The first, the Element class in my mind should handle and subsequently hide all of the interactions with the Element Manager Service. Essentially wrap all the functionality and provide higher level, task oriented access to the Service’s functionality. This all seemed logical to me. So in the constructor (all constructors are virtual) the Element class handles registration with the EMS. Now, if the EMS rejects the registration, which can happen if the Element Id is not unique for example, the instance of that element is not valid and should be deleted. Well, this constructor is being called from a much higher level virtual constructor. So neither the EMS register() function now the Element constructor it’s self can handle deleting the memory b/c at that point during the construction it only knows that it is an Element, there for the Element memory would be deleted, nothing else, and the rest of the constructors would proceed as normal. Even if you don’t delete it right then, you then have the issue of communicating back to the calling code the fact that it failed. Also the calling code must then have to take care of cleaning it up conditionally which I didn’t like.
Now I thought up several solutions but when pitching them to other programmers got the sense they were very uneasy about the whole thing as was I. It just indicated there was a deeper design flaw. Their general response was, it should be a 2 stage initialization. Construction, then initialization. This is probably something close to what I will be going with.
Another thing. I didn’t use exception any where in the design. I have used exception and understand them just fine. But I had never used them in C++, with the time constraints I had at the time and the amount of things I had to learn any way I decided to not tack on another unknown. That was a mistake. Exceptions would provide a very clean solution to the previous issue as well as many others. So some point soon I plan on developing the exception scheme and implementing it.
The last big thing is. I tracked the majority of my memory corruption bugs back to my hash table. Which. Christ. I should be able to code a freaking hash table. That was the big slap in the face. For many reasons though besides just the memory bugs, I decided to switch to STL::map which is a simple unique hash map. While doing so I learned a lot about 2 things which I had known existed but hadn’t spent time to get to know well. Iterator and References. The sad fact is, I was taught C and C++ together so until recently had a confused idea of what belonged to which language. If you don’t know already, while they can be used together, they shouldn’t be, and there is a clear separation between the two.
In C++, looping through arrays should when EVER possible be done with Iterators. And heap allocated objects should almost ALWAYS be passed by reference (which does NOT mean passing a pointer!), for speed, safety, everything. Use References!
So I plan at some point removing as many as possible (the VAST majority) of raw pointers and replacing them with references.
That being said, this is the view of my code through the most critical spot light possible. My own. I believe that when these things mentioned are refactored, the code base will be rock solid and modern well coded C++.
So takes a breath…
Any way, I started writing the 2nd tutorial which goes in depth about the Extension project which is the actually game and graphics engine portion of the whole framework. I’ll probably finish that tomorrow as well as hammer away at some more of the bugs and maybe a few of these refactoring tasks.
Well, if your still reading then you’re a freaking trooper lol.
That’s it for me.
- Adam
Post a Comment
.plan Archive
.plan rss
adam_23feb2010.plan
adam_25sep2009.plan
adam_03may2009.plan
adam_07may2008.plan
adam_20nov2007.plan
adam_02nov2007.plan
adam_12oct2007.plan
adam_03oct2007.plan
adam_26sep2007.plan
adam_31jul2007.plan
adam_17jul2007.plan
adam_05jul2007.plan
adam_31may2007.plan
adam_16may2007.plan
adam_01may2007.plan
adam_28apr2007.plan
adam_11apr2007.plan
adam_08apr2007.plan
adam_03apr2007.plan
adam_31mar2007.plan
adam_29mar2007.plan
adam_29mar2007.plan
adam_26mar2007.plan
adam_04mar2007.plan
adam_27feb2007.plan
adam_08feb2007.plan
adam_02feb2007.plan
adam_01feb2007.plan
adam_28jan2007.plan
adam_27jan2007.plan
adam_26jan2007.plan
adam_22jan2007.plan
adam_18jan2007.plan
adam_06jan2007.plan
adam_28dec2006.plan
adam_22dec2006.plan
adam_17dec2006.plan
adam_14dec2006.plan
adam_28nov2006.plan
adam_26nov2006.plan
adam_24nov2006.plan
adam_11nov2006.plan
adam_02nov2006.plan
adam_31oct2006.plan
adam_25oct2006.plan
adam_19oct2006.plan
adam_16oct2006.plan
adam_09oct2006.plan
adam_28sep2006.plan
adam_24sep2006.plan
adam_21sep2006.plan
adam_23feb2010.plan
adam_25sep2009.plan
adam_03may2009.plan
adam_07may2008.plan
adam_20nov2007.plan
adam_02nov2007.plan
adam_12oct2007.plan
adam_03oct2007.plan
adam_26sep2007.plan
adam_31jul2007.plan
adam_17jul2007.plan
adam_05jul2007.plan
adam_31may2007.plan
adam_16may2007.plan
adam_01may2007.plan
adam_28apr2007.plan
adam_11apr2007.plan
adam_08apr2007.plan
adam_03apr2007.plan
adam_31mar2007.plan
adam_29mar2007.plan
adam_29mar2007.plan
adam_26mar2007.plan
adam_04mar2007.plan
adam_27feb2007.plan
adam_08feb2007.plan
adam_02feb2007.plan
adam_01feb2007.plan
adam_28jan2007.plan
adam_27jan2007.plan
adam_26jan2007.plan
adam_22jan2007.plan
adam_18jan2007.plan
adam_06jan2007.plan
adam_28dec2006.plan
adam_22dec2006.plan
adam_17dec2006.plan
adam_14dec2006.plan
adam_28nov2006.plan
adam_26nov2006.plan
adam_24nov2006.plan
adam_11nov2006.plan
adam_02nov2006.plan
adam_31oct2006.plan
adam_25oct2006.plan
adam_19oct2006.plan
adam_16oct2006.plan
adam_09oct2006.plan
adam_28sep2006.plan
adam_24sep2006.plan
adam_21sep2006.plan