An event-driven framework built on SFML. Compose behavior with traits, manage plugins safely, and ship polished UI — without the boilerplate.
#include <Malena/Engine/App/Application.h> #include <Malena/Graphics/Primitives/Rectangle.h> class MyApp : public ml::Application { public: MyApp() : Application(1280, 720, 32, "My App") {} void initialization() override { _panel.setSize({300.f, 160.f}); _panel.setFillColor(sf::Color(83, 74, 183)); _panel.setPosition({100.f, 100.f}); addComponent(_panel); } void registerEvents() override { _panel.onClick([this]{ _panel.setFillColor(sf::Color::Green); }); _panel.onHover([this]{ _panel.setFillColor(sf::Color(120, 80, 220)); }); _panel.onUnhover([this]{ _panel.setFillColor(sf::Color(83, 74, 183)); }); } private: ml::Rectangle _panel; };
class MyManifest : public ml::Manifest { public: static constexpr const char* name = "My Plugin"; static constexpr const char* version = "1.0.0"; enum class Images { Background, Player }; enum class Fonts { Main }; enum class Flag { Selected, Active }; enum class State { Idle, Running }; private: inline static const auto _ = [](){ set(Images::Background, "assets/bg.png"); set(Images::Player, "assets/player.png"); set(Fonts::Main, "assets/main.ttf"); return 0; }(); };
#include "MyApp.h" int main() { MyApp app; app.run(); // enters the main loop return 0; }
Mix in Subscribable, Flaggable, Draggable, and Positionable without deep inheritance. Behavior composes cleanly at compile time.
Two channels — string-keyed events for UI input, typed enum messages for plugins. Deferred operations prevent iterator crashes.
Load and unload dylibs at runtime. Deferred cleanup ensures no use-after-free when a plugin tears itself down inside a callback.
Declare textures, fonts, and sounds in a manifest struct. AssetsManager loads and caches them — no manual file paths scattered in code.
window.draw() still works. sf::Vector2f, sf::Color, sf::Texture — unchanged. Malena adds structure, not a new API to learn.
moveTo() and moveDistance() with LINEAR or EXPONENTIAL easing built into every Positionable. No animation library needed.
Inherit ml::Application and override two methods
Create framework objects and register them in initialization()
Wire up onClick, onHover, onUpdate in registerEvents()
Register assets and custom flags in a manifest struct
Call app.run() and enter the main loop
Build a window with a colored rectangle that responds to clicks and hover events.
Declare textures, fonts, and custom flags. Load assets through AssetsManager.
Mix Draggable, Flaggable, and custom state machines into a single component.
Add a game-selection carousel with shader effects and navigation arrows.
Create a plugin with PluginWith, export it with REGISTER_PLUGIN, and load it at runtime.
Build a student plugin for the DaveStation platform with GamePlugin and a manifest.
Full API reference, Doxygen docs, and example projects included.