Optimizing project management and its requirements
This commit is contained in:
@@ -28,15 +28,15 @@ void CoreManager::init()
|
||||
m_bus = make_unique<dBus::Bus>();
|
||||
|
||||
// Initialize other subsystems (e.g., logger, etc.)
|
||||
m_logger = make_unique<logger::Logger>(*m_bus);
|
||||
m_requirementManager = make_unique<requirementManager::RequirementManager>(*m_bus);
|
||||
m_logger = make_unique<logger::Logger>(*m_bus);
|
||||
m_projectManager = make_unique<project::ProjectManager>(*m_bus);
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
/* Release resources used by the core manager (e.g., clean up the bus, etc.) */
|
||||
void CoreManager::release()
|
||||
{
|
||||
// Clean up other subsystems (e.g., logger, etc.)
|
||||
m_requirementManager.reset();
|
||||
m_projectManager.reset();
|
||||
m_logger.reset();
|
||||
|
||||
// Clean up the application bus
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "logger/logger.h"
|
||||
#include "requirementManager/requirementManager.h"
|
||||
#include "projectManager/projectManager.h"
|
||||
|
||||
#include <dBus/dBus.h>
|
||||
#include <memory>
|
||||
@@ -24,8 +24,8 @@ class CoreManager
|
||||
protected:
|
||||
std::unique_ptr<dBus::Bus> m_bus; // Application data bus
|
||||
|
||||
std::unique_ptr<logger::Logger> m_logger; // Application logger system
|
||||
std::unique_ptr<requirementManager::RequirementManager> m_requirementManager; // Requirement manager system
|
||||
std::unique_ptr<logger::Logger> m_logger; // Application logger system
|
||||
std::unique_ptr<project::ProjectManager> m_projectManager; // Requirement manager system
|
||||
|
||||
private:
|
||||
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
|
||||
{
|
||||
static constexpr auto LOG_PRINT_INTERVAL = std::chrono::seconds{ 1 };
|
||||
static constexpr auto LOG_PRINT_INTERVAL = std::chrono::milliseconds{ 500 };
|
||||
|
||||
public:
|
||||
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
|
||||
Reference in New Issue
Block a user