3 #include <Core/Utils/Singleton.hpp>
4 #include <Core/Utils/StdUtils.hpp>
5 #include <Engine/RaEngine.hpp>
6 #include <Engine/Scene/Component.hpp>
12 #include <unordered_map>
48 using Getter = std::function<
const T*( void )>;
50 using Setter = std::function<void(
const T* )>;
60 struct CallbackTypes<std::shared_ptr<T>> {
61 using Getter = std::function<std::shared_ptr<const T>(
void )>;
62 using Setter = std::function<void( std::shared_ptr<const T> )>;
63 using ReadWrite = std::function<std::shared_ptr<T>(
void )>;
65 static const std::shared_ptr<const T>& getHelper(
const Getter& g ) {
return ( g() ); }
70 using Key = std::pair<std::string, std::type_index>;
79 inline std::size_t operator()(
const Key& k )
const;
83 struct CallbackBase {};
85 struct GetterCallback :
public CallbackBase {
86 typename CallbackTypes<T>::Getter m_cb;
89 struct SetterCallback :
public CallbackBase {
90 typename CallbackTypes<T>::Setter m_cb;
93 struct RwCallback :
public CallbackBase {
94 typename CallbackTypes<T>::ReadWrite m_cb;
98 using CallbackMap = std::unordered_map<Key, std::unique_ptr<CallbackBase>, HashFunc>;
101 ComponentMessenger() =
default;
107 template <
typename ReturnType>
108 inline typename CallbackTypes<ReturnType>::Getter getterCallback(
const Entity* entity,
109 const std::string&
id );
111 template <
typename ReturnType>
112 inline typename CallbackTypes<ReturnType>::ReadWrite rwCallback(
const Entity* entity,
113 const std::string&
id );
115 template <
typename ReturnType>
116 inline typename CallbackTypes<ReturnType>::Setter setterCallback(
const Entity* entity,
117 const std::string&
id );
126 template <
typename ReturnType>
127 inline const ReturnType& get(
const Entity* entity,
const std::string&
id );
133 template <
typename ReturnType>
134 inline bool canGet(
const Entity* entity,
const std::string&
id );
136 template <
typename ReturnType>
137 inline bool canSet(
const Entity* entity,
const std::string&
id );
139 template <
typename ReturnType>
140 inline bool canRw(
const Entity* entity,
const std::string&
id );
146 template <
typename ReturnType>
147 inline void registerOutput(
const Entity* entity,
149 const std::string&
id,
150 const typename CallbackTypes<ReturnType>::Getter& cb );
152 template <
typename ReturnType>
153 inline void registerReadWrite(
const Entity* entity,
155 const std::string&
id,
156 const typename CallbackTypes<ReturnType>::ReadWrite& cb );
158 template <
typename ReturnType>
159 inline void registerInput(
const Entity* entity,
161 const std::string&
id,
162 const typename CallbackTypes<ReturnType>::Setter& cb );
165 void unregisterAll(
const Entity* entity, Component* component );
168 using EntityMap = std::unordered_map<const Entity*, CallbackMap>;
169 EntityMap m_entityGetLists;
170 EntityMap m_entitySetLists;
171 EntityMap m_entityRwLists;
174 inline std::size_t ComponentMessenger::HashFunc::operator()(
const Key& k )
const {
175 return Core::Utils::hash( k );
178 template <
typename ReturnType>
180 ComponentMessenger::getterCallback(
const Entity* entity,
const std::string&
id ) {
181 CORE_ASSERT( canGet<ReturnType>( entity,
id ),
"Unregistered callback" );
182 return static_cast<GetterCallback<ReturnType>*
>(
183 m_entityGetLists[entity][Key(
id, std::type_index(
typeid( ReturnType ) ) )].get() )
187 template <
typename ReturnType>
189 ComponentMessenger::rwCallback(
const Entity* entity,
const std::string&
id ) {
190 CORE_ASSERT( canRw<ReturnType>( entity,
id ),
"Unregistered callback" );
191 return static_cast<RwCallback<ReturnType>*
>(
192 m_entityRwLists[entity][Key(
id, std::type_index(
typeid( ReturnType ) ) )].get() )
196 template <
typename ReturnType>
198 ComponentMessenger::setterCallback(
const Entity* entity,
const std::string&
id ) {
199 CORE_ASSERT( canSet<ReturnType>( entity,
id ),
"Unregistered callback" );
200 return static_cast<SetterCallback<ReturnType>*
>(
201 m_entitySetLists[entity][Key(
id, std::type_index(
typeid( ReturnType ) ) )].get() )
205 template <
typename ReturnType>
206 inline const ReturnType& ComponentMessenger::get(
const Entity* entity,
const std::string&
id ) {
217 template <
typename ReturnType>
218 inline bool ComponentMessenger::canGet(
const Entity* entity,
const std::string&
id ) {
220 const auto& entityListPos = m_entityGetLists.find( entity );
221 if ( entityListPos == m_entityGetLists.end() )
224 Key key(
id, std::type_index(
typeid( ReturnType ) ) );
225 const CallbackMap& entityList = entityListPos->second;
229 const auto& callbackEntry = entityList.find( key );
230 const bool found = ( callbackEntry != entityList.end() );
234 template <
typename ReturnType>
235 inline bool ComponentMessenger::canSet(
const Entity* entity,
const std::string&
id ) {
237 auto entityListPos = m_entitySetLists.find( entity );
238 if ( entityListPos == m_entitySetLists.end() )
241 Key key(
id, std::type_index(
typeid( ReturnType ) ) );
242 const CallbackMap& entityList = entityListPos->second;
246 const auto& callbackEntry = entityList.find( key );
247 const bool found = ( callbackEntry != entityList.end() );
251 template <
typename ReturnType>
252 inline bool ComponentMessenger::canRw(
const Entity* entity,
const std::string&
id ) {
254 const auto& entityListPos = m_entityRwLists.find( entity );
255 if ( entityListPos == m_entityRwLists.end() )
258 Key key(
id, std::type_index(
typeid( ReturnType ) ) );
259 const CallbackMap& entityList = entityListPos->second;
263 const auto& callbackEntry = entityList.find( key );
264 const bool found = ( callbackEntry != entityList.end() );
268 template <
typename ReturnType>
270 ComponentMessenger::registerOutput(
const Entity* entity,
272 const std::string&
id,
273 const typename CallbackTypes<ReturnType>::Getter& cb ) {
274 CORE_ASSERT( entity && comp->getEntity() == entity,
"Component not added to entity" );
277 CallbackMap& entityList = m_entityGetLists[entity];
279 Key key(
id, std::type_index(
typeid( ReturnType ) ) );
280 CORE_ASSERT( entityList.find( key ) == entityList.end(),
281 "Output function already registered for " +
id );
283 GetterCallback<ReturnType>* getter =
new GetterCallback<ReturnType>();
285 entityList[key].reset( getter );
288 template <
typename ReturnType>
290 ComponentMessenger::registerReadWrite(
const Entity* entity,
292 const std::string&
id,
293 const typename CallbackTypes<ReturnType>::ReadWrite& cb ) {
294 CORE_ASSERT( entity && comp->getEntity() == entity,
"Component not added to entity" );
297 CallbackMap& entityList = m_entityRwLists[entity];
299 Key key(
id, std::type_index(
typeid( ReturnType ) ) );
300 CORE_ASSERT( entityList.find( key ) == entityList.end(),
301 "Rw function already registered for " +
id );
303 RwCallback<ReturnType>* rw =
new RwCallback<ReturnType>();
305 entityList[key].reset( rw );
308 template <
typename ReturnType>
310 ComponentMessenger::registerInput(
const Entity* entity,
312 const std::string&
id,
313 const typename CallbackTypes<ReturnType>::Setter& cb ) {
314 CORE_ASSERT( entity && comp->getEntity() == entity,
"Component not added to entity" );
317 CallbackMap& entityList = m_entitySetLists[entity];
319 Key key(
id, std::type_index(
typeid( ReturnType ) ) );
320 CORE_ASSERT( entityList.find( key ) == entityList.end(),
321 "Input function already registered for " +
id );
323 SetterCallback<ReturnType>* setter =
new SetterCallback<ReturnType>();
325 entityList[key].reset( setter );
This describes the function pointers accepted for each type.
static const T & getHelper(const Getter &g)
Calls the callback and retrieves the object.
std::function< void(const T *)> Setter
Function pointer for a setter function.
std::function< T *(void)> ReadWrite
Function pointer for a read/write getter.
std::function< const T *(void)> Getter
Function pointer for a getter function.