AuroraAlthough this project isn't directly related to SFML, I thought some people may find it interesting. Formerly a part of Thor, Aurora is now an autonomous library that provides various C++ functionality which can be useful in different situations.
I know this sounds extremely abstract, so here is an example of a quite intelligent smart pointer:
#include <Aurora/SmartPtr/CopiedPtr.hpp>
namespace sf { class Drawable; } // Forward declaration is enough
struct GameObject
{
aur::CopiedPtr<sf::Drawable> drawable;
};
#include <SFML/Graphics.hpp>
int main()
{
GameObject a, b, c;
a.drawable.reset(new sf::RectangleShape);
b.drawable.reset(new sf::Sprite); // different derivates
c = a; // performs a deep copy
} // deletes everything correctly
sf::Drawable is an abstract base class, but we can wrap it into a smart pointer. Like this, GameObject has normal value semantics, i.e. we can copy it as usual, while the derived type (sf::RectangleShape) is copied correctly through the hierarchy. This without a single copy constructor, assignment operator or a virtual clone function.
Another example are the dispatchers (also known as a way to emulate multimethods in C++). Their task is to choose the correct overload of a set of functions, of which the arguments are only known at runtime. This allows you to work with abstract base classes (like Object in the example), while interaction between two objects can still be implemented with the full type information. No need for manual case differentiations.
#include <Aurora/Dispatch.hpp>
#include <iostream>
// Example class hierarchy
class Object { public: virtual ~Object() {} };
class Asteroid : public Object {};
class Ship : public Object {};
// Functions for collision with different argument types
void collision(Asteroid*, Asteroid*) { std::cout << "Asteroid-Asteroid\n"; }
void collision(Asteroid*, Ship*) { std::cout << "Asteroid-Ship\n"; }
void collision(Ship*, Ship*) { std::cout << "Ship-Ship\n"; }
int main()
{
// Create dispatcher and register functions
aur::DoubleDispatcher<Object*> dispatcher;
dispatcher.add<Asteroid, Asteroid>(&collision);
dispatcher.add<Asteroid, Ship> (&collision);
dispatcher.add<Ship, Ship> (&collision);
// Base class pointers (no static type information about derived classes)
Object* a = new Asteroid;
Object* s = new Ship;
// Invoke functions, let dispatcher choose the correct overload
dispatcher.call(a, s); // Output: "Asteroid-Ship"
dispatcher.call(a, a); // Output: "Asteroid-Asteroid"
dispatcher.call(s, s); // Output: "Ship-Ship"
delete a;
delete s;
}
Aurora uses the zlib/libpng license. Since it is a header-only library, it requires no build process and can thus be very easily be used in your projects.
LinksAurora project homepageGitHub page