diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj
index d7f333c..7ae72bd 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj
@@ -102,7 +102,7 @@
true
_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
true
- $(ProjectDir)models;$(ProjectDir)controllers;$(ProjectDir)factories;$(ProjectDir)views;$(ProjectDir)services;$(ProjectDir)utilities;$(ProjectDir)core\patterns;$(ProjectDir)datastores;$(ProjectDir)core\sharedmemory;%(AdditionalIncludeDirectories)
+ $(ProjectDir)models;$(ProjectDir)controllers;$(ProjectDir)factories;$(ProjectDir)views;$(ProjectDir)services;$(ProjectDir)utilities;$(ProjectDir)core\patterns;$(ProjectDir)datastores;$(ProjectDir)core\sharedmemory;$(ProjectDir)core\events;%(AdditionalIncludeDirectories)
Console
@@ -117,7 +117,7 @@
true
NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
true
- $(ProjectDir)models;$(ProjectDir)controllers;$(ProjectDir)factories;$(ProjectDir)views;$(ProjectDir)services;$(ProjectDir)utilities;$(ProjectDir)core\patterns;$(ProjectDir)datastores;$(ProjectDir)core\sharedmemory;%(AdditionalIncludeDirectories)
+ $(ProjectDir)models;$(ProjectDir)controllers;$(ProjectDir)factories;$(ProjectDir)views;$(ProjectDir)services;$(ProjectDir)utilities;$(ProjectDir)core\patterns;$(ProjectDir)datastores;$(ProjectDir)core\sharedmemory;$(ProjectDir)core\events;%(AdditionalIncludeDirectories)
Console
@@ -126,6 +126,7 @@
+
@@ -153,6 +154,7 @@
+
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj.filters b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj.filters
index d354bcb..714382b 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj.filters
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj.filters
@@ -70,6 +70,12 @@
{0769afb6-f57d-4ae3-a1cf-ceca6e606af0}
+
+ {85029bdb-6941-41dc-a3a7-9e5841671d8c}
+
+
+ {1050aca7-6f2c-4ccb-a446-db9c898c3599}
+
@@ -147,6 +153,9 @@
Source Files\Core\SharedMemory
+
+ Source Files\Core\Events
+
@@ -275,5 +284,8 @@
Header Files\Core\SharedMemory
+
+ Header Files\Core\Events
+
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/core/events/EventManager.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/core/events/EventManager.cpp
new file mode 100644
index 0000000..568a0e6
--- /dev/null
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/core/events/EventManager.cpp
@@ -0,0 +1,225 @@
+/*
+File: EventManager.cpp
+Description: Implementation file containing the method definitions of the
+ EventManager class, including listener management and
+ interprocess event publishing.
+Author: Trenser
+Date:15-Jun-2026
+*/
+
+#include
+#include
+#include "EventManager.h"
+
+namespace
+{
+ const std::string USER_DISABLED_EVENT = "userDisabled_";
+
+ const std::string NOTIFICATION_AVAILABLE_EVENT = "notificationAvailable_";
+}
+
+/*
+Function: EventManager
+Description: Constructs an EventManager instance with default values.
+Parameter: None
+Return type: None
+*/
+EventManager::EventManager()
+ :
+ m_userDisabledEvent(NULL),
+ m_notificationAvailableEvent(NULL),
+ m_shutdownEvent(NULL),
+ m_running(false) {}
+
+/*
+Function: ~EventManager
+Description: Destroys the EventManager and performs final cleanup.
+Parameter: None
+Return type: None
+*/
+EventManager::~EventManager()
+{
+ shutdown();
+ if (m_listenerThread.joinable())
+ {
+ m_listenerThread.join();
+ }
+}
+
+/*
+Function: initialize
+Description: Creates the user-specific events and starts the listener
+ thread.
+Parameter: const std::string& userId - unique identifier of the user
+ std::function userDisabledCallback - callback for
+ user disable events
+ std::function notificationCallback - callback for
+ notification events
+Return type: bool - true if initialization succeeds, false otherwise
+*/
+bool EventManager::initialize(const std::string& userId, std::function userDisabledCallback, std::function notificationCallback)
+{
+ if (m_running.load())
+ {
+ return false;
+ }
+ m_userDisabledCallback = userDisabledCallback;
+ m_notificationCallback = notificationCallback;
+ m_userDisabledEvent = CreateEventA(NULL, FALSE, FALSE, (USER_DISABLED_EVENT + userId).c_str());
+ if (!m_userDisabledEvent)
+ {
+ return false;
+ }
+ if (GetLastError() == ERROR_ALREADY_EXISTS)
+ {
+ CloseHandle(m_userDisabledEvent);
+ m_userDisabledEvent = NULL;
+ throw std::runtime_error("Only one session allowed per user.");
+ }
+ m_notificationAvailableEvent = CreateEventA(NULL, FALSE, FALSE, (NOTIFICATION_AVAILABLE_EVENT + userId).c_str());
+ if (!m_notificationAvailableEvent)
+ {
+ CloseHandle(m_userDisabledEvent);
+ m_userDisabledEvent = NULL;
+ return false;
+ }
+ m_shutdownEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
+ if (!m_shutdownEvent)
+ {
+ CloseHandle(m_userDisabledEvent);
+ CloseHandle(m_notificationAvailableEvent);
+ m_userDisabledEvent = NULL;
+ m_notificationAvailableEvent = NULL;
+ return false;
+ }
+ m_running.store(true);
+ m_listenerThread = std::thread(&EventManager::run, this);
+ return true;
+}
+
+/*
+Function: shutdown
+Description: Stops the listener thread and releases event resources.
+Parameter: None
+Return type: None
+*/
+void EventManager::shutdown()
+{
+ if (!m_running.load())
+ {
+ return;
+ }
+ m_running.store(false);
+ if (m_shutdownEvent)
+ {
+ SetEvent(m_shutdownEvent);
+ }
+ if (m_listenerThread.joinable())
+ {
+ if (std::this_thread::get_id() != m_listenerThread.get_id())
+ {
+ m_listenerThread.join();
+ }
+ }
+ if (m_userDisabledEvent)
+ {
+ CloseHandle(m_userDisabledEvent);
+ m_userDisabledEvent = NULL;
+ }
+ if (m_notificationAvailableEvent)
+ {
+ CloseHandle(m_notificationAvailableEvent);
+ m_notificationAvailableEvent = NULL;
+ }
+ if (m_shutdownEvent)
+ {
+ CloseHandle(m_shutdownEvent);
+ m_shutdownEvent = NULL;
+ }
+}
+
+/*
+Function: run
+Description: Waits for and dispatches user-related events.
+Parameter: None
+Return type: void
+*/
+void EventManager::run()
+{
+ HANDLE handles[3];
+ handles[0] = m_userDisabledEvent;
+ handles[1] = m_notificationAvailableEvent;
+ handles[2] = m_shutdownEvent;
+ while (m_running.load())
+ {
+ DWORD result = WaitForMultipleObjects(3, handles, FALSE, INFINITE);
+ switch (result)
+ {
+ case WAIT_OBJECT_0:
+ try
+ {
+ if (m_userDisabledCallback)
+ {
+ m_userDisabledCallback();
+ }
+ }
+ catch (const std::exception& exception)
+ {
+ std::cout << exception.what() << std::endl;
+ }
+ break;
+ case WAIT_OBJECT_0 + 1:
+ try
+ {
+ if (m_notificationCallback)
+ {
+ m_notificationCallback();
+ }
+ }
+ catch (const std::exception& exception)
+ {
+ std::cout << exception.what() << std::endl;
+ }
+ break;
+ case WAIT_OBJECT_0 + 2:
+ return;
+ default:
+ break;
+ }
+ }
+}
+
+/*
+Function: sendUserDisabledEvent
+Description: Publishes a user disabled event for a specific user.
+Parameter: const std::string& userId - target user identifier
+Return type: void
+*/
+void EventManager::sendUserDisabledEvent(const std::string& userId)
+{
+ HANDLE eventHandle = CreateEventA(NULL, FALSE, FALSE, (USER_DISABLED_EVENT + userId).c_str());
+ if (!eventHandle)
+ {
+ return;
+ }
+ SetEvent(eventHandle);
+ CloseHandle(eventHandle);
+}
+
+/*
+Function: sendNotificationAvailableEvent
+Description: Publishes a notification available event for a specific
+ user.
+Parameter: const std::string& userId - target user identifier
+Return type: void
+*/
+void EventManager::sendNotificationAvailableEvent(const std::string& userId)
+{
+ HANDLE eventHandle = CreateEventA(NULL, FALSE, FALSE, (NOTIFICATION_AVAILABLE_EVENT + userId).c_str());
+ if (!eventHandle)
+ {
+ return;
+ }
+ SetEvent(eventHandle);
+ CloseHandle(eventHandle);
+}
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/core/events/EventManager.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/core/events/EventManager.h
new file mode 100644
index 0000000..01de6c4
--- /dev/null
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/core/events/EventManager.h
@@ -0,0 +1,37 @@
+/*
+File: EventManager.h
+Description: Header file declaring the EventManager class, which manages
+ user-specific interprocess events for user disable and
+ notification availability updates.
+Author: Trenser
+Date:15-Jun-2026
+*/
+
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
+
+class EventManager
+{
+private:
+ HANDLE m_userDisabledEvent;
+ HANDLE m_notificationAvailableEvent;
+ HANDLE m_shutdownEvent;
+ std::atomic m_running;
+ std::thread m_listenerThread;
+ std::function m_userDisabledCallback;
+ std::function m_notificationCallback;
+ void run();
+
+public:
+ EventManager();
+ ~EventManager();
+ bool initialize(const std::string& userId, std::function userDisabledCallback, std::function notificationCallback);
+ void shutdown();
+ static void sendUserDisabledEvent(const std::string& userId);
+ static void sendNotificationAvailableEvent(const std::string& userId);
+};
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/AuthenticationManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/AuthenticationManagementService.cpp
index 71d66b6..ac5682d 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/AuthenticationManagementService.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/AuthenticationManagementService.cpp
@@ -8,12 +8,14 @@ Date:19-May-2026
*/
#include
+#include
#include "AuthenticationManagementService.h"
#include "User.h"
#include "Utility.h"
#include "DataStoreLockGuard.h"
User* AuthenticationManagementService::m_authenticatedUser = nullptr;
+EventManager AuthenticationManagementService::m_eventManager;
/*
Function: login
@@ -37,6 +39,16 @@ bool AuthenticationManagementService::login(const std::string& username, const s
if (password == user->getPassword())
{
m_authenticatedUser = user;
+ m_eventManager.initialize(
+ user->getId(),
+ []()
+ {
+ std::cout << "USER_DISABLED event received" << std::endl;
+ },
+ []()
+ {
+ std::cout << "NOTIFICATION_AVAILABLE event received" << std::endl;
+ });
return true;
}
return false;
@@ -65,6 +77,7 @@ Return type: void
*/
void AuthenticationManagementService::logout()
{
+ m_eventManager.shutdown();
m_authenticatedUser = nullptr;
}
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/AuthenticationManagementService.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/AuthenticationManagementService.h
index 47266a1..e1cb251 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/AuthenticationManagementService.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/AuthenticationManagementService.h
@@ -9,6 +9,7 @@ Date:19-May-2026
#pragma once
#include
+#include "EventManager.h"
#include "DataStore.h"
class User;
@@ -17,6 +18,7 @@ class AuthenticationManagementService
{
private:
static User* m_authenticatedUser;
+ static EventManager m_eventManager;
DataStore& m_dataStore;
public:
AuthenticationManagementService() : m_dataStore(DataStore::getInstance()) {}
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.cpp
index 8e17739..a007ac1 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.cpp
@@ -19,6 +19,7 @@ Date: 22-May-2026
#include "Utility.h"
#include "Vector.h"
#include "DataStoreLockGuard.h"
+#include "EventManager.h"
util::Map InventoryManagementService::m_observers{};
@@ -281,5 +282,6 @@ void InventoryManagementService::sendNotification(User* user, const std::string&
auto& trackedNotificationsMap = m_dataStore.getNotifications();
trackedNotificationsMap.insert(notification->getId(), util::createNewRecord(notification));
m_dataStore.saveNotifications();
+ EventManager::sendNotificationAvailableEvent(user->getId());
}
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp
index dc42a5b..09bf1da 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp
@@ -22,6 +22,7 @@ Date: 20-May-2026
#include "User.h"
#include "Utility.h"
#include "DataStoreLockGuard.h"
+#include "EventManager.h"
util::Map PaymentManagementService::m_observers{};
@@ -109,6 +110,7 @@ void PaymentManagementService::sendNotification(User* user, const std::string& t
auto& trackedNotificationsMap = m_dataStore.getNotifications();
trackedNotificationsMap.insert(notification->getId(), util::createNewRecord(notification));
m_dataStore.saveNotifications();
+ EventManager::sendNotificationAvailableEvent(user->getId());
}
/*
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp
index ed59380..cf438d0 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp
@@ -27,6 +27,7 @@ Date:19-May-2026
#include "DataStoreLockGuard.h"
#include "Utility.h"
#include "DataStoreLockGuard.h"
+#include "EventManager.h"
/*
Function: purchaseService
@@ -199,6 +200,7 @@ void ServiceManagementService::sendNotification(User* user, const std::string& t
auto& trackedNotificationsMap = m_dataStore.getNotifications();
trackedNotificationsMap.insert(notification->getId(), util::createNewRecord(notification));
m_dataStore.saveNotifications();
+ EventManager::sendNotificationAvailableEvent(user->getId());
}
/*
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.cpp
index e923e1c..ab85936 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.cpp
@@ -22,6 +22,7 @@ Date:19-May-2026
#include "Utility.h"
#include "TrackedRecord.h"
#include "DataStoreLockGuard.h"
+#include "EventManager.h"
/*
Function: ensureAdminExists
@@ -267,30 +268,38 @@ void UserManagementService::removeUser(const std::string& userID)
InventoryManagementService inventoryManagementService;
PaymentManagementService paymentManagementService;
ServiceManagementService serviceManagementService;
- DataStoreLockGuard lock(m_dataStore);
- auto& trackedUsersMap = m_dataStore.getUsers();
- int index = trackedUsersMap.find(userID);
- if (index != -1)
+ std::string removedUserID;
{
- User* user = trackedUsersMap.getValueAt(index).data;
- if (user != nullptr)
+ DataStoreLockGuard lock(m_dataStore);
+ auto& trackedUsersMap = m_dataStore.getUsers();
+ int index = trackedUsersMap.find(userID);
+ if (index != -1)
{
- if (user->getUserType() == util::UserType::CUSTOMER)
+ User* user = trackedUsersMap.getValueAt(index).data;
+ if (user != nullptr)
{
- serviceManagementService.cancelCustomerServiceBookings(userID);
+ if (user->getUserType() == util::UserType::CUSTOMER)
+ {
+ serviceManagementService.cancelCustomerServiceBookings(userID);
+ }
+ if (user->getUserType() == util::UserType::TECHNICIAN)
+ {
+ serviceManagementService.cancelTechnicianJobs(userID);
+ }
+ inventoryManagementService.detach(user);
+ paymentManagementService.detach(user);
+ serviceManagementService.detach(user);
+ user->setState(util::State::INACTIVE);
+ trackedUsersMap.getValueAt(index).state = RecordState::MODIFIED;
+ removedUserID = user->getId();
+ m_dataStore.saveUsers();
}
- if (user->getUserType() == util::UserType::TECHNICIAN)
- {
- serviceManagementService.cancelTechnicianJobs(userID);
- }
- inventoryManagementService.detach(user);
- paymentManagementService.detach(user);
- serviceManagementService.detach(user);
- user->setState(util::State::INACTIVE);
- trackedUsersMap.getValueAt(index).state = RecordState::MODIFIED;
- m_dataStore.saveUsers();
}
}
+ if (!removedUserID.empty())
+ {
+ EventManager::sendUserDisabledEvent(removedUserID);
+ }
}
/*