ArcdpsExtension
 
Loading...
Searching...
No Matches
Singleton.h
Go to the documentation of this file.
1// copied from MIT-Licensed project `GW2Common`
2// https://github.com/Friendly0Fire/GW2Common
3
4#pragma once
5
6#include <concepts>
7#include <functional>
8#include <memory>
9#include <stack>
10#include <stdexcept>
11#include <type_traits>
12
13namespace ArcdpsExtension {
19 public:
20 virtual ~BaseSingleton() = default;
21
22 protected:
23 static BaseSingleton* Store(std::unique_ptr<BaseSingleton>&& ptr);
24 static void Clear(BaseSingleton* ptr);
25 };
26
28 public:
29 SingletonManager() = default;
30 // Call this when shutting down `mod_release`
31 void Shutdown() {
32 while (!singletons_.empty())
33 singletons_.pop();
34 }
35
36 [[nodiscard]] bool Empty() const {
37 return singletons_.empty();
38 }
39
40 private:
41 std::stack<std::unique_ptr<BaseSingleton>> singletons_;
42
43 friend class BaseSingleton;
44 };
46
47 template<typename T>
48 class Singleton : public BaseSingleton {
49 public:
50 template<typename T2 = T>
51 requires std::derived_from<T2, T>
52 static T2& instance() {
53 if (!init_) {
54 if constexpr (std::is_default_constructible_v<T2>) {
55 init_ = true;
56 instance_ = (T*) Store(std::make_unique<T2>());
57 } else
58 throw std::logic_error("Singleton is not default-constructible but was not explicitly initialized before access.");
59 }
60
61 return *(T2*) instance_;
62 }
63
64 template<typename T2 = T, typename... Args>
65 requires std::derived_from<T2, T>
66 static T2& init(Args&&... args) {
67 init_ = true;
68 instance_ = (T*) Store(std::make_unique<T2>(std::forward<Args>(args)...));
69 return *(T2*) instance_;
70 }
71
72 template<typename T2>
73 requires std::derived_from<T2, T>
74 static void f(std::function<void(T2&)> action) {
75 if (instance_)
76 action(*(T2*) instance_);
77 }
78
79 static void f(std::function<void(T&)> action) {
80 if (instance_)
81 action(*instance_);
82 }
83
84 static void reset() {
85 if (init_)
86 Clear(instance_);
87 }
88
89 ~Singleton() override {
90 instance_ = nullptr;
91 init_ = false;
92 }
93
94 private:
95 inline static bool init_ = false;
96 inline static T* instance_ = nullptr;
97 };
98} // namespace ArcdpsExtension
Definition Singleton.h:18
virtual ~BaseSingleton()=default
static void Clear(BaseSingleton *ptr)
Definition Singleton.cpp:10
static BaseSingleton * Store(std::unique_ptr< BaseSingleton > &&ptr)
Definition Singleton.cpp:5
Definition Singleton.h:27
void Shutdown()
Definition Singleton.h:31
bool Empty() const
Definition Singleton.h:36
Definition Singleton.h:48
static void f(std::function< void(T2 &)> action)
Definition Singleton.h:74
static void reset()
Definition Singleton.h:84
static T2 & init(Args &&... args)
Definition Singleton.h:66
static void f(std::function< void(T &)> action)
Definition Singleton.h:79
static T2 & instance()
Definition Singleton.h:52
~Singleton() override
Definition Singleton.h:89
Definition ArcdpsExtension.h:10
SingletonManager g_singletonManagerInstance
Definition Singleton.cpp:3