Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/raoulkdev/MiniECS/llms.txt

Use this file to discover all available pages before exploring further.

MiniECS::Unit is the entity class. It holds a collection of Modules and provides type-safe access to them. Units are not constructed directly — they are created through World::createUnit() and owned by the World. Each Unit carries a name for identification and a modules vector that drives its per-frame behaviour.

Namespace & Header

namespace MiniECS { class Unit; }
#include "unit/Unit.h"

Constructor

explicit Unit(std::string newName);
Stores the given name (moving it into the internal name field) and prints "Constructed unit, name: <name>" to stdout. Units are constructed internally by World::createUnit() and stored as std::unique_ptr<Unit> — you do not normally call this constructor directly.
newName
string
required
The name to assign to this Unit. Used for identification in World::getUnitByName() and World::removeUnitByName().
Example
// Typically created via World, not directly:
MiniECS::Unit unit("Player");
// stdout: "Constructed unit, name: Player"

Destructor

~Unit();
Prints "Destructed unit, name: <name>" to stdout when the Unit is destroyed. Because the Unit owns its Modules via unique_ptr, all attached Modules are also destroyed at this point, each printing their own "Removed <typeName>" message.

addModule

void addModule(ModuleType moduleType);
Creates and attaches a Module of the specified type to this Unit. Before creating the Module, the method iterates the existing modules vector to check for duplicates. If a Module of the same type already exists, it prints "Module type already exsists, cannot add it!" to stdout and does nothing. The supported types and their corresponding concrete classes are:
ModuleTypeConcrete Class
ModuleType::RendererRendererModule
ModuleType::TransformTransformModule
Passing any other ModuleType value (such as ModuleType::ModuleBase) prints "Invalid Module Type!!" and does not add a Module.
moduleType
ModuleType
required
The type of Module to create and attach. See ModuleType for all valid values.
Example
auto& player = myWorld.getUnitByName("Player");
player->addModule(MiniECS::ModuleType::Transform);
player->addModule(MiniECS::ModuleType::Renderer);

// Attempting to add a duplicate:
player->addModule(MiniECS::ModuleType::Transform);
// stdout: "Module type already exsists, cannot add it!"
Each Unit can hold at most one Module of each type. The duplicate check is based on the ModuleType enum value stored inside the Module, compared via getType().

removeModule

void removeModule(ModuleType moduleType);
Searches the modules vector for a Module whose getType() matches moduleType. If found, the Module is erased from the vector and its destructor is called. If no matching Module is found, the method prints "Could not find module in: <name>" to stdout.
moduleType
ModuleType
required
The type of Module to locate and remove. See ModuleType for all valid values.
Example
player->removeModule(MiniECS::ModuleType::Renderer);
// stdout: "Removed Renderer"

player->removeModule(MiniECS::ModuleType::Renderer); // already removed
// stdout: "Could not find module in: Player"

getModule<T>

template<typename T>
T* getModule();
Iterates the modules vector and attempts a dynamic_cast<T*> on each Module’s raw pointer. Returns the first successful cast. If no Module in the vector can be cast to T, prints "Module of requested type not found in unit: <name>" to std::cerr and returns nullptr. Template parameter: T — the concrete Module subclass to retrieve, such as TransformModule or RendererModule. Returns: T* pointing to the matching Module, or nullptr if no match is found.
Always check the return value for nullptr before dereferencing it. Dereferencing a nullptr is undefined behaviour and will crash at runtime.
Example
auto* transform = player->getModule<MiniECS::TransformModule>();
if (transform)
{
    transform->position = glm::vec2(10.0f, 5.0f);
}
getModule<T>() uses dynamic_cast rather than type-enum comparison, so it works correctly with any custom Module subclass you create — not just the built-in types.

getName

std::string getName() const;
Returns a copy of the Unit’s name string. This is the same value that was passed to the constructor and is used for name-based lookups in the World. Returns: std::string — the Unit’s name. Example
std::cout << player->getName(); // "Player"

getModulesVector

std::vector<std::unique_ptr<Module>>& getModulesVector();
Returns a mutable reference to the internal modules vector. This is a lower-level accessor primarily used by World::play() to check whether a Unit has any Modules before entering the game loop. Prefer addModule(), removeModule(), and getModule<T>() for typical module management. Returns: std::vector<std::unique_ptr<Module>>& — a mutable reference to the modules container. Example
auto& mods = player->getModulesVector();
std::cout << "Module count: " << mods.size() << "\n";

callModuleStart

void callModuleStart() const;
Iterates every Module in the modules vector and calls start() on each one in order. This method is invoked by World::play() on every frame (approximately every 16 ms) for Units that have at least one Module. You can also call it manually if you need to tick a Unit outside the standard game loop. Example
// Manual single-frame tick:
player->callModuleStart();
The start() name is a legacy convention from the framework’s initial design. In practice, start() functions as a per-frame update callback, not a one-time initialisation method.

Build docs developers (and LLMs) love