View difference between Paste ID: 0Z4phQnk and 1LgnkyDq
SHOW: | | - or go back to the newest paste.
1
#ifndef ENGINE_SYSTEM_H
2
#define ENGINE_SYSTEM_H
3
4
#include <tuple>
5-
#include <util/traits.h>
5+
#include "traits.h"
6
#include <assert.h>
7
8
#define MACRO_DECLARE_PROVIDER_ACCESS(provider)                                       \
9
template <typename T>                                                                 \
10
inline                                                                                \
11
typename std::enable_if< has_type< T*, provider::SubSystemPtrs >::value, T* >::type   \
12
Get();                                                                                \
13
                                                                                      \
14
template <typename T>                                                                 \
15
inline                                                                                \
16
typename std::enable_if< has_type< T*, provider::SubSystemPtrs >::value, bool >::type \
17
Set(T* ptr);
18
19
#define MACRO_DEFINE_PROVIDER_ACCESS(provider)                                        \
20
template <typename T>                                                                 \
21
inline                                                                                \
22
typename std::enable_if< has_type< T*, provider::SubSystemPtrs >::value, T* >::type   \
23
Get()                                                                                 \
24
{                                                                                     \
25
  if(provider::s_pInstance)                                                           \
26
    return std::get<T*>(provider::s_pInstance->m_SubSystems);                         \
27
  return nullptr;                                                                     \
28
}                                                                                     \
29
                                                                                      \
30
template <typename T>                                                                 \
31
inline                                                                                \
32
typename std::enable_if< has_type< T*, provider::SubSystemPtrs >::value, bool >::type \
33
Set(T *ptr)                                                                           \
34
{                                                                                     \
35
  if(provider::s_pInstance)                                                           \
36
  {                                                                                   \
37
    std::get<T*>(provider::s_pInstance->m_SubSystems) = ptr;                          \
38
    return true;                                                                      \
39
  }                                                                                   \
40
  return false;                                                                       \
41
}
42
43
template <typename ...Ts>
44
class Provider {
45
private:
46
  using thisType = Provider<Ts...>;
47
  using SubSystemPtrs = std::tuple<Ts*...>;
48
49
  template <typename T>
50
  friend
51
  typename std::enable_if< has_type< T*, thisType::SubSystemPtrs >::value, T* >::type
52
  Get();
53
54
  template <typename T>
55
  friend
56
  typename std::enable_if< has_type< T*, thisType::SubSystemPtrs >::value, bool >::type
57
  Set(T* ptr);
58
59
  static Provider *s_pInstance;
60
  SubSystemPtrs m_SubSystems;
61
62
public:
63
  Provider() { s_pInstance = this; }
64
  ~Provider() { if(s_pInstance == this); s_pInstance = nullptr; }
65
66
  template <typename T>
67
  T* Get();
68
69
  template <typename T>
70
  void Register(T* service);
71
72
  template <typename T>
73
  void UnRegister(T* service = nullptr);
74
75
  // Switching on multiple Providers was not yet thought about
76
  // void MakeCurrent();
77
};
78
79
template <typename ...Ts>
80
Provider<Ts...> *Provider<Ts...>::s_pInstance = nullptr;
81
82
template <typename ...Ts>
83
template <typename T>
84
T* Provider<Ts...>::Get()
85
{
86
  return std::get<T*>(m_SubSystems);
87
}
88
89
template <typename ...Ts>
90
template <typename T>
91
void Provider<Ts...>::Register(T* service)
92
{
93
  std::get<T*>(m_SubSystems) = service;
94
}
95
96
template <typename ...Ts>
97
template <typename T>
98
void Provider<Ts...>::UnRegister(T* service)
99
{
100
  std::get<T*>(m_SubSystems) = nullptr;
101
}
102
103
#endif