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