Consolix
Loading...
Searching...
No Matches
ServiceLocator.hpp
Go to the documentation of this file.
1#pragma once
2#ifndef _CONSOLIX_SERVICE_LOCATOR_HPP_INCLUDED
3#define _CONSOLIX_SERVICE_LOCATOR_HPP_INCLUDED
4
8
9#if CONSOLIX_USE_LOGIT == 1
10#include <LogIt.hpp>
11#endif
12
13#include "std_compat.hpp"
14
15#include <unordered_map>
16#include <functional>
17#include <memory>
18#include <typeindex>
19#include <stdexcept>
20#include <mutex>
21
22namespace consolix {
23
30 public:
31
35 static ServiceLocator* instance = new ServiceLocator();
36 return *instance;
37 }
38
43 template <typename T>
44 void register_service(std::function<std::shared_ptr<T>()> creator) {
45 std::shared_ptr<T> service = creator();
46
47 std::unique_lock<compat::shared_mutex> lock(m_mutex);
48 const auto type = std::type_index(typeid(T));
49 if (m_services.find(type) != m_services.end()) {
50# if CONSOLIX_USE_LOGIT == 1
51 LOGIT_PRINT_ERROR("Service already registered: ", std::string(typeid(T).name()));
52# endif
53 throw std::runtime_error("Service already registered: " + std::string(typeid(T).name()));
54 }
55 m_services[type] = std::move(service);
56 }
57
61 template <typename T>
63 std::unique_lock<compat::shared_mutex> lock(m_mutex);
64 const auto type = std::type_index(typeid(T));
65 if (m_services.find(type) != m_services.end()) {
66# if CONSOLIX_USE_LOGIT == 1
67 LOGIT_PRINT_ERROR("Service already registered: ", std::string(typeid(T).name()));
68# endif
69 throw std::runtime_error("Service already registered: " + std::string(typeid(T).name()));
70 }
71 m_services[type] = std::make_shared<T>();
72 }
73
78 template <typename T>
81 const auto type = std::type_index(typeid(T));
82 auto it = m_services.find(type);
83 if (it == m_services.end()) {
84# if CONSOLIX_USE_LOGIT == 1
85 LOGIT_PRINT_ERROR("Service not registered: ", std::string(typeid(T).name()));
86# endif
87 throw std::runtime_error("Service not registered: " + std::string(typeid(T).name()));
88 }
89 return *std::static_pointer_cast<T>(it->second);
90 }
91
95 template <typename T>
96 bool has_service() {
98 const auto type_id = std::type_index(typeid(T));
99 return m_services.find(type_id) != m_services.end();
100 }
101
103 void clear_all() {
104 std::unique_lock<compat::shared_mutex> lock(m_mutex);
105 m_services.clear();
106 }
107
108 private:
109 std::unordered_map<
110 std::type_index,
111 std::shared_ptr<void>> m_services;
113
114 ServiceLocator() = default;
115 ~ServiceLocator() = default;
116
117 // Delete copy and move constructors and assignment operators.
122 }; // ServiceLocator
123
124} // namespace consolix
125
126#endif // _CONSOLIX_SERVICE_LOCATOR_HPP_INCLUDED
static ServiceLocator & get_instance()
Retrieves the singleton instance of the ServiceLocator.
void clear_all()
Clears all registered resources.
ServiceLocator(ServiceLocator &&)=delete
void register_service(std::function< std::shared_ptr< T >()> creator)
Registers a resource or service.
std::unordered_map< std::type_index, std::shared_ptr< void > > m_services
Registered services.
bool has_service()
Checks if a resource is registered.
compat::shared_mutex m_mutex
Mutex for thread-safe access.
ServiceLocator & operator=(const ServiceLocator &)=delete
T & get_service()
Retrieves a resource from the locator.
void register_service()
Registers a resource with default construction.
ServiceLocator(const ServiceLocator &)=delete
ServiceLocator & operator=(ServiceLocator &&)=delete
std::unique_lock< Mutex > shared_lock
< Utility modules and helpers.
Compatibility helpers for standard library features used across Consolix.