Bicameral Engine
GPU-resident engine for a magic-research open-world game
Loading...
Searching...
No Matches
singleton.h
Go to the documentation of this file.
1// singleton.h — mozc 式のシングルトン(ユーザー提供の singleton_template を規約 docs/style.md に合わせたもの)。
2//
3// 生成は最初の GetInstance()、破棄は SingletonFinalizer::Finalize() でまとめて行う(main の最後で 1 回呼ぶ)。
4// 元の実装から変えた点:
5// - 破棄は「作った順の逆」。後から作られた物は先に作られた物に依存しうる(ログを使う物より先にログを壊さない)
6// - Finalize() を 2 回呼んでも二重に delete しない
7// - FinalizeClass<T>() の後に GetInstance() を呼ぶと作り直す(元は call_once 済みで nullptr を返していた)
8//
9// 注意(docs/style.md「分け方・つなぎ方」): グローバルな状態は避ける。使うのはログのように本当に 1 つしか要らず、
10// どこからでも呼ぶものだけ。
11#pragma once
12
13#include <atomic>
14#include <cassert>
15#include <mutex>
16#include <typeindex>
17#include <vector>
18
19namespace bicameral {
20
22 public:
23 using FinalizerFunc = void (*)();
24
25 // 作られたすべてのインスタンスを、作った順の逆に破棄する
26 static void Finalize();
27
28 // T のインスタンスだけを破棄する。作られていなければ何もしない
29 template <typename T>
30 static void FinalizeClass() {
31 FinalizeType(typeid(T));
32 }
33
34 private:
35 template <typename T>
36 friend class Singleton;
37
38 struct Entry {
39 std::type_index type;
41 };
42
43 static void AddFinalizer(std::type_index type, FinalizerFunc finalize);
44 static void FinalizeType(std::type_index type);
45
46 static std::mutex s_mutex;
47 static std::vector<Entry> s_finalizers; // 作った順
48 };
49
50 template <typename T>
51 class Singleton final {
52 public:
53 static T& GetInstance() {
54 // 作成済みなら鍵を取らずに返す(ログのように頻繁に呼ばれるため)
55 if (T* instance = s_instance.load(std::memory_order_acquire))
56 return *instance;
57
58 std::scoped_lock lock(s_mutex);
59 if (s_instance.load(std::memory_order_relaxed) == nullptr)
60 Create();
61
62 return *s_instance.load(std::memory_order_relaxed);
63 }
64
65 private:
66 static void Create() {
67 s_instance.store(new T, std::memory_order_release);
69 }
70
71 static void Destroy() {
72 std::scoped_lock lock(s_mutex);
73 delete s_instance.exchange(nullptr, std::memory_order_acq_rel);
74 }
75
76 static inline std::mutex s_mutex;
77 static inline std::atomic<T*> s_instance = nullptr;
78 };
79
80} // namespace bicameral
static std::mutex s_mutex
Definition singleton.h:46
static std::vector< Entry > s_finalizers
Definition singleton.h:47
static void FinalizeType(std::type_index type)
Definition singleton.cpp:39
static void AddFinalizer(std::type_index type, FinalizerFunc finalize)
Definition singleton.cpp:20
static std::mutex s_mutex
Definition singleton.h:76
static T & GetInstance()
Definition singleton.h:53
static std::atomic< T * > s_instance
Definition singleton.h:77
static void Destroy()
Definition singleton.h:71
static void Create()
Definition singleton.h:66