Sign in to follow this  
Angelic Ice

Wrapping Libraries / Multiple Platforms

Recommended Posts

Hello forum : )

I was wondering if it is common practice to wrap around classes from external libraries in order to interchange such library by another.

And how modern C++ tackle to provide multiple builds for multiple OS.

 

What I do:

I have the same files used by multiple projects, one project per OS.

All I do is linking different OS versions of my one Graphics library. Is this advised? Or are macros more common?

 

Let us take a Graphics library as an example, containing a windows-class and a sprite-class.

Now, our code owns a Graphics component having the sprite-class as a member.

I can simply change the library binaries

 

Would it be better to create a Sprite-wrapper instead? So, my Graphics component can call methods to obtain coordinates without really knowing what kind of object it is working with.

As far as I know, decoupling is generally advised, just curious to know when it is too much.

 

Thanks for reading : )!

Share this post


Link to post
Share on other sites

How I handle Platform Specific code is quite simple. I usually try to ambiguate the types the class relies on using preprocessor directives like #ifdef/#endif. So for instance I could do this

Struct WindowInstance
{
#ifdef WIN32
    HINSTANCE hInstance
#elif
    //another platform API handle, like XWindows
#endif
};

struct WindowHandle
{ 
#ifdef WIN32
    HWND hWnd;
#elif
    //another platform API handle, like XWindows
#endif
};

I then use these types in the appropriate header so for the above example I would use that for a Window Class

class Window
{
public:
    Window(const WindowInstance&);
    ~Window();
public:
     const WindowHandle& getHandle() const;
     //ect...
private:
    WindowInstance& winInstance;
    WindowHandle&   winHandle;
};

This enables me to create platform independent headers, and leave the platform specifics to the implementation file. There are a lot of ways you can approach this problem, you could go the virtual function route, but I find this to be clean, and simple.

 

Marcus Hansen

Share this post


Link to post
Share on other sites

It is common to wrap things if you intend to change them, It's called Abstraction.

In terms of basic design concepts, you should abstract something if you change it a lot.

For example a window handle, for different OSs it is different, but the abstracted beahvior is the same (Open window, Close window, Change title, Change width/height, etc...) 

 

In terms of high level design concepts it's not the best solution. Since it would take much effort to actually implement this abstraction in a nice way. 

It's a good solution if you want a very extendable library (such as support for more operation systems and plugins).

But I fear you gain too little from it- In terms of maintaining the library, upgrading code and developing new features. 

So if you look at it in smaller details, it's worthwile to check if preprocessors are a better way to change behavior than splitting it into different libraries and interfaces.

 

The key is measure twice cut once. 

Because if you decide now to develop for multiple operation systems but at the end only windows users will actually play, then why did you even go cross platform? 

Edited by WoopsASword

Share this post


Link to post
Share on other sites

I was wondering if it is common practice to wrap around classes from external libraries in order to interchange such library by another.

 

Do this work when you know you need to interchange the library, not before. You don't save any time by doing it up front, all you do is change which part of your code you'll need to alter next time. If anything it's worse to do it up front because you don't have enough experience of each alternative yet to be able to create an adequate abstraction for them both.

Share this post


Link to post
Share on other sites
If you want to have multiple target platforms, the first thing you need is an easy way to test your program on every relevant platform. Without that, you may think that your program is multi-platform but you might be fooling yourself.

I like using SFML, which neatly wraps a lot of platform-specific things for you. For anything else, I have a header file called something like "platform-specific.hpp" which contains prototypes of free functions (I typically only need a few), and several corresponding implementation files, one per platform ("windows_platform.cpp", "posix_platform", etc.). I then use only the appropriate implementation file in each makefile or project description.

Share this post


Link to post
Share on other sites

Either use an off-the-shelf library that provides such an abstraction layer (say, something like SDL for window/input management, of bgfx for renderer abstraction), or don't write these abstractions till you need them.

 

It's close to impossible to write such abstraction layers until you actually know the requirements, and you won't know the requirements till you write the game the first time. Writing abstractions first will just stick you in an endless cycle of rewrites as you discover new features you need to abstract over.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this