Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Scrapping and learning  (Read 5403 times)

0 Members and 1 Guest are viewing this topic.

Wulframm

  • Newbie
  • *
  • Posts: 5
    • View Profile
Scrapping and learning
« on: June 29, 2014, 07:13:53 am »
Hey there,
       
         I've been developing a project of a simple character creator for a while now and have decided to start using it with SFML. Before i do so i feel i need to completely rewrite it as it is full of ungodly amount of mess and i want to start developing good coding habits. Currently the code is a mess (i think im even included some include files that im not even using) and i thought it might be a good idea to put the code here and see what advice people can offer about good habits, what i did wrong, what i did right, how i could use SFML to do this, and anything else you feel like commenting about. Alternately you can just keep going about the forum.

I imagine i did a lot of weird/wrong things but it works. Thing is im not content that it works; I want it to be clean and easy to understand as well as avoiding malpractices. Anything you can offer commentwise is appreciated. Hopefully SFML will be able to help a lot too. =3

P.S. the only way i could find to avoid a massive wall of code was to encase it in a spoiler. I've seen other people use this scroll thing to avoid that but i don't know how to do that. If someone could tell me that be awesome. sorry about the wall of code :P

(click to show/hide)

Peteck

  • Jr. Member
  • **
  • Posts: 55
    • View Profile
Re: Scrapping and learning
« Reply #1 on: June 29, 2014, 01:31:13 pm »
Well. You could start by using the window module :)

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Scrapping and learning
« Reply #2 on: June 29, 2014, 02:28:12 pm »
I agree with Peteck - if you use SFML's Window module, you won't need almost all of this code.
You should break down parts of the code into functions too so that you can more easily see what is happening, rather than having to follow each line of code and its comments.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Wulframm

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Scrapping and learning
« Reply #3 on: June 29, 2014, 07:55:17 pm »
I've been thinking about doing that since it does clean it up quite a bit and make things simpler. however doesn't the original windows library give you more control?

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: Scrapping and learning
« Reply #4 on: June 29, 2014, 07:59:44 pm »
Yes, most platform-specific libraries will give you more control than cross-platform abstractions, but do you plan on doing anything which requires that extra control?  Even if you do, there's a good chance you'd be better off using SFML for the standard stuff and then calling getSystemHandle() when you really need to do something special.

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Scrapping and learning
« Reply #5 on: June 29, 2014, 08:25:10 pm »
I've been thinking about doing that since it does clean it up quite a bit and make things simpler. however doesn't the original windows library give you more control?
The best way to have complete control is to not use any libraries at all.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: Scrapping and learning
« Reply #6 on: June 29, 2014, 11:00:39 pm »
... i thought it might be a good idea to put the code here and see what advice people can offer about good habits, what i did wrong, what i did right, how i could use SFML to do this, and anything else you feel like commenting about.  ...
<

Ok. Some random comments below - some trivial, some more substantial, I just wrote down everything that sprung into my mind as I looked through your code :)

#if defined(UNICODE) && !defined(_UNICODE)
    #define _UNICODE
#elif defined(_UNICODE) && !defined(UNICODE)
    #define UNICODE
#endif
 
You could simplify this a bit to just test if either one is defined and if so, define both.
#if defined(UNICODE) || defined(_UNICODE)
  #define UNICODE
  #define _UNICODE
#endif
 

Ohh and you have an awful lot of consecutive blank lines near the top and elsewhere, one or two should do, don't you think? ;)
Actually I get the impression that you are mostly formatting the code by hand rather than using a tool to enforce a specific style/layout - consider looking into clang-format.

// Define variables that hold the ID of the windows and buttons we will hide and show

// Button IDs
#define ms_but 1
#define in_but 2
#define dx_but 3
#define ps_but 4
#define ch_but 5
#define cn_but 6
#define TextBut 29
//Attribute window IDs
#define ms 7
...
 
Why macros? why not "static const int", "constexpr" or similar? Macros are evil - even if they are just used for constants.

/******************************GLOBAL VARIABLES***********************************************************************************/
int ms_num = 0;
int in_num = 0;
int dx_num = 0;
int ps_num = 0;
int ch_num = 0;
int cn_num = 0;
// Create storage for the dice (for use in a later update)
int die1;
int die2;
int die3;
int die4;
clock_t clkms=clock();

//strings for textboxes
std::string AnimText;




/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/*  Make the class name into a global variable  */
char szClassName[ ] = "WindowsApp";
 
The comment says it all. Global variables - yuck. Don't do that.
A properly designed application almost never has any need for global variables and even when there's a legitimate reason (rare) their use should be minimized. Global variables bring you all sorts of headaches; like:

- It's hard to keep track of where they are read/written since they are not encapsulated.
- Different objects each using the same global variable become very tightly coupled (and you should try to minimize coupling between your classes).
- Global variables in different translation units have undefined order of initialization, so you can't count on one being initialized before another.
- Global variables are constructed before entering main() and destroyed after leaving it which means that they operate in a world where certain things that you assume about your runtime environment may not be true.
- Since they are visible to your entire project, changing one of them potentially requires recompilation of a lot of files.
And more. Just say no.  Friends don't let friends use global variables ;)

(and yes, Singletons are global variables - don't use them).

//converts integers
std::string String ( double Val ) {
        std::ostringstream Stream;
        Stream << Val;
        return Stream.str ( );
}
 
Why not just use std::to_string?

int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nFunsterStil)
 
Any specific reason you want to tie your code to windows by using WinMain over the standard "main()"?
Look into the "sfml-main" lib to keep main as an entry point while at the same time compiling a Windows (rather than Console) application.

...
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */

    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default color as the background of the window */
    wincl.hbrBackground = GetSysColorBrush(COLOR_3DFACE);

    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;



    /* The class is registered, let's create the program*/

    hwnd = CreateWindowEx (
...
 
This and all the rest of the Windows specific Window related code just goes away when you use sfml-window (as others have also pointed out - and as a bonus it becomes cross-platform.

And for all your GUI needs, look into these: https://github.com/SFML/SFML/wiki/FAQ#libraries-gui-package

                     srand(clock()-clkms);// seed the rand function with time NOTE: will only change result every second
                     roll= 3+(rand()%16);// creat a random number between 1-18 NOTE: rand will always count upwards until the limit is reached and then start low again. too predictable
 
Superiour alternatives to srand/rand can be found in the "<random>" header.

    return 0;
 
Being extremely pedantic here, but returning EXIT_SUCCESS is ever so slightly more portable ;)

Another comment, that others have also made; you really need to use some classes and functions to encapsulate functionality and make the code more readable.
I also feel like pointing you at this article about RAII by Nexus.

Wulframm

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Scrapping and learning
« Reply #7 on: June 30, 2014, 02:51:12 am »


Ok. Some random comments below - some trivial, some more substantial, I just wrote down everything that sprung into my mind as I looked through your code :)




I swear this is the single most helpful thing I've read in a very long time. thanks a lot! the project started out with some default code which is why winmain() and some other windows specific code is used. At the time programming with a window was very new to me and it seemed like a good idea to use it to figure out the typical structure and values that are needed to deal with this sort of thing. I'll work on replacing code with sfml to make it cross-platform. Thanks also for the article! it's looking to be a fun read.  I'll also work on getting rid of the globals as i wasn't thinking about how they could affect the program, but now that i think about it that makes complete sense. I ended up using #define as a way of defining a constant without using stack space... i think... But if there is a better way than yeah I'm up for it.
« Last Edit: June 30, 2014, 06:16:48 pm by Wulframm »

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Scrapping and learning
« Reply #8 on: June 30, 2014, 08:03:44 am »
Please avoid full quotes -- especially if the post is overly long, and even more if it's just above.

And read Jesper Juhl's post once again, it contains much more useful information than just #define ;)
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

 

anything