Author Topic: A closer look to PS development.  (Read 1120 times)

Winterheaven

  • Traveller
  • *
  • Posts: 20
    • View Profile
A closer look to PS development.
« on: May 02, 2004, 08:57:10 pm »
After spending half of the night in the CVS of PS and in writing this article, I decided to publish this post as an extra thread. It has not much to do with the leaving of kronon... and it should better reside in the development forum.

Quote

Originally posted by Vengeance

While I think there are some areas better than others in our code, most of the comments in here have not been about those sections, but instead have been very general comments about the complexity of CS.  Yes it is complex, but I\'d like to hear from you which parts you think you can take out.



Ok, Vengeance, you want to have concrete hints, where CRITICS see problems... and damned, you are right. It is tedious to talk about common tasks, when they never come to the bottom. I am not willing to leave me in the corner of the critics without analytic expertise. But perhaps I belong exact to that place? Anyway, I want to show, what I mean. (Btw, YOUR comment was as general as the others too ;) ).

I simply walk in the actual CVS in the heart of the client/gui directory. Took there the first from the (alphabetically sorted) files: chatwindow... header and implementation file. Wandered over the first class and stopped at the second one: pawsChatHistory. Now I examined the declaration AND implementation. Following things I want to mentioned:

Global Issues:
  • Comment says: \"Class to store chat history.  Implementation is a circular buffer\". Hm... looking only to the declaration of the class functions and member variables I thought... this code CRYES for a template class. If there is a need for a similar buffer of an other type the programmer has to copy/paste the whole thing (one of the main source of errors in coding).
  • In the function Insert() the copy of the string argument is allocated with csNewStr() - a Crystal Space function. But what, if I only want to code in some parts of the Planeshift code. Is it necessary to now all the details about CS-functionality? So every coder willing to help planeshift is liable to get also close to Crystal Space. Wouldn\'t it be better to HIDE the engine code?
  • What does csNewStr? Does it allocate with new or with one of the alloc functions? The resulting buffer is freed with delete. So probably csNewStr follows its name and calls new. But why then is the buffer for the string pointers allocated with calloc? Is mixing the allocation function a standard procedure in planeshift. Are there existing rules? Where is this DOCUMENTED? And how the allocation functions are traced? Does CS this? Is the global ::new allocator overloaded? Where is it DOCUMENTED? How do you check for memory leaks?
  • How do you profile the code? I do not see any function traces? Do you get the compiler generating profiling code? Do you take professional programs like Numega TrueCoverage or TrueTime? Where is this DOCUMENTED?
  • Why do you decide to use in this class a buffer of pointers and not directly store the strings in the buffer? Fast access to the strings? Or was the reason an easier handling? I do not know. But if I want to learn from your code, I have to extract all your consideration, all your transpiration for myself... and all your preliminary work is for nothing. That is one of the biggest difficulties with Open Source projects. You get soooo much code around your ears... but only very few information, ow the decisions are done. How the organisation runs. How the communication in an international team works. Where are the log files of the IRC-Sessions, where you discussed this? Or even a summarization of this? Does every coder are only responsible for his task? Are there only one boss, which gives out the programming problem?
  • It takes me 15 minutes to understand, that this class does NOT manage the history of the chat window... IT IS THE HISTORY OF THE EDIT FIELD WINDOW. There is really a lack of DOCUMENTATION, if I have to work out this from the code!
  • Why do you use char and not TCHAR or any other unicode-compatibility? Does localization not play a role in PS?
  • Why do you decide not to use the hungarian notation? I find it difficult to distinguish between local and class variables, if there is no naming differences. And more difficult, if I can not see, if the variable is a pointer, an int, float or a string directly in the name.


After I had problems getting the clue of the variable getLoc I made a short test program. Here I must honour the author, because it was a very easy task to program a small console proggy to test the class! But it results to the conclusion, that this class was never tested!

Local Issues:
  • I get a compile warning in constructor: initsize(argument) is of type size_t and size(member) of type unsigned: could result in a loss of data. You should either do an explicit type cast or declarate of same type or at least comment the line to clarify the decision.
  • Why is the check vor an invalid n(argument) in GetCommand() is done AFTER the calculation of the index?
  • Why is the allocation of the buffer implemented in constructor and also in SetSize. Wouldn\'t it be better to set size to NULL in the constructor and then call SetSize() as THE function for reallocate the buffer?
  • Why differs the type of the argument in constructor and SetSize()... even they mean the same variable?
  • In the function Insert() the string is allocated with csNewStr - probably with \"new char[strlen(str)+1]\". Should not the freeing operation be \"delete []\" than \"delete\"?
  • In SetSize() getLoc is wrong calculated at the end (that IS an error). Can be result in an invalid value. Try this:construct object with initsize=3; add three words; call three times GetPrev; call SetSize(2); If you now call GetNext() you get a wrong (but valid) string. The string is valid because of the next error.
  • The function SetSize() was NEVER tested... The line \"newBuffer = (char **)calloc(size, sizeof(char *));\" shows, that the new buffer is allocated with the size of the old... and not with the argument newSize.


That brings me to the last point: Where are all the little test programs, that verify the correctness of the code? The programs, that take a class or connected collection of classes to show, that they work independent of the rest of the code base. The programs, that create different error cases, which make shure, the implementation is strong and right?

I hope, I could get you a clue about my thoughts and how I learned to develope. I would very, very glad, if people find errors in my statements... \'cause any of those hints helps me to get a better programmer.

Ah, only one additional point (the really last one - promised ;)). I will not accept the answer of the lack of persons and time for the above mentioned things. I know that. I agree with that. I understand it. But for a huge project like this, I think some organisation, testing and thinking SHOULD be done before implemeting only one single line of code.

br, Winterheaven.

p.s. I wrote this post NOT to criticize the work of the planeshift team. I wrote this post, BECAUSE I am willing to help and give my (perhaps little) experiance into planeshift. Vengeance asked for detailed comments... and I wrote them. That is all. If this is helpless... sorry for any inconveniences.
Max and Logan, that is the plan. (joshua)

Fextina

  • Traveller
  • *
  • Posts: 27
    • View Profile
(No subject)
« Reply #1 on: May 02, 2004, 09:31:25 pm »
Good points overall.

Though PS is a multi-platform project, this is why TCHAR is not possible (Is there TCHAR in Linux??).

I read an article recently on the lack of testing methodologies in Linux. The problem also has to do with tools, I\'m not sure if the developers even ran PS under Valgrind to check for memory leaks? And where there has been any attempts on optimization using any tools.

acraig

  • Administrator
  • Veteran
  • *
  • Posts: 1562
    • View Profile
(No subject)
« Reply #2 on: May 02, 2004, 10:21:44 pm »
Quote
Originally posted by Winterheaven

Global Issues:
Comment says: \"Class to store chat history.  Implementation is a circular buffer\". Hm... looking only to the declaration of the class functions and member variables I thought... this code CRYES for a template class. If there is a need for a similar buffer of an other type the programmer has to copy/paste the whole thing (one of the main source of errors in coding).


Fixed.  Class now uses csPDelArray which is a smart template of csString pointers.  When the class goes out of scope it will automatically delete the points.  This also cleans up a lot of the other issues that you mention.



Quote

How do you profile the code? I do not see any function traces? Do you get the compiler generating profiling code? Do you take professional programs like Numega TrueCoverage or TrueTime? Where is this DOCUMENTED?

In Linux I use gprof/kprof/valgrind to do profiling.  But I have not done any lately since I still have a lot of work to do in other areas and just don\'t have the time at this point to do fine tune things.  Maybe this is something that somebody can look at to create some documents here on different profiling techniques.  

Quote

Does every coder are only responsible for his task? Are there only one boss, which gives out the programming problem?


Usually we assign a task/area for a person.  Depending on their skills and time with the team the tasks can be either very small or very large.  Those people are responsible for the maintainance of that area.

Quote

  • It takes me 15 minutes to understand, that this class does NOT manage the history of the chat window... IT IS THE HISTORY OF THE EDIT FIELD WINDOW. There is really a lack of DOCUMENTATION, if I have to work out this from the code!


Doxygen comments have been updated.

Quote

Why do you decide not to use the hungarian notation? I find it difficult to distinguish between local and class variables, if there is no naming differences. And more difficult, if I can not see, if the variable is a pointer, an int, float or a string directly in the name.


I am not a big fan of this type of notation.  I guess it is just personal preference.  I know that most modern day compilers can tell you type and declaration location on mouse over a variable.  I myself use vim most of the time so I don\'t even have this but I don\'t have a big problem with this.  Maybe is just familarity :)

Quote

That brings me to the last point: Where are all the little test programs, that verify the correctness of the code? The programs, that take a class or connected collection of classes to show, that they work independent of the rest of the code base. The programs, that create different error cases, which make shure, the implementation is strong and right?

Well that is the ideal situation.  But when you think about it that is a large task as well.  I agree that this is important to do but would take a lot of time and take us away from the more fun aspects of the game.  


Quote

Ah, only one additional point (the really last one - promised ;)). I will not accept the answer of the lack of persons and time for the above mentioned things. I know that. I agree with that. I understand it. But for a huge project like this, I think some organisation, testing and thinking SHOULD be done before implemeting only one single line of code.


Well, I think we are fairly organized in our thoughts and actions but again you mention a more ideal situation.  In a company or localized team then this is a good plan but for us it doesn\'t work so well.   I think we are more result driven.  If people see our project and all they see are plans then they may think that it is going nowhere and people would loose interest.  However if they see progress ( ie code ) then it spurs them on to think more progress is made.  Again this may lead to more refactoring and code re-writes but I think that this is an occupational hazzard.  Again a lot of the code is written and maintained by a few core developers and we are learning as we go.  Maybe not the best way to develop software but has been working out for us so far :).


Quote

p.s. I wrote this post NOT to criticize the work of the planeshift team. I wrote this post, BECAUSE I am willing to help and give my (perhaps little) experiance into planeshift. Vengeance asked for detailed comments... and I wrote them. That is all. If this is helpless... sorry for any inconveniences.


No problem, the more people that can examine the code and point out errors the better.  The next step is to start providing patches :)
----------
Andrew
"For all I know, she's lying, everyone's lying; welcome to the Internet"

dfryer

  • Veteran
  • *
  • Posts: 1070
    • View Profile
(No subject)
« Reply #3 on: May 03, 2004, 01:42:11 am »
With regards to the separation between Planeshift and CrystalSpace (or lack thereof) I can\'t speak as a dev, but I have a little bit of exposure to both codebases.  CrystalSpace is more than just the rendering engine - it\'s a cross-platform framework for file management, 2D and 3D graphics, sound, event handling.  CEL is built on top of CrystalSpace and is tightly integrated - PS depends on CEL as well.  Since PS depends on CS, it makes little sense for Planeshift to reimplement all this functionality.  CS is the target platform - instead of Win32, MacOS Cocoa, GTK or what have you, CS is *the* system API that Planeshift uses.  I\'ve been wanting to spend some time adding documentation to CS or PS, but so far I haven\'t come at it with the required perseverance.
Quidquid latine dictum sit, altum sonatur.