Platform abstraction in the ZFXCE2

Hervorgehoben

I am using a new concept to support multiple platforms in the ZFC-Community-Engine 2 and I want to explain the ideas behind this a little bit.

Where do I come from?

When I had to support more than one platform the first time I tried two different approaches to do this:

  • Use platform-specific #ifdef directives for every place where a system call from the operation system has to be done. This is an easy to use straid-forward concept which is widely used in many other projects. Unfortunately it brings some serious pitfalls with it: your code is full of dead sections because there are only used for one platform. This makes the code hard to read, hard to test ( special when you have to adapt one feature and you missed all other supported platforms ) and your API calls will be spread all over your code. When you have to support any new platform you have to check each place where an #ifdef is placed.
  • Use a platform-abstraction library like SDL2 and use all the platform-specific stuff offered by this framework. For getting your daily jobs like creating a window this solution works fine. And you don’t have to check all your code for special #ifdef’s. Unfortunately this solution has also some serious pitfalls: when you need a special platform-specific feature this must be supported by your platform-abstraction framework. If it is not supported you have to implement this on your own and put it into #ifdef-blocks. And after time this will cause again a lot of spreaded ifdefs all over the place. And what happens when you have to support another platform which is not part of your platform-abstraction framework?

And one big disadvantage of both concepts: they are really hard to mockup for a test.

What was my next step?

After dealing with these two solutions for quite a while my next step to improve this was building interfaces which will implementing the features for the supported platforms. For instance I build an interface like:

// The interface
class IWindow {};

// The implementation for window
class Win32Window : public IWindow {};

// The implementation for x-server based systems
class XWindow : public IWindow {};

So much better. You have an implementation for each platform, you can build mockup-implementations for your tests. In your make-file you can specify which platform shall been build.

But one issue is still there: you are spreading all the platform-specific implementation all over your code. When you have to port somethink you still have to figure our which interafces your have to implement for the platform.  From this point I did some research how other frameworks are dealing with situations like this. And I found the Qt5-approach.

The Qt Platform Abstraction

Qt is a cross-platform framework for User Interfaces, whcih also offers a wide list of cross-platform features like UI-developments, network-programming and much more. They are using a concept calle QPA ( Qt PLatform Abstraction ). Check this link to learn more about it: http://qt-project.org/videos/watch/qpa-the-qt-platform-abstraction .

In short: it offers you all needed platform abstraction at one place. New platforms can be integrated via a new plugin. The place where to find the plugins for your platform is well defined. If you have to support a special feature it will be done only in this platform-plugin. And you can configure via make which stuff will be build for the several platforms. Each implementations gets its own folder. So when you look for a platform-specific implementation you can look easily at

Code/Infrastructure/Platfom/<Impl-Type>/

What is the main advantage from my point of view:

  • You still have a bundle of interfaces to provide all the platform-specific stuff.
  • There is one place where all these implementation is placed in the code. So it is much easier to maintain it
  • Providing new platforms is easiy: just provide the new implementatiosn.
  • You still can use SDL2 for instance: it is just another plugin, which runs on different platforms

How to integrate this into the ZFX-Community-Engine 2

In the ZFX-Community-Engine I am currently offering a platform-integration called PlatformInterface. It currently contains:

  • Windows system abstraction to get a render window
  • Event handling abstraction for platform-specific event handling
  • Render Context abstraction for OpenGL 4.x
  • Thread abstraction

Two different implementation are already there: one for cross-platform based on SDL2 and one for Windows based on Win32-API. At the moment the classes are part of the Infrastructure library in the ZFXCE2. You can get the implementation by calling an static getter for the abstraction:

AbstractRenderContext *pRC = nullptr;
pRC = PlatformInterface::getInstance().getRenderCtx();

This works fine at the moment. Currently I haven’t planned to bring the platform-specific implementation in several plugins, but I will see.

Run a QML-Application in CodeXL

Hervorgehoben

I just tried to run my QML-based application in CodeXL to get an overview about my hotspots. You have to setup the path to your executable for the CodeXL-project.

Unfortunately with a qmake-based build the executable and the QT-libraries are not at the same place. So per default your app will not start.

Solving this is really easy: just add your QT-installation path to the PATH vaiable, if you are using only one QT-installation.

If you have to switch between two different installations you can use a startup-script, which adds your QT-installation path to the PATH-variable in windows.

Chicken Korma

Hervorgehoben

For my english training I just translated my favourite recepy for Chicken Korma into english. And of course I want to share this one:

Chicken Korma:
==============

800 g chicken breasts, cut in little pieces without skin or bones
One big onion cut in half rings
One red chilli peppers
Three cloves of garlic
One pieces of ginger ( size of your thump )
Almond slices
Shredded coconut
1 shrub of coriander
Curry paste ( Korma, you can do this on your own )
1 peace of butter
400 g chickpeas
400 g coconut milk
Salt
Black pepper
200 g natural yoghurt

At first produce the curry paste on your own or just buy it. Separate the leafs and the stalk
of the shrub of coriander. Now take your wok, put some oil in and heat it up until it is hot. Now you can sear the chicken meat until it get a light brown color all
around. Put the chilli, the mashed ginger, the onions and the stalk of
coriander with the butter into the wok. Cook this 10 minutes or so while you
are stiring the whole soup.
Mx the curry paste, the coconut milk, the almond leaves, the chickpeas,
the desiccated coconut and 200 ml of water into the wok.

Let it cook about 30 minutes. Now season to taste it with salt and
pepper.

Serve it with the leaves of coriander, the natural yoghurt and rice.

Enjoy your dinner!

Asset Importer Library news

Hervorgehoben

I am really happy to announce that we made a new major release for the Asset-Importer-Library. Currently we have only a new source package out, but the SDK is on its way as well.
The guy’s from Debian asked for a new stable release, because they wanted to add the assimp-package into the next Ubuntu-release and assimp changed the API. And this API-change will cause binary-incompatibilies with applications, which belongs to the 2.0-version.
The API-changes are already documented and you can find them here:
http://assimp.sourceforge.net/lib_html/usage.html

So what is new in Asset Importer Library 3.0. A lot I guess:

New features:

  • New export interface similar to the import API. Supported export formats are: collada, obj, ply and stl.
  • New import formats: XGL/ZGL, M3 (experimental)
  • New postprocessing step: Debone
  • Vastly improved IFC (Industry Foundation Classes) support
  • Introduced API to query importer meta information (such as supported format versions, full name, maintainer info).
  • Reworked Ogre XML import
House keeping / refactorings:
  • The API changed to optimize the usability
  • Unified naming and cleanup of public headers
  • Supporting a Debian-Package
  • IMprove CMake-Build system
  • Better CMake-Support for Linux and MacOS
We will release our release notes as fast as possible. Currently we are all really spare on time.
Thanks to all the helping hands, the patches and all the nice and really constructive feedback about our work.