Skip to content
CXO2 edited this page Jul 16, 2026 · 7 revisions

Overview

Genode currently provides 5 interfaces, each representing a particular entity that can be used as a building block to create a complex entity. These interfaces are lightweight and can be used in any setting: You can use them in any part of the Genode layers or even in a simple, plain SFML traditional game loop.

It is highly recommended that you understand how to design an SFML-like entity, which shares the same idea with how you would utilize sf::Drawable class to create an entity.

Type of entities

Gx::Renderable

This interface represents an entity that can be rendered to a render surface (or a render target). Gx::Renderable implements and is equivalent to the sf::Drawable class in SFML.

Unlike the draw function, the Render function expects you to return a Gx::RenderStates. Typically, you return the latest render states after finishing the rendering calls. This could be useful in the SceneGraph implementation, where you may interested in inferring some of the rendering states from the renderable children or sibling nodes.

When you draw a renderable object as asf::Drawable object, the Render function will be called with a temporary Gx::RenderSurface using the adaptor class that is bound to the specified sf::RenderTarget.

Genode uses the Render term rather than draw, but they're essentially the same.

Gx::Updatable

This interface represents an entity that can be updated every frame via Update(const sf::Time& delta). Unlike Render or draw, Update is a mutable (non-const) function. The delta represents the time elapsed since the last frame, expressed in sf::Time.

Gx::Inputable

This interface represents an entity that can receive user input.

Gx::Colorable

This interface represents an entity that possesses a color.

Gx::Presentable

This interface represents an entity that can be presented on top of Gx::Presentable::Parent. For example, this interface can be used to implement UI Dialog/Modal-like behavior. The interface is not tied to graphical details and can also be utilized for other non-graphical implementations.

Creating your own entity

Similar to how creating an entity works in SFML, you can simply implement one or more interfaces to create your entity. The following code illustrates an entity that can render, update, and listen to user input:

class MyEntity : public sf::Transformable, public Gx::Renderable, public Gx::Updatable, public Gx::Inputable
{
public:

    // add functions to play with the entity's geometry / colors / texturing...

private:

    void Update(const sf::Time& delta) override
    {
        // Move entity to the right by 100px every second
        m_elapsed += delta;
        if (m_elapsed >= sf::seconds(1))
        {
            move({100, 0});                // move() is defined by sf::Transformable
            m_elapsed -= sf::seconds(1); // reset timer duration
        }
    }

    void OnKeyPressed(const sf::Event::KeyPressed& ev) override
    {
        // Move entity upward by 100px when user press / hold space key
        if (ev.code == sf::Keyboard::Key::Space)
        {
            move(0, -100); // move() is defined by sf::Transformable
        }
    }

    Gx::RenderStates Render(Gx::RenderSurface& target, Gx::RenderStates states) const override
    {
        // apply the entity's transform -- combine it with the one that was passed by the caller
        states.Transform *= getTransform(); // getTransform() is defined by sf::Transformable

        // apply the texture
        states.texture = &m_texture;

        // you may also override states.shader or states.blendMode if you want

        // draw the vertex array
        target.Render(m_vertices, states);
    }

    sf::VertexArray m_vertices;
    sf::Texture m_texture;
    sf::Time m_elapsed;
};

You can then use this class as if it were a built-in SFML/Genode class:

MyEntity entity;
sf::Time delta = // compute delta each frame..

// you can transform it
entity.setPosition(10.f, 50.f);
entity.setRotation(45.f);

// you can update it
entity.Update(delta);

// you can let it listen to input events
if (const auto event = window.pollEvent()) {
    entity.Input(event.value());
}

// you can draw it via SFML sf::RenderTarget
window.draw(entity);

// .. or render it via Genode Gx::RenderSurface
surface.Render(entity);

Clone this wiki locally