Thread: Completely seperating parts of code

  1. #1
    Registered User
    Join Date
    Mar 2002
    Posts
    125

    Completely seperating parts of code

    I have a bit of a problem. I have a piece of code of a game seperated into two classes, one that handles textures and one that handles a game level (seperated into Texturehandler.cpp, Texturehandler.h and Gamelevel.cpp and Gamelevel.h) and the gamelevel handler needs to use some of the public functions of the texturehandler. The problem is the class prototype of the texturehandler uses some OpenGL specific types and a struct that also uses these types. Texturehandler.h contains:
    Code:
    #ifndef _TEXHANDLER_H_
    #define _TEXHANDLER_H_
    
    enum E_texture_type 
    {
        TEXTYPE_player, 
        TEXTYPE_hud, 
        TEXTYPE_level,
        TEXTYPE_monster,
        TEXTYPE_misc,
    };
    
    struct S_texture_entry
    {
    	GLuint texture_id;
    	E_texture_type texture_type;
    	int texture_inuse;
    	char texture_name[80];
    };
    
    class TextureHandler
    {
    	public:
    		TextureHandler();
    		~TextureHandler();
    		unsigned int GetTexture(const char* tex_file_name, E_texture_type tex_type = TEXTYPE_misc);
    		void UseTexture(unsigned int entry_id);
    		void MarkTypeAsUnused(E_texture_type unused_type);
    		void ClearUnusedTextures();
    	private:
    		unsigned int default_texture;
    		S_texture_entry *entries;
    		int entries_currentsize;
    		GLuint LoadTGA(const char* tex_file_name);
    		int CheckSize(int size);
    };
    
    #endif // ifndef _TEXHANDLER_H_
    and Gamelevel.cpp contrains:
    Code:
    #include "game_level.h"
    #include "texhandler.h"
    (well, it contains a lot more of course, but that is the important part)

    This refuses to compile because Texhandler.h contains variables and functions of type GLuint, something that isn't defined in Gamelevel.cpp. I could fix this by including the OpenGL headers in Gamelevel.cpp, but obviously it doesn't make much sense that a game level class needs to know what sort of types the texturehandler class uses internally (the public interface of the texturehandler doesn't require any OGL specific stuff after all, and making the whole OGL interface invisible to parts of a program that don't need it is one of the good things about seperating code; it would make things tough on me as well if I later decide to add support for different renderers)
    Would it be possible to make a seperate H file that contains only the interface of the class (an incomplete class prototype) and include that in the Gamelevel.CPP, and then include the complete class definition in Texturehandler.CPP?
    Thanks in advance.

    (my apologies if this had been asked before; I tried a few searches but didn't know what search terms to look for and the FAQ also didn't say anything about this; I also apologise for the long story, I couldn't really compress it any further )
    Typing stuff in Code::Blocks 8.02, compiling stuff with MinGW 3.4.5.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Well it's one of the problems of C++ which forces you to list all your privates in the interface.

    You can hide them all, at the expense of an extra level of indirection.
    Code:
    #ifndef _TEXHANDLER_H_
    #define _TEXHANDLER_H_
    
    enum E_texture_type
    {
        TEXTYPE_player,
        TEXTYPE_hud,
        TEXTYPE_level,
        TEXTYPE_monster,
        TEXTYPE_misc,
    };
    
    struct S_texthander_private;
    
    class TextureHandler
    {
        public:
            TextureHandler();
            ~TextureHandler();
            unsigned int GetTexture(const char* tex_file_name, E_texture_type tex_type = TEXTYPE_misc);
            void UseTexture(unsigned int entry_id);
            void MarkTypeAsUnused(E_texture_type unused_type);
            void ClearUnusedTextures();
        private:
            S_texthander_private  *privates;
    };
    
    #endif // ifndef _TEXHANDLER_H_
    
    #ifndef _TEXHANDLER_PRIVATE_H_
    #define _TEXHANDLER_PRIVATE_H_
    struct S_texture_entry
    {
        GLuint texture_id;
        E_texture_type texture_type;
        int texture_inuse;
        char texture_name[80];
    };
    struct S_texthander_private
    {
        unsigned int default_texture;
        S_texture_entry *entries;
        int entries_currentsize;
        GLuint LoadTGA(const char* tex_file_name);
        int CheckSize(int size);
    };
    #endif // _TEXHANDLER_PRIVATE_H_
    Texturehandler.cpp would begin
    #include "Texturehandler.h"
    #include "Texturehandler_private.h"
    Along with any GL headers it needs.

    Anything just using the class only needs Texturehandler.h and no GL header files.


    An alternative is to include all your GL header files in Texturehandler.h, like so
    Code:
    #ifndef _TEXHANDLER_H_
    #define _TEXHANDLER_H_
    #include <gl.h>
    // rest of class.
    This has it's downside as well, since any code which uses this class automatically gets all the GL interface in it's namespace as well, which is perhaps not what you want either.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Nov 2002
    Posts
    491
    You can include headers in other headers, it's perfect valud.

    Fix your inclusion guard name though. _TEXHANDLER_H_ steps on the the reserved identifier naemspace. _[A-Z] is reserved.

  4. #4
    Registered User
    Join Date
    Mar 2002
    Posts
    125
    Putting the private part in a seperate struct or class seems like a reasonably clean solution, I'll go with that. Thanks a lot.

    orbitz: I'd rather not include very large header files in other header files, for the reason Salem mentioned ('sides it would probably end up with me indirectly including all headers in all source files ). I'll fix that inclusion guard tho', thanks for pointing that one out.
    Typing stuff in Code::Blocks 8.02, compiling stuff with MinGW 3.4.5.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C source code to split any given file into many parts
    By m.sudhakar in forum C Programming
    Replies: 2
    Last Post: 08-15-2006, 03:43 AM
  2. Replies: 30
    Last Post: 06-19-2006, 12:35 AM
  3. Updated sound engine code
    By VirtualAce in forum Game Programming
    Replies: 8
    Last Post: 11-18-2004, 12:38 PM
  4. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM
  5. Interface Question
    By smog890 in forum C Programming
    Replies: 11
    Last Post: 06-03-2002, 05:06 PM