Skip to content

AshleyCPP For Java Users

SgtCoDFish edited this page Dec 19, 2014 · 9 revisions

If you've got experience with the Java version of AshleyCPP, this page will get you up to speed with the C++ port quickly.

Getting up and Running

First thing's first: compile AshleyCPP using CMake and make sure the include files and the library are available for your project to use. The debug library looks like libAshleyCPP-d.a and the release version looks like libAshleyCPP.a. You'll want to do #include "Ashley/AshleyCore.hpp" at the top of files which use AshleyCPP.

Engines are made very similar to in Java:

Engine engine;

will create an engine for you to use. Entities and components are created slightly differently. Say we have a PositionComponent:

class PositionComponent : public ashley::Component {
    public:
        int64_t x, y;

        PositionComponent() : PositionComponent(0, 0) {}
        PositionComponent(int64_t x, int64_t y) : x(x), y(y) {}
};

we create an entity with a position component in one of a few ways:

// make the Entity manually, and move it into the Engine.
auto entity = std::unique_ptr<ashley::Entity>(new Entity());
            //std::make_unique<ashley::Entity>(); // in C++14

// Using perfect forwarding to avoid constructing a temporary component.
// create a PositionComponent and call the second constructor to initialise 
// it to x = 3, y = 5.
entity->add<PositionComponent>(3, 5);

// alternatively if you need to still use the component afterwards:
auto pc = std::unique_ptr<PositionComponent>(new PositionComponent(3, 5));
        //std::make_unique<PositionComponent>(3, 5); // in C++14
entity->add(std::move(pc));
// don't forget to move it, and don't use it after moving!

// also don't forget to add the entity to the engine!
Entity *ret = engine.addEntity(std::move(entity));

// we can't use entity any more as it's been moved from; we can use ret however.

// this is all much cleaner using preferred style:
auto temp = engine.addEntity(); // add empty Entity but get a pointer
temp->add<PositionComponent>(2, 7);

Creating a System

Creating a system is very similar to Java:

// in "MovementSystem.hpp"
#include <cstdint>

class MovementSystem : public ashley::IteratingSystem {
    MovementSystem(int64_t priority);

    void processEntity(ashley::Entity * const &entity, float deltaTime) override;
}

// in "MovementSystem.cpp"
#include <typeinfo>
#include "Ashley/AshleyCore.hpp"
#include "MovementSystem.hpp"

// we call the IteratingSystem constructor with a family which
// only matches our PositionComponent from above.
MovementSystem::MovementSystem(int64_t priority ) :
    ashley::IteratingSystem(ashley::Family::getFor({typeid(PositionComponent)}), priority) {}

void MovementSystem::processEntity(std::shared_ptr<ashley::Entity> &entity, float deltaTime) {
    // note the API change; ComponentMapper is templated on the type it
    // maps; we just call getMapper() to retrieve it.
    auto positionMapper =
        ashley::ComponentMapper<PositionComponent>::getMapper();
    
    auto position = positionMapper.get(entity);
    position->x += 2;
    position->y += 3;
}

the above code creates an IteratingSystem which will iterate over any entity in the engine which has a PositionComponent and increase its x and y coordinates.

Conclusion

I hope this guide helped you to get to grips with the small changes made to AshleyCPP. Consider checking the Ashley Wiki for Java guides which should be easy to "translate" to C++ given the similarities between the two!

Clone this wiki locally