Optimizing project management and its requirements
This commit is contained in:
80
src/api/project.h
Normal file
80
src/api/project.h
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <dbus/api/api.h>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
namespace api::project
|
||||||
|
{
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
enum class OperationType : uint8_t
|
||||||
|
{
|
||||||
|
Create = 0,
|
||||||
|
Open,
|
||||||
|
Save,
|
||||||
|
SaveAs,
|
||||||
|
Close,
|
||||||
|
};
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
|
||||||
|
/* --- */
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
// Post event structs
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
struct ProjectOperationEvent : dBus::api::DefaultData<dBus::makeID("project.file.operation")>
|
||||||
|
{
|
||||||
|
ProjectOperationEvent() = default; // Default constructor
|
||||||
|
virtual ~ProjectOperationEvent() = default; // Default destructor
|
||||||
|
ProjectOperationEvent(const ProjectOperationEvent &obj) = default; // Copy constructor
|
||||||
|
ProjectOperationEvent(ProjectOperationEvent &&obj) noexcept = default; // Move constructor
|
||||||
|
ProjectOperationEvent &operator=(const ProjectOperationEvent &obj) = default; // Copy assignment operator
|
||||||
|
ProjectOperationEvent &operator=(ProjectOperationEvent &&obj) noexcept = default; // Move assignment operator
|
||||||
|
|
||||||
|
OperationType operationType;
|
||||||
|
std::filesystem::path filePath;
|
||||||
|
|
||||||
|
[[nodiscard]] std::string toString() const override
|
||||||
|
{
|
||||||
|
if (operationType == OperationType::Open || operationType == OperationType::SaveAs)
|
||||||
|
return std::format("ProjectOperationEvent: operation={}, filePath={}", getOperationString(), filePath.string());
|
||||||
|
else
|
||||||
|
return std::format("ProjectOperationEvent: operation={}", getOperationString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
[[nodiscard]] std::string getOperationString() const
|
||||||
|
{
|
||||||
|
switch (operationType)
|
||||||
|
{
|
||||||
|
using enum OperationType;
|
||||||
|
case Create:
|
||||||
|
return "Create";
|
||||||
|
case Open:
|
||||||
|
return "Open";
|
||||||
|
case Save:
|
||||||
|
return "Save";
|
||||||
|
case SaveAs:
|
||||||
|
return "SaveAs";
|
||||||
|
case Close:
|
||||||
|
return "Close";
|
||||||
|
}
|
||||||
|
throw std::runtime_error("Invalid project operation");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
|
||||||
|
/* --- */
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
// Post event helpers
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
inline dBus::api::PostReturnStatus postProjectOperationRequest(dBus::Bus &bus, const OperationType &operationType, const std::filesystem::path &filePath = "")
|
||||||
|
{
|
||||||
|
auto eventData = ProjectOperationEvent();
|
||||||
|
eventData.operationType = std::move(operationType);
|
||||||
|
eventData.filePath = std::move(filePath);
|
||||||
|
|
||||||
|
return dBus::api::requestData<decltype(eventData), void>(bus, eventData.getID(), eventData, dBus::MessageCategory::UI);
|
||||||
|
}
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
} // namespace api::project
|
||||||
@@ -1,20 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <dbus/api/api.h>
|
#include <dbus/api/api.h>
|
||||||
#include <filesystem>
|
|
||||||
#include <sdi_toolBox/generic/uuid.h>
|
#include <sdi_toolBox/generic/uuid.h>
|
||||||
|
|
||||||
namespace api::requirement
|
namespace api::requirement
|
||||||
{
|
{
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
enum class FileOperation : uint8_t
|
|
||||||
{
|
|
||||||
Create = 0,
|
|
||||||
Open,
|
|
||||||
Save,
|
|
||||||
SaveAs
|
|
||||||
};
|
|
||||||
//--------------------------------------------------------------
|
|
||||||
struct Requirement
|
struct Requirement
|
||||||
{
|
{
|
||||||
std::string uuid;
|
std::string uuid;
|
||||||
@@ -28,7 +19,7 @@ struct Requirement
|
|||||||
/* Default constructor */
|
/* Default constructor */
|
||||||
Requirement()
|
Requirement()
|
||||||
{
|
{
|
||||||
uuid = sdi_toolBox::generic::UuidGenerator::uniqid(); // Generate a unique identifier for the requirement
|
uuid = sdi_toolBox::generic::UuidGenerator::uuid_v4(); // Generate a unique UUID for the requirement
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
@@ -38,41 +29,6 @@ struct Requirement
|
|||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
// Post event structs
|
// Post event structs
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
struct FileOperationEvent : dBus::api::DefaultData<dBus::makeID("requirement.file.operation")>
|
|
||||||
{
|
|
||||||
virtual ~FileOperationEvent() = default; // Default destructor
|
|
||||||
|
|
||||||
FileOperation fileOperation;
|
|
||||||
std::filesystem::path filePath;
|
|
||||||
|
|
||||||
[[nodiscard]] std::string toString() const override
|
|
||||||
{
|
|
||||||
if (fileOperation == FileOperation::Open || fileOperation == FileOperation::SaveAs)
|
|
||||||
return std::format("FileOperationEvent: operation={}, filePath={}", getOperationString(), filePath.string());
|
|
||||||
else
|
|
||||||
return std::format("FileOperationEvent: operation={}", getOperationString());
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
[[nodiscard]] std::string getOperationString() const
|
|
||||||
{
|
|
||||||
switch (fileOperation)
|
|
||||||
{
|
|
||||||
using enum FileOperation;
|
|
||||||
case Create:
|
|
||||||
return "Create";
|
|
||||||
case Open:
|
|
||||||
return "Open";
|
|
||||||
case Save:
|
|
||||||
return "Save";
|
|
||||||
case SaveAs:
|
|
||||||
return "SaveAs";
|
|
||||||
default:
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
//--------------------------------------------------------------
|
|
||||||
struct RequirementEvent : dBus::api::DefaultData<dBus::makeID("requirement.requirementEvent")>
|
struct RequirementEvent : dBus::api::DefaultData<dBus::makeID("requirement.requirementEvent")>
|
||||||
{
|
{
|
||||||
virtual ~RequirementEvent() = default; // Default destructor
|
virtual ~RequirementEvent() = default; // Default destructor
|
||||||
@@ -95,15 +51,6 @@ struct RequirementEvent : dBus::api::DefaultData<dBus::makeID("requirement.requi
|
|||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
// Post event helpers
|
// Post event helpers
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
inline dBus::api::PostReturnStatus postFileOperationRequest(dBus::Bus &bus, const FileOperation &fileOperation, const std::filesystem::path &filePath = "")
|
|
||||||
{
|
|
||||||
auto eventData = FileOperationEvent();
|
|
||||||
eventData.fileOperation = std::move(fileOperation);
|
|
||||||
eventData.filePath = std::move(filePath);
|
|
||||||
|
|
||||||
return dBus::api::requestData<decltype(eventData), void>(bus, eventData.getID(), eventData, dBus::MessageCategory::UI);
|
|
||||||
}
|
|
||||||
//--------------------------------------------------------------
|
|
||||||
/* Post a requirement event to the bus. This function will post a
|
/* Post a requirement event to the bus. This function will post a
|
||||||
* RequirementEvent containing the provided requirement data to the
|
* RequirementEvent containing the provided requirement data to the
|
||||||
* bus, and return a PostReturnStatus indicating whether the post was
|
* bus, and return a PostReturnStatus indicating whether the post was
|
||||||
|
|||||||
@@ -28,15 +28,15 @@ void CoreManager::init()
|
|||||||
m_bus = make_unique<dBus::Bus>();
|
m_bus = make_unique<dBus::Bus>();
|
||||||
|
|
||||||
// Initialize other subsystems (e.g., logger, etc.)
|
// Initialize other subsystems (e.g., logger, etc.)
|
||||||
m_logger = make_unique<logger::Logger>(*m_bus);
|
m_logger = make_unique<logger::Logger>(*m_bus);
|
||||||
m_requirementManager = make_unique<requirementManager::RequirementManager>(*m_bus);
|
m_projectManager = make_unique<project::ProjectManager>(*m_bus);
|
||||||
}
|
}
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
/* Release resources used by the core manager (e.g., clean up the bus, etc.) */
|
/* Release resources used by the core manager (e.g., clean up the bus, etc.) */
|
||||||
void CoreManager::release()
|
void CoreManager::release()
|
||||||
{
|
{
|
||||||
// Clean up other subsystems (e.g., logger, etc.)
|
// Clean up other subsystems (e.g., logger, etc.)
|
||||||
m_requirementManager.reset();
|
m_projectManager.reset();
|
||||||
m_logger.reset();
|
m_logger.reset();
|
||||||
|
|
||||||
// Clean up the application bus
|
// Clean up the application bus
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "logger/logger.h"
|
#include "logger/logger.h"
|
||||||
#include "requirementManager/requirementManager.h"
|
#include "projectManager/projectManager.h"
|
||||||
|
|
||||||
#include <dBus/dBus.h>
|
#include <dBus/dBus.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@@ -24,8 +24,8 @@ class CoreManager
|
|||||||
protected:
|
protected:
|
||||||
std::unique_ptr<dBus::Bus> m_bus; // Application data bus
|
std::unique_ptr<dBus::Bus> m_bus; // Application data bus
|
||||||
|
|
||||||
std::unique_ptr<logger::Logger> m_logger; // Application logger system
|
std::unique_ptr<logger::Logger> m_logger; // Application logger system
|
||||||
std::unique_ptr<requirementManager::RequirementManager> m_requirementManager; // Requirement manager system
|
std::unique_ptr<project::ProjectManager> m_projectManager; // Requirement manager system
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init(); // Initialize the core manager (e.g., set up the bus, etc.)
|
void init(); // Initialize the core manager (e.g., set up the bus, etc.)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace core::logger
|
|||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
class Logger : public dBus::Node
|
class Logger : public dBus::Node
|
||||||
{
|
{
|
||||||
static constexpr auto LOG_PRINT_INTERVAL = std::chrono::seconds{ 1 };
|
static constexpr auto LOG_PRINT_INTERVAL = std::chrono::milliseconds{ 500 };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Logger() = delete; // Default constructor
|
Logger() = delete; // Default constructor
|
||||||
|
|||||||
11
src/core/projectManager/projectData.cpp
Normal file
11
src/core/projectManager/projectData.cpp
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#include "projectData.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace core::project;
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
/* Get the root requirement */
|
||||||
|
ProjectData::RequirementPtr ProjectData::getRootRequirement()
|
||||||
|
{
|
||||||
|
return m_rootRequirement;
|
||||||
|
}
|
||||||
|
//--------------------------------------------------------------
|
||||||
29
src/core/projectManager/projectData.h
Normal file
29
src/core/projectManager/projectData.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <api/requirement.h>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace core::project
|
||||||
|
{
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
class ProjectData
|
||||||
|
{
|
||||||
|
using RequirementPtr = std::shared_ptr<api::requirement::Requirement>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ProjectData() = default; // Default constructor
|
||||||
|
virtual ~ProjectData() = default; // Default destructor
|
||||||
|
ProjectData(const ProjectData &obj) = delete; // Copy constructor
|
||||||
|
ProjectData(ProjectData &&obj) noexcept = delete; // Move constructor
|
||||||
|
ProjectData &operator=(const ProjectData &obj) = delete; // Copy assignment operator
|
||||||
|
ProjectData &operator=(ProjectData &&obj) noexcept = delete; // Move assignment operator
|
||||||
|
|
||||||
|
RequirementPtr getRootRequirement(); // Get the root requirement
|
||||||
|
|
||||||
|
protected:
|
||||||
|
RequirementPtr m_rootRequirement; // Root requirement of the current project
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
} // namespace core::project
|
||||||
171
src/core/projectManager/projectManager.cpp
Normal file
171
src/core/projectManager/projectManager.cpp
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
#include "projectManager.h"
|
||||||
|
|
||||||
|
#include "projectData.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace core::project;
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
/* Constructor */
|
||||||
|
ProjectManager::ProjectManager(dBus::Bus &bus)
|
||||||
|
: Node(bus)
|
||||||
|
{
|
||||||
|
// Initialize the bus listener thread
|
||||||
|
runBusListener();
|
||||||
|
}
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
/* Default destructor */
|
||||||
|
ProjectManager::~ProjectManager()
|
||||||
|
{
|
||||||
|
// Stop the bus listener thread if it's running
|
||||||
|
stopBusListener();
|
||||||
|
}
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
/* Open a project file and load the requirements */
|
||||||
|
void ProjectManager::openFile(const std::filesystem::path &filePath)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
/* Save the current requirements to a project file */
|
||||||
|
void ProjectManager::saveFile(const std::filesystem::path &filePath)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
/* Run the bus listener thread */
|
||||||
|
void ProjectManager::runBusListener()
|
||||||
|
{
|
||||||
|
// Subscribe to the bus for messages related to log entries
|
||||||
|
subscribe(dBus::makeID("project.file.operation"));
|
||||||
|
|
||||||
|
/* Start the bus listener thread to process incoming messages related to requirements.
|
||||||
|
* The thread will continuously wait for messages and process them until a stop is requested. */
|
||||||
|
// clang-format off
|
||||||
|
m_busListenerThread = std::jthread([this](const std::stop_token &stopToken)
|
||||||
|
{
|
||||||
|
while (!stopToken.stop_requested())
|
||||||
|
{
|
||||||
|
// Wait for a message to be received
|
||||||
|
syncWaitForMessage();
|
||||||
|
|
||||||
|
// Process all received messages
|
||||||
|
while (getMessageCount() > 0)
|
||||||
|
{
|
||||||
|
auto message = popNextMessage();
|
||||||
|
if (message)
|
||||||
|
processMessageBus(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// clang-format on
|
||||||
|
}
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
/* Stop the bus listener thread */
|
||||||
|
void ProjectManager::stopBusListener()
|
||||||
|
{
|
||||||
|
// Stop event thread loop
|
||||||
|
m_busListenerThread.request_stop();
|
||||||
|
|
||||||
|
// Wake up event thread if waiting
|
||||||
|
notifyMessageQueue();
|
||||||
|
|
||||||
|
/* No need to join the thread explicitly as std::jthread will
|
||||||
|
* automatically join in its destructor.
|
||||||
|
* Subscribe to the bus will be automatically cleaned up in the
|
||||||
|
* Node destructor. */
|
||||||
|
}
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
/* Process a message received from the bus */
|
||||||
|
void ProjectManager::processMessageBus(const Message_ptr &message)
|
||||||
|
{
|
||||||
|
const auto messageType = message->getMessageTypeID();
|
||||||
|
switch (messageType)
|
||||||
|
{
|
||||||
|
case dBus::makeID("project.file.operation"):
|
||||||
|
{
|
||||||
|
// Process project operation request
|
||||||
|
on_projectOperationEvent(message->as<dBus::RequestMessage<api::project::ProjectOperationEvent, void>>());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
/* Process a file operation event */
|
||||||
|
void ProjectManager::on_projectOperationEvent(const ProjectOperationMessage_ptr &message)
|
||||||
|
{
|
||||||
|
// Sanity check
|
||||||
|
if (!message)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (message->value.operationType)
|
||||||
|
{
|
||||||
|
using enum api::project::OperationType;
|
||||||
|
case Create:
|
||||||
|
on_projectCreateFileEvent(message);
|
||||||
|
break;
|
||||||
|
case Open:
|
||||||
|
on_projectOpenFileEvent(message);
|
||||||
|
break;
|
||||||
|
case Save:
|
||||||
|
case SaveAs:
|
||||||
|
on_projectSaveFileEvent(message);
|
||||||
|
break;
|
||||||
|
case Close:
|
||||||
|
on_projectCloseFileEvent(message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
/* Process a file creation event */
|
||||||
|
void ProjectManager::on_projectCreateFileEvent(const ProjectOperationMessage_ptr &message)
|
||||||
|
{
|
||||||
|
m_projectData = make_shared<ProjectData>();
|
||||||
|
|
||||||
|
message->responsePromise.set_value();
|
||||||
|
}
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
/* Process a file open event */
|
||||||
|
void ProjectManager::on_projectOpenFileEvent(const ProjectOperationMessage_ptr &message)
|
||||||
|
{
|
||||||
|
// message->responsePromise.set_exception(std::make_exception_ptr(std::runtime_error("Open operation not implemented")));
|
||||||
|
try
|
||||||
|
{
|
||||||
|
openFile(message->value.filePath);
|
||||||
|
}
|
||||||
|
catch (const std::exception &e)
|
||||||
|
{
|
||||||
|
message->responsePromise.set_exception(std::make_exception_ptr(e));
|
||||||
|
}
|
||||||
|
message->responsePromise.set_value();
|
||||||
|
}
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
/* Process a file save event */
|
||||||
|
void ProjectManager::on_projectSaveFileEvent(const ProjectOperationMessage_ptr &message)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (message->value.operationType == api::project::OperationType::SaveAs)
|
||||||
|
{
|
||||||
|
if (message->value.filePath.empty())
|
||||||
|
throw std::runtime_error("File path is empty for SaveAs operation");
|
||||||
|
saveFile(message->value.filePath);
|
||||||
|
}
|
||||||
|
else if (message->value.operationType == api::project::OperationType::Save)
|
||||||
|
{
|
||||||
|
if (m_filePath.empty())
|
||||||
|
throw std::runtime_error("File path is empty for Save operation");
|
||||||
|
saveFile();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (const std::exception &e)
|
||||||
|
{
|
||||||
|
message->responsePromise.set_exception(std::make_exception_ptr(e));
|
||||||
|
}
|
||||||
|
message->responsePromise.set_value();
|
||||||
|
}
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
/* Process a file close event */
|
||||||
|
void ProjectManager::on_projectCloseFileEvent(const ProjectOperationMessage_ptr &message)
|
||||||
|
{
|
||||||
|
m_projectData = {};
|
||||||
|
message->responsePromise.set_value();
|
||||||
|
}
|
||||||
|
//--------------------------------------------------------------
|
||||||
52
src/core/projectManager/projectManager.h
Normal file
52
src/core/projectManager/projectManager.h
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <api/project.h>
|
||||||
|
#include <api/requirement.h>
|
||||||
|
#include <dBus/dBus.h>
|
||||||
|
#include <memory>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
namespace core::project
|
||||||
|
{
|
||||||
|
class ProjectData;
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
class ProjectManager : public dBus::Node
|
||||||
|
{
|
||||||
|
using ProjectPtr = std::shared_ptr<ProjectData>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ProjectManager() = delete; // Default constructor
|
||||||
|
virtual ~ProjectManager(); // Default destructor
|
||||||
|
ProjectManager(const ProjectManager &obj) = delete; // Copy constructor
|
||||||
|
ProjectManager(ProjectManager &&obj) noexcept = delete; // Move constructor
|
||||||
|
ProjectManager &operator=(const ProjectManager &obj) = delete; // Copy assignment operator
|
||||||
|
ProjectManager &operator=(ProjectManager &&obj) noexcept = delete; // Move assignment operator
|
||||||
|
|
||||||
|
explicit ProjectManager(dBus::Bus &bus); // Constructor
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::filesystem::path m_filePath; // Path of the currently opened project file
|
||||||
|
|
||||||
|
ProjectPtr m_projectData; // Current project data, including the root requirement and all its sub-requirements
|
||||||
|
|
||||||
|
private:
|
||||||
|
void openFile(const std::filesystem::path &filePath); // Open a project file and load the requirements
|
||||||
|
void saveFile(const std::filesystem::path &filePath = ""); // Save the current requirements to a project file
|
||||||
|
|
||||||
|
// dBus management
|
||||||
|
using Message_ptr = std::shared_ptr<dBus::Message>;
|
||||||
|
void runBusListener(); // Run the bus listener thread
|
||||||
|
void stopBusListener(); // Stop the bus listener thread
|
||||||
|
void processMessageBus(const Message_ptr &message); // Process a message received from the bus
|
||||||
|
std::jthread m_busListenerThread; // Thread for listening to bus messages related to requirements
|
||||||
|
|
||||||
|
// Events processing
|
||||||
|
using ProjectOperationMessage_ptr = std::shared_ptr<dBus::RequestMessage<api::project::ProjectOperationEvent, void>>;
|
||||||
|
void on_projectOperationEvent(const ProjectOperationMessage_ptr &message); // Process a file operation event
|
||||||
|
void on_projectCreateFileEvent(const ProjectOperationMessage_ptr &message); // Process a file creation event
|
||||||
|
void on_projectOpenFileEvent(const ProjectOperationMessage_ptr &message); // Process a file opening event
|
||||||
|
void on_projectSaveFileEvent(const ProjectOperationMessage_ptr &message); // Process a file saving event
|
||||||
|
void on_projectCloseFileEvent(const ProjectOperationMessage_ptr &message); // Process a file closing event
|
||||||
|
};
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
} // namespace core::project
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
#include "requirementManager.h"
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace core::requirementManager;
|
|
||||||
//--------------------------------------------------------------
|
|
||||||
/* Constructor */
|
|
||||||
RequirementManager::RequirementManager(dBus::Bus &bus)
|
|
||||||
: Node(bus)
|
|
||||||
{
|
|
||||||
// Initialize the bus listener thread
|
|
||||||
runBusListener();
|
|
||||||
}
|
|
||||||
//--------------------------------------------------------------
|
|
||||||
/* Default destructor */
|
|
||||||
RequirementManager::~RequirementManager()
|
|
||||||
{
|
|
||||||
// Stop the bus listener thread if it's running
|
|
||||||
stopBusListener();
|
|
||||||
}
|
|
||||||
//--------------------------------------------------------------
|
|
||||||
/* Get the root requirement */
|
|
||||||
api::requirement::Requirement &RequirementManager::getRootRequirement()
|
|
||||||
{
|
|
||||||
return m_rootRequirement;
|
|
||||||
}
|
|
||||||
//--------------------------------------------------------------
|
|
||||||
/* Run the bus listener thread */
|
|
||||||
void RequirementManager::runBusListener()
|
|
||||||
{
|
|
||||||
// Subscribe to the bus for messages related to log entries
|
|
||||||
subscribe(dBus::makeID("requirement.file.operation"));
|
|
||||||
|
|
||||||
/* Start the bus listener thread to process incoming messages related to requirements.
|
|
||||||
* The thread will continuously wait for messages and process them until a stop is requested. */
|
|
||||||
// clang-format off
|
|
||||||
m_busListenerThread = std::jthread([this](const std::stop_token &stopToken)
|
|
||||||
{
|
|
||||||
while (!stopToken.stop_requested())
|
|
||||||
{
|
|
||||||
// Wait for a message to be received
|
|
||||||
syncWaitForMessage();
|
|
||||||
|
|
||||||
// Process all received messages
|
|
||||||
while (getMessageCount() > 0)
|
|
||||||
{
|
|
||||||
auto message = popNextMessage();
|
|
||||||
if (message)
|
|
||||||
processMessageBus(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// clang-format on
|
|
||||||
}
|
|
||||||
//--------------------------------------------------------------
|
|
||||||
/* Stop the bus listener thread */
|
|
||||||
void RequirementManager::stopBusListener()
|
|
||||||
{
|
|
||||||
// Stop event thread loop
|
|
||||||
m_busListenerThread.request_stop();
|
|
||||||
|
|
||||||
// Wake up event thread if waiting
|
|
||||||
notifyMessageQueue();
|
|
||||||
|
|
||||||
/* No need to join the thread explicitly as std::jthread will
|
|
||||||
* automatically join in its destructor.
|
|
||||||
* Subscribe to the bus will be automatically cleaned up in the
|
|
||||||
* Node destructor. */
|
|
||||||
}
|
|
||||||
//--------------------------------------------------------------
|
|
||||||
/* Process a message received from the bus */
|
|
||||||
void RequirementManager::processMessageBus(const Message_ptr &message)
|
|
||||||
{
|
|
||||||
const auto messageType = message->getMessageTypeID();
|
|
||||||
switch (messageType)
|
|
||||||
{
|
|
||||||
case dBus::makeID("requirement.file.operation"):
|
|
||||||
{
|
|
||||||
// Process file operation request
|
|
||||||
const auto requestMessage = message->as<dBus::RequestMessage<api::requirement::FileOperationEvent, void>>();
|
|
||||||
if (!requestMessage)
|
|
||||||
break;
|
|
||||||
|
|
||||||
requestMessage->responsePromise.set_exception(std::make_exception_ptr(std::runtime_error("Failed to process file operation request")));
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//--------------------------------------------------------------
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <api/requirement.h>
|
|
||||||
#include <dBus/dBus.h>
|
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
namespace core::requirementManager
|
|
||||||
{
|
|
||||||
//--------------------------------------------------------------
|
|
||||||
class RequirementManager : public dBus::Node
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
RequirementManager() = delete; // Default constructor
|
|
||||||
virtual ~RequirementManager(); // Default destructor
|
|
||||||
RequirementManager(const RequirementManager &obj) = delete; // Copy constructor
|
|
||||||
RequirementManager(RequirementManager &&obj) noexcept = delete; // Move constructor
|
|
||||||
RequirementManager &operator=(const RequirementManager &obj) = delete; // Copy assignment operator
|
|
||||||
RequirementManager &operator=(RequirementManager &&obj) noexcept = delete; // Move assignment operator
|
|
||||||
|
|
||||||
explicit RequirementManager(dBus::Bus &bus); // Constructor
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// dBus::Bus &m_bus; // Reference to the application bus
|
|
||||||
|
|
||||||
api::requirement::Requirement m_rootRequirement;
|
|
||||||
|
|
||||||
private:
|
|
||||||
api::requirement::Requirement &getRootRequirement(); // Get the root requirement
|
|
||||||
|
|
||||||
// dBus management
|
|
||||||
using Message_ptr = std::shared_ptr<dBus::Message>;
|
|
||||||
void runBusListener(); // Run the bus listener thread
|
|
||||||
void stopBusListener(); // Stop the bus listener thread
|
|
||||||
void processMessageBus(const Message_ptr &message); // Process a message received from the bus
|
|
||||||
std::jthread m_busListenerThread; // Thread for listening to bus messages related to requirements
|
|
||||||
};
|
|
||||||
//--------------------------------------------------------------
|
|
||||||
} // namespace core::requirementManager
|
|
||||||
@@ -212,7 +212,8 @@ std::expected<TResponse, ReturnStatus> requestData(Bus
|
|||||||
catch (const std::exception &e)
|
catch (const std::exception &e)
|
||||||
{
|
{
|
||||||
::api::log::postLogError(bus, std::format("Exception in requestData for message type: 0x{:08x}: {}", msg->getMessageTypeID(), e.what()));
|
::api::log::postLogError(bus, std::format("Exception in requestData for message type: 0x{:08x}: {}", msg->getMessageTypeID(), e.what()));
|
||||||
return std::unexpected(ReturnStatus::Exception);
|
// return std::unexpected(ReturnStatus::Exception);
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ void Node::subscribe(const HashID &eventType)
|
|||||||
m_bus.subscribe(eventType, this);
|
m_bus.subscribe(eventType, this);
|
||||||
}
|
}
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
/* Unsubscribe from a specific message type */
|
/* Unsubscribe from a specific message type */
|
||||||
void Node::unsubscribe(const HashID &eventType)
|
void Node::unsubscribe(const HashID &eventType)
|
||||||
{
|
{
|
||||||
m_bus.unsubscribe(eventType, this);
|
m_bus.unsubscribe(eventType, this);
|
||||||
|
|||||||
Reference in New Issue
Block a user