build: split core/ from frontends/; prepare for multiple GUI/TUI targets
Reorganise the tree into business vs frontend as separate directories:
src/core/{domain,imports,app} (was system/, imports/, app/)
src/frontends/tui/ (was tui/ + main.cpp)
tests/tui/ (the FTXUI-coupled helper test)
All cross-dir #include paths rewritten; same-dir includes untouched.
CMake: essim_core is the frontend-agnostic business library — links libzip,
pugixml and bsdl, NO GUI toolkit. Each frontend is a self-contained
src/frontends/<name>/ (own CMakeLists, toolkit, main.cpp) that links
essim_core, selected with -DESSIM_FRONTEND=<name> (default tui; 'none' = core +
tests only, no toolkit fetched). FTXUI moved into the tui frontend. Tests are
split: essim_tests links essim_core (no FTXUI), essim_tui_tests links essim_tui.
Verified: default tui build green (ctest 2/2); ESSIM_FRONTEND=none builds the
core + tests with FTXUI never fetched and no `essim` binary.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
215
src/core/domain/syselmts.hpp
Normal file
215
src/core/domain/syselmts.hpp
Normal file
@@ -0,0 +1,215 @@
|
||||
#ifndef _SYSELEMENTS_HPP_
|
||||
#define _SYSELEMENTS_HPP_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <stdexcept>
|
||||
|
||||
using namespace std;
|
||||
|
||||
/**
|
||||
* @brief Represents a basic system element with a name.
|
||||
*/
|
||||
class SystemElement
|
||||
{
|
||||
public:
|
||||
string name; // Name of the system element.
|
||||
|
||||
/**
|
||||
* @brief Constructor for SystemElement.
|
||||
* @param name Name of the element.
|
||||
*/
|
||||
SystemElement(string name) : name(name) {};
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A container for managing system elements of type T.
|
||||
*
|
||||
* @tparam T Type of elements, must inherit from SystemElement.
|
||||
*/
|
||||
template <typename T>
|
||||
class SystemElementContainer : public SystemElement
|
||||
{
|
||||
public:
|
||||
using MapType = unordered_map<string, T *>; // Map to store elements by name.
|
||||
using iterator = typename MapType::iterator; // Iterator for the map.
|
||||
using const_iterator = typename MapType::const_iterator; // Const iterator for the map.
|
||||
|
||||
protected:
|
||||
unsigned int iter_count; // Counter for iterations (currently unused).
|
||||
MapType content; // Container for storing elements.
|
||||
|
||||
/**
|
||||
* @brief Adds elements from a map to the container.
|
||||
* @param el_content Map of elements to add.
|
||||
*/
|
||||
void add(MapType el_content)
|
||||
{
|
||||
for (const auto &[key, value] : el_content)
|
||||
{
|
||||
add(value);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor for an empty container.
|
||||
* @param name Name of the container.
|
||||
*/
|
||||
SystemElementContainer(string name) : SystemElement(name) {};
|
||||
|
||||
/**
|
||||
* @brief Constructor with initial elements.
|
||||
* @param name Name of the container.
|
||||
* @param elements Vector of elements to add.
|
||||
*/
|
||||
SystemElementContainer(string name, vector<T *> elements) : SystemElement(name)
|
||||
{
|
||||
add(elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds a single element to the container with a given name.
|
||||
* @param name Name of the element to add.
|
||||
* @param element Pointer to the element to add.
|
||||
* @throws runtime_error If the element's name is empty or already exists.
|
||||
*/
|
||||
virtual void add(string name, T *element)
|
||||
{
|
||||
if ("" == name)
|
||||
{
|
||||
throw runtime_error("System elements with empty names are forbidden");
|
||||
}
|
||||
if (exists(name))
|
||||
{
|
||||
throw runtime_error("System elements of same names are forbidden");
|
||||
}
|
||||
content.insert({name, element});
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds a single element to the container.
|
||||
* @param element Pointer to the element to add.
|
||||
* @throws runtime_error If the element's name is empty or already exists.
|
||||
*/
|
||||
virtual void add(T *element)
|
||||
{
|
||||
add (element->name, element);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if an element exists in the container.
|
||||
* @param name Name of the element to check.
|
||||
* @return True if the element exists, false otherwise.
|
||||
*/
|
||||
bool exists(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
get(name);
|
||||
return true;
|
||||
}
|
||||
catch (const exception &e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds elements from another container.
|
||||
* @param elements Pointer to another container.
|
||||
*/
|
||||
void add(SystemElementContainer<T> *elements)
|
||||
{
|
||||
add(elements->content);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds multiple elements from a vector.
|
||||
* @param elements Vector of elements to add.
|
||||
*/
|
||||
void add(vector<T *> elements)
|
||||
{
|
||||
for (auto &element : elements)
|
||||
{
|
||||
add(element);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieves an element by its name.
|
||||
* @param name Name of the element to retrieve.
|
||||
* @return Pointer to the element.
|
||||
* @throws runtime_error If the element is not found.
|
||||
*/
|
||||
T *get(string name)
|
||||
{
|
||||
auto it = content.find(name);
|
||||
if (it != content.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw runtime_error("System elements not found");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Merges an element by retrieving it or creating a new one if it doesn't exist.
|
||||
* @param name Name of the element.
|
||||
* @return Pointer to the merged or newly created element.
|
||||
*/
|
||||
/**
|
||||
* @brief Removes the element with the given name from the container.
|
||||
* The element itself is NOT deleted — caller owns it.
|
||||
* @return True if an element was removed, false if the name was absent.
|
||||
*/
|
||||
bool remove(string name)
|
||||
{
|
||||
return content.erase(name) > 0;
|
||||
}
|
||||
|
||||
T *merge(string name)
|
||||
{
|
||||
if (exists(name))
|
||||
{
|
||||
return get(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
T *ret = new T(name);
|
||||
add(ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
size_t size() const { return content.size(); }
|
||||
|
||||
/**
|
||||
* @brief Returns an iterator to the beginning of the container.
|
||||
* @return Iterator to the beginning.
|
||||
*/
|
||||
iterator begin() { return std::begin(content); }
|
||||
|
||||
/**
|
||||
* @brief Returns an iterator to the end of the container.
|
||||
* @return Iterator to the end.
|
||||
*/
|
||||
iterator end() { return std::end(content); }
|
||||
|
||||
/**
|
||||
* @brief Returns a constant iterator to the beginning of the container.
|
||||
* @return Constant iterator to the beginning.
|
||||
*/
|
||||
const_iterator begin() const { return std::begin(content); }
|
||||
|
||||
/**
|
||||
* @brief Returns a constant iterator to the end of the container.
|
||||
* @return Constant iterator to the end.
|
||||
*/
|
||||
const_iterator end() const { return std::end(content); }
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user