6
\$\begingroup\$

I would like to create some level of abstraction above math in my code. I mean I don't want to be dependant on the implementation of math operations or even on class names, which are provided by some math library. I will show you a simple example.

Let's assume that we have 2 math libraries. Let's consider 3D-vector classes:

Library A has 3D-vector class as "Vector3D" and its method "Subtract".

Library B has 3D-vector class as "vector3" and its method "subtr".

Now I want to be able to swtich between these 2 different implementations, but without changing any line of code. For, instance I would like to have it like this:

My 3D-vector class name will be "vec3" and its method "sub". But behind "vec3" and "sub" it can be implementation from library A or library B, depending on what I choose with 1 line of code in the beginning of program or even on compilation stage.

In other words it should look like a plugable system for math libraries.

I think it's about programming patterns here right? It look like delegation or factory. Could make clear for me how to implement this approach and is it worth it?

\$\endgroup\$
3
  • 1
    \$\begingroup\$ And why? Anyway, I think this is moe suited to SO. \$\endgroup\$ May 23, 2011 at 14:08
  • 1
    \$\begingroup\$ @The Communist Duck, I think this question is fine. Other field of programming could easily get away with a non optimized abstraction for the math lib, but a game on a mobile device really needs to be optimized as possible. \$\endgroup\$ May 23, 2011 at 17:50
  • 1
    \$\begingroup\$ Actually, I was more going for 'why do you want multiple math libraries'? \$\endgroup\$ May 23, 2011 at 18:03

3 Answers 3

9
\$\begingroup\$

The design pattern you are looking for is the adapter pattern (wikipedia).

The adapter pattern (often referred to as the wrapper pattern or simply a wrapper) is a design pattern that translates one interface for a class into a compatible interface...

One way to implement the adapter pattern is to create a generic interface (abstract) for the vector class, and then you could derive classes from it that call the correct functions.

To switch between the concrete derived classes you could use a typedef. e.g. you would define

typedef VectorDirectX Vector

or

typedef VectorOpenGL Vector

and then you would only use Vector in your code. This would only work if you weren't planning on switching Vector classes at runtime.

If you did need to switch between them at runtime you could use a factory, which would create the required class and return a pointer/reference to the base abstract class.

In practice for performance reasons I'd rather rely on refactoring tools (e.g. Visual Assist) to rename functions and classes unless I'm working on a massive project or there's a legitimate reason why the classes would need to frequently change.

\$\endgroup\$
1
  • \$\begingroup\$ Definitely +1 for the performance note. Most mathematical libraries like XNAMath feature heavy inlining, which would be lost with some kind of factory pattern. \$\endgroup\$
    – DeadMG
    May 23, 2011 at 15:24
6
\$\begingroup\$

I strongly recommend not to put a layer of abstraction between your application and the math-lib, neither high level factories nor inheritance for different platforms, nor delegation nor similar patterns.

You want your vector math code as optimized as possible.

Unfortunetely layers of abstraction that make your design more user-friendly, have massive performance impacts, especially in low level code such as math libraries.

So what can you do?

Either use those libraries that do all the dirty work for you like: multi platform implementation, passing vectors via registers rather than the stack if possible, etc:

  1. Sony's vectormath SSE2 and Altivec
  2. Bullet's Linearmath SSE2

Or use them as the inspiration for your own. Forget about fancy design patterns in this case, here performance is priority No. 1

\$\endgroup\$
3
  • \$\begingroup\$ What about mobile platforms? I'm currently working on an OpenGL project for Android and iOS. To be more specific I'm implementing skeletal animation and I need a good math library, which would compile for those platforms. I don't think SSE would be possible :) \$\endgroup\$ May 23, 2011 at 13:11
  • \$\begingroup\$ SSE is just a compile option in either suggested libraries, both can be compiled with normal C++, just dont activate the "SSE" compile switch :) \$\endgroup\$ May 23, 2011 at 13:13
  • \$\begingroup\$ You're very welcome! Good luck :) \$\endgroup\$ May 23, 2011 at 13:55
-1
\$\begingroup\$

since you are coding with c++ you can use some advance template features like this :

struct vector3
{
    void subtr(vector3 p){};
};

struct vector3D
{
    void Subtract(vector3D p){};
};

template <bool t> class Vector3DWrapper{
    vector3D v3d;
public:
    void subtract(Vector3DWrapper pv) {v3d.Subtract(pv.v3d);};
};

template <> class Vector3DWrapper<true> {
    vector3 v3;
public:
    void subtract(Vector3DWrapper pv) {v3.subtr(pv.v3);};
};

now if you declare some vector from Vector3DWrapper<true> type it'll use all vector3d features and other wise it'll all be Vector3D features, the only thing is that this code will generate errors if want to set some Vector3DWrapper<false> variable to Vector3DWrapper<true> value, but this can also be solved by just implementing cast operators for these classes.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .