240 lines
7.5 KiB
C++
240 lines
7.5 KiB
C++
/* ***********************************************************************
|
|
//
|
|
// Copyright (C) 2025 -- The 4D-STAR Collaboration
|
|
// File Author: Emily Boudreaux
|
|
// Last Modified: March 17, 2025
|
|
//
|
|
// 4DSSE is free software; you can use it and/or modify
|
|
// it under the terms and restrictions the GNU General Library Public
|
|
// License version 3 (GPLv3) as published by the Free Software Foundation.
|
|
//
|
|
// 4DSSE is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
// See the GNU Library General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Library General Public License
|
|
// along with this software; if not, write to the Free Software
|
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
//
|
|
// *********************************************************************** */
|
|
#include "DObject.h"
|
|
#include <iostream>
|
|
#include <stdexcept>
|
|
|
|
/**
|
|
* @file DObject.cpp
|
|
* @brief Implementation of the DObject class.
|
|
*
|
|
* Provides the implementation for a universal data container with plugin support.
|
|
*/
|
|
|
|
// Default constructor
|
|
DObject::DObject() : data_(std::monostate()), debugEnabled_(false) {
|
|
// The data is initialized to an empty state using std::monostate (a variant placeholder).
|
|
}
|
|
|
|
/**
|
|
* @brief Constructor to initialize a DObject with data.
|
|
*/
|
|
DObject::DObject(const DataType& data)
|
|
: data_(data), debugEnabled_(false) {}
|
|
|
|
/**
|
|
* @brief Retrieves the data stored in the DObject.
|
|
*/
|
|
const DObject::DataType& DObject::getData() const noexcept {
|
|
return data_;
|
|
}
|
|
|
|
/**
|
|
* @brief Sets the data for the DObject.
|
|
*/
|
|
void DObject::setData(const DataType& data) {
|
|
data_ = data;
|
|
}
|
|
|
|
/**
|
|
* @brief Enables or disables debugging and tracing for the DObject.
|
|
*/
|
|
void DObject::setDebugging(bool enableDebug) {
|
|
debugEnabled_ = enableDebug;
|
|
}
|
|
|
|
/**
|
|
* @brief Checks if debugging is enabled for the DObject.
|
|
*/
|
|
bool DObject::isDebuggingEnabled() const noexcept {
|
|
return debugEnabled_;
|
|
}
|
|
|
|
/**
|
|
* @breif Sets an error code and returns the old one
|
|
*/
|
|
int DObject::setErrorCode(int code) noexcept {
|
|
int oldCode = errorCode_;
|
|
errorCode_ = code;
|
|
return oldCode;
|
|
}
|
|
|
|
int DObject::getErrorCode() const noexcept {
|
|
return errorCode_;
|
|
}
|
|
|
|
/**
|
|
* @brief Registers a plugin with the DObject.
|
|
*/
|
|
void DObject::registerPlugin(const std::string& id, Plugin plugin) {
|
|
if (plugins_.find(id) != plugins_.end()) {
|
|
throw std::runtime_error("Plugin with ID '" + id + "' already exists.");
|
|
}
|
|
plugins_[id] = std::move(plugin);
|
|
}
|
|
|
|
/**
|
|
* @brief Unregisters a plugin by its identifier.
|
|
*/
|
|
void DObject::unregisterPlugin(const std::string& id) {
|
|
if (plugins_.erase(id) == 0) {
|
|
throw std::runtime_error("Plugin with ID '" + id + "' not found.");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Executes a plugin by its identifier.
|
|
*/
|
|
void DObject::runPlugin(const std::string& id) {
|
|
auto it = plugins_.find(id);
|
|
if (it == plugins_.end()) {
|
|
throw std::runtime_error("Plugin with ID '" + id + "' not found.");
|
|
}
|
|
it->second(*this); // Invoke the plugin, passing this DObject as a reference.
|
|
}
|
|
|
|
/**
|
|
* @brief Executes all registered plugins in the registry.
|
|
*/
|
|
void DObject::runAllPlugins() {
|
|
for (auto& [id, plugin] : plugins_) {
|
|
plugin(*this); // Invoke each plugin, passing this DObject as a reference.
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Provides a human-readable summary of the DObject.
|
|
*/
|
|
std::ostream& operator<<(std::ostream& os, const DObject& obj) {
|
|
os << "DObject Summary:\n";
|
|
os << " Debugging Enabled: " << (obj.debugEnabled_ ? "Yes" : "No") << "\n";
|
|
os << " Data: ";
|
|
std::visit([&os](const auto& value) {
|
|
using T = std::decay_t<decltype(value)>;
|
|
if constexpr (std::is_same_v<T, std::monostate>) {
|
|
os << "EMPTY";
|
|
} else if constexpr (std::is_same_v<T, int>) {
|
|
os << value;
|
|
} else if constexpr (std::is_same_v<T, float>) {
|
|
os << value;
|
|
} else if constexpr (std::is_same_v<T, double>) {
|
|
os << value;
|
|
} else if constexpr (std::is_same_v<T, std::string>) {
|
|
os << value;
|
|
} else if constexpr (std::is_same_v<T, std::vector<int>>) {
|
|
os << "[";
|
|
for (const auto& elem : value) {
|
|
os << elem << ", ";
|
|
}
|
|
os << "]";
|
|
} else if constexpr (std::is_same_v<T, std::vector<float>>) {
|
|
os << "[";
|
|
for (const auto& elem : value) {
|
|
os << elem << ", ";
|
|
}
|
|
os << "]";
|
|
} else if constexpr (std::is_same_v<T, std::vector<double>>) {
|
|
os << "[";
|
|
for (const auto& elem : value) {
|
|
os << elem << ", ";
|
|
}
|
|
os << "]";
|
|
} else if constexpr (std::is_same_v<T, std::vector<std::vector<int>>>) {
|
|
os << "\n[";
|
|
for (const auto& row : value) {
|
|
os << "[";
|
|
for (const auto& elem : row) {
|
|
os << elem << ", ";
|
|
}
|
|
os << "], ";
|
|
}
|
|
os << "]";
|
|
} else if constexpr (std::is_same_v<T, std::vector<std::vector<float>>>) {
|
|
os << "\n[";
|
|
for (const auto& row : value) {
|
|
os << "[";
|
|
for (const auto& elem : row) {
|
|
os << elem << ", ";
|
|
}
|
|
os << "], ";
|
|
}
|
|
os << "]";
|
|
} else if constexpr (std::is_same_v<T, std::vector<std::vector<double>>>) {
|
|
os << "\n[";
|
|
for (const auto& row : value) {
|
|
os << "[";
|
|
for (const auto& elem : row) {
|
|
os << elem << ", ";
|
|
}
|
|
os << "], ";
|
|
}
|
|
os << "]";
|
|
} else if constexpr (std::is_same_v<T, std::vector<std::vector<std::vector<int>>>>) {
|
|
os << "\n[";
|
|
for (const auto& plane : value) {
|
|
os << "[";
|
|
for (const auto& row : plane) {
|
|
os << "[";
|
|
for (const auto& elem : row) {
|
|
os << elem << ", ";
|
|
}
|
|
os << "], ";
|
|
}
|
|
os << "], ";
|
|
}
|
|
os << "]";
|
|
} else if constexpr (std::is_same_v<T, std::vector<std::vector<std::vector<float>>>>) {
|
|
os << "\n[";
|
|
for (const auto& plane : value) {
|
|
os << "[";
|
|
for (const auto& row : plane) {
|
|
os << "[";
|
|
for (const auto& elem : row) {
|
|
os << elem << ", ";
|
|
}
|
|
os << "], ";
|
|
}
|
|
os << "], ";
|
|
}
|
|
os << "]";
|
|
} else if constexpr (std::is_same_v<T, std::vector<std::vector<std::vector<double>>>>) {
|
|
os << "\n[";
|
|
for (const auto& plane : value) {
|
|
os << "[";
|
|
for (const auto& row : plane) {
|
|
os << "[";
|
|
for (const auto& elem : row) {
|
|
os << elem << ", ";
|
|
}
|
|
os << "], ";
|
|
}
|
|
os << "], ";
|
|
}
|
|
os << "]";
|
|
} else {
|
|
os << "UNKNOWN";
|
|
}
|
|
}, obj.data_);
|
|
os << "\n Data Type: " << obj.dataTypeMap.at(obj.data_.index());
|
|
os << "\n Plugins Registered: " << obj.plugins_.size() << "\n";
|
|
return os;
|
|
}
|