8#ifndef ARP_USE_ARP_SYSTEM_CORE
10#include "Arp/Base/Core/AppDomain.hpp"
15#include "Arp/System/Core/Singleton.hxx"
22#ifdef ARP_PLATFORM_LINUX
30namespace Arp {
namespace System {
namespace Acf
40#ifdef ARP_PLATFORM_LINUX
48 RdLockGuard(pthread_rwlock_t* rw_lock);
51 RdLockGuard(
const RdLockGuard& arg) =
delete;
54 RdLockGuard& operator=(
const RdLockGuard& arg) =
delete;
60 pthread_rwlock_t* rw_lock;
66inline RdLockGuard::RdLockGuard(pthread_rwlock_t* rw_lockArg)
69 pthread_rwlock_rdlock(rw_lock);
72inline RdLockGuard::~RdLockGuard()
74 pthread_rwlock_unlock(rw_lock);
85 WrLockGuard(pthread_rwlock_t* rw_lock);
88 WrLockGuard(
const WrLockGuard& arg) =
delete;
91 WrLockGuard& operator=(
const WrLockGuard& arg) =
delete;
97 pthread_rwlock_t* rw_lock;
103inline WrLockGuard::WrLockGuard(pthread_rwlock_t* rw_lockArg)
104 : rw_lock(rw_lockArg)
106 pthread_rwlock_wrlock(rw_lock);
109inline WrLockGuard::~WrLockGuard()
111 pthread_rwlock_unlock(rw_lock);
126class AppDomain :
private Singleton<AppDomain>
128 friend class Singleton<AppDomain>;
131 using Strings = std::vector<String>;
132 using IApplication = Arp::System::Acf::IApplication;
135 using SingletonDisposer = void(*)(void);
136 using SingletonBase = Singleton<AppDomain>;
137 using TypeKey = std::type_index;
138 using Singletons = std::map<TypeKey, void*>;
144 AppDomain(
const AppDomain& arg) =
delete;
146 AppDomain& operator=(
const AppDomain& arg) =
delete;
153 static bool IsCreated(
void);
157 static AppDomain& GetCurrent(
void);
164 static TApp&
Create(
void);
171 static TApp&
Create(
const String& appName);
176 static void Dispose(
void);
181 static void Assign(AppDomain& other);
186 IApplication& GetApplication(
void);
190 size_t GetSingletonsCount(
void)
const;
194 Strings GetSingletonsTypeName(
void)
const;
200 template<
class TSingleton>
201 void AddSingleton(TSingleton* pSingleton);
206 template<
class TSingleton>
207 TSingleton& GetSingleton(
void);
212 template<
class TSingleton>
213 TSingleton* GetSingletonPtr(
void);
218 template<
class TSingleton>
219 bool RemoveSingleton(
void);
223 static TypeKey GetTypeKey(
void);
226 IApplication* pApplication;
227 Singletons singletons;
229#ifdef ARP_PLATFORM_LINUX
230 pthread_rwlock_t rw_lock;
238inline AppDomain::AppDomain()
239 : pApplication(nullptr)
242#ifdef ARP_PLATFORM_LINUX
243 pthread_rwlock_init(&this->rw_lock, NULL);
247inline bool AppDomain::IsCreated(
void)
249 return SingletonBase::IsCreated();
252inline AppDomain& AppDomain::GetCurrent(
void)
254 return SingletonBase::GetInstance();
258inline AppDomain::TypeKey AppDomain::GetTypeKey(
void)
260 return std::type_index(
typeid(T));
264inline TApp& AppDomain::Create(
void)
267 SingletonBase::CreateInstance();
269 TApp::CreateInstance();
271 SingletonBase::GetInstance().pApplication = &TApp::GetInstance();
273 return dynamic_cast<TApp&
>(TApp::GetInstance());
277inline TApp& AppDomain::Create(
const String& appName)
280 SingletonBase::CreateInstance();
282 TApp::CreateInstance(appName);
284 SingletonBase::GetInstance().pApplication = &TApp::GetInstance();
286 return dynamic_cast<TApp&
>(TApp::GetInstance());
289inline void AppDomain::Assign(AppDomain& other)
291 if (!SingletonBase::IsCreated())
293 SingletonBase::GetStaticInstancePtr().reset(other.GetStaticInstancePtr().get());
298inline void AppDomain::Dispose(
void)
300 TApp::DisposeInstance();
301 SingletonBase::DisposeInstance();
304inline AppDomain::IApplication& AppDomain::GetApplication(
void)
306 return *(this->pApplication);
309inline size_t AppDomain::GetSingletonsCount()
const
311 return this->singletons.size();
314template<
class TSingleton>
315inline void AppDomain::AddSingleton(TSingleton* pSingleton)
317#ifdef ARP_PLATFORM_LINUX
318 WrLockGuard lock(&this->rw_lock);
320 std::lock_guard<std::mutex> lock(this->rw_lock);
324 auto result = this->singletons.insert(make_pair(AppDomain::GetTypeKey<TSingleton>(), pSingleton));
327 throw Exception(
"AppDomain Singleton of type '{0}' has been added yet", TypeName<TSingleton>());
331template<
class TSingleton>
332inline TSingleton& AppDomain::GetSingleton()
334 TSingleton* pResult = this->GetSingletonPtr<TSingleton>();
335 if (pResult ==
nullptr)
337 throw Exception(
"AppDomain does not contain Singleton of type '{0}'", TypeName<TSingleton>().GetFullName());
341template<
class TSingleton>
342inline TSingleton* AppDomain::GetSingletonPtr()
344#ifdef ARP_PLATFORM_LINUX
345 RdLockGuard lock(&this->rw_lock);
347 std::lock_guard<std::mutex> lock(this->rw_lock);
350 auto i = this->singletons.find(AppDomain::GetTypeKey<TSingleton>());
351 if (i == this->singletons.end())
356 return (TSingleton*)(i->second);
359template<
class TSingleton>
360inline bool AppDomain::RemoveSingleton()
362#ifdef ARP_PLATFORM_LINUX
363 WrLockGuard lock(&this->rw_lock);
365 std::lock_guard<std::mutex> lock(this->rw_lock);
368 return this->singletons.erase(AppDomain::GetTypeKey<TSingleton>()) != 0;
@ Create
Creates a new file. If the file already exists, it is overwritten.
Root namespace for the PLCnext API