Program Listing for File app_control.h#
↰ Return to documentation for file (support\app_control.h)
#ifndef SDV_APP_CONTROL_H
#define SDV_APP_CONTROL_H
#include "sdv_core.h"
#include "../interfaces/app.h"
#include "../interfaces/config.h"
#include "interface_ptr.h"
#include "local_service_access.h"
namespace sdv
{
namespace app
{
class CAppControl : public IInterfaceAccess, public IAppEvent
{
public:
CAppControl() = default;
CAppControl(const std::string& rssConfig) : CAppControl()
{
Startup(rssConfig);
}
~CAppControl()
{
Shutdown();
}
// Interface map
BEGIN_SDV_INTERFACE_MAP()
SDV_INTERFACE_ENTRY(IAppEvent)
END_SDV_INTERFACE_MAP()
bool Startup(const std::string& rssConfig)
{
IAppControl* pAppControl = core::GetCore() ? core::GetCore<IAppControl>() : nullptr;
if (!pAppControl) return false;
if (m_eState != EAppOperationState::not_started) return false;
try
{
// Start the application control
bool bRet = pAppControl->Startup(rssConfig, this);
// Get the application context
const IAppContext* pAppContext = core::GetCore<IAppContext>();
if (pAppContext)
{
m_eContext = pAppContext->GetContextType();
m_uiInstanceID = pAppContext->GetInstanceID();
m_uiRetries = pAppContext->GetRetries();
}
// Automatically connect to the server
if (m_eContext == EAppContext::external)
{
// Try to connect
m_ptrServerRepository = sdv::com::ConnectToLocalServerRepository(m_uiInstanceID, m_uiRetries);
if (!m_ptrServerRepository)
{
if (!ConsoleIsSilent())
std::cerr << "ERROR: Failed to connect to the server repository." << std::endl;
Shutdown();
return false;
}
// Get access to the module control service
sdv::core::IObjectAccess* pObjectAccess = m_ptrServerRepository.GetInterface<sdv::core::IObjectAccess>();
const sdv::core::IRepositoryControl* pRepoControl = nullptr;
if (pObjectAccess)
pRepoControl = sdv::TInterfaceAccessPtr(pObjectAccess->GetObject("RepositoryService")).
GetInterface<sdv::core::IRepositoryControl>();
if (!pRepoControl)
{
if (!ConsoleIsSilent())
std::cerr << "ERROR: Failed to access the server repository." << std::endl;
return false;
}
// Link the local repository to the server repository.
sdv::core::ILinkCoreRepository* pLinkCoreRepo =
sdv::core::GetObject<sdv::core::ILinkCoreRepository>("RepositoryService");
if (!pLinkCoreRepo)
{
if (!ConsoleIsSilent())
std::cerr << "ERROR: Cannot link local and server repositories." << std::endl;
return false;
}
pLinkCoreRepo->LinkCoreRepository(m_ptrServerRepository);
}
return bRet;
}
catch (const XSysExcept& rxException)
{
if (!ConsoleIsSilent())
std::cerr << "ERROR: " << rxException.what() << std::endl;
return false;
}
}
bool RunLoop()
{
IAppControl* pAppControl = core::GetCore() ? core::GetCore<IAppControl>() : nullptr;
if (!pAppControl) return false;
try
{
pAppControl->RunLoop();
} catch (const XSysExcept&)
{
return false;
}
return true;
}
void Shutdown()
{
// Disconnect local and remote repositories.
if (m_ptrServerRepository)
{
// Link the local repository to the server repository.
sdv::core::ILinkCoreRepository* pLinkCoreRepo =
sdv::core::GetObject<sdv::core::ILinkCoreRepository>("RepositoryService");
if (!pLinkCoreRepo)
{
if (!ConsoleIsSilent())
std::cerr << "ERROR: Cannot unlink local and server repositories." << std::endl;
} else
pLinkCoreRepo->UnlinkCoreRepository();
}
// Disconnect from the server (if connected at all).
m_ptrServerRepository.Clear();
// Shutdown.
IAppControl* pAppControl = core::GetCore() ? core::GetCore<IAppControl>() : nullptr;
try
{
if (pAppControl) pAppControl->Shutdown(false);
} catch (const XSysExcept&)
{
if (!ConsoleIsSilent())
std::cerr << "ERROR: Failed to shutdown app control." << std::endl;
}
m_eContext = EAppContext::no_context;
m_uiInstanceID = 0u;
}
bool IsRunning() const
{
return m_eState == EAppOperationState::running;
}
static std::filesystem::path GetFrameworkRuntimeDirectory()
{
#ifdef _WIN32
const wchar_t* szFrameworkDir = _wgetenv(L"SDV_FRAMEWORK_RUNTIME");
if (!szFrameworkDir) return {};
return szFrameworkDir;
#elif defined __unix__
const char* szFrameworkDir = getenv("SDV_FRAMEWORK_RUNTIME");
if (!szFrameworkDir) return {};
return szFrameworkDir;
#else
#error The OS is not supported!
#endif
}
static void SetFrameworkRuntimeDirectory(const std::filesystem::path& rpathDir)
{
#ifdef _WIN32
// NOTE: In windows there are two environment variable stacks which need to be updated.
std::ignore = SetEnvironmentVariable(L"SDV_FRAMEWORK_RUNTIME", rpathDir.native().c_str());
std::ignore = _wputenv((std::wstring(L"SDV_FRAMEWORK_RUNTIME=") + rpathDir.native()).c_str());
#elif defined __unix__
std::ignore = setenv("SDV_FRAMEWORK_RUNTIME", rpathDir.generic_u8string().c_str(), 1);
#else
#error The OS is not supported!
#endif
}
static std::filesystem::path GetComponentInstallDirectory()
{
#ifdef _WIN32
const wchar_t* szComponentDir = _wgetenv(L"SDV_COMPONENT_INSTALL");
if (!szComponentDir) return {};
return szComponentDir;
#elif defined __unix__
const char* szComponentDir = getenv("SDV_COMPONENT_INSTALL");
if (!szComponentDir) return {};
return szComponentDir;
#else
#error The OS is not supported!
#endif
}
static void SetComponentInstallDirectory(const std::filesystem::path& rpathDir)
{
#ifdef _WIN32
// NOTE: In windows there are two environment variable stacks which need to be updated.
std::ignore = SetEnvironmentVariable(L"SDV_COMPONENT_INSTALL", rpathDir.native().c_str());
std::ignore = _wputenv((std::wstring(L"SDV_COMPONENT_INSTALL=") + rpathDir.native()).c_str());
#elif defined __unix__
std::ignore = setenv("SDV_COMPONENT_INSTALL", rpathDir.generic_u8string().c_str(), 1);
#else
#error The OS is not supported!
#endif
}
EAppContext GetAppContext() const
{
return m_eContext;
}
uint32_t GetInstanceID() const
{
return m_uiInstanceID;
}
void SetRunningMode()
{
IAppOperation* pAppOperation = core::GetObject<IAppOperation>("AppControlService");
if (pAppOperation)
pAppOperation->SetRunningMode();
}
bool IsConfiguring() const
{
return m_eState == EAppOperationState::configuring;
}
void SetConfigMode()
{
IAppOperation* pAppOperation = core::GetObject<IAppOperation>("AppControlService");
if (pAppOperation)
pAppOperation->SetConfigMode();
}
core::EConfigProcessResult ProcessConfig(/*in*/ const sdv::u8string& ssContent)
{
core::IConfig* pAppConfig = nullptr;
sdv::TInterfaceAccessPtr ptrConfigObj = core::GetObject("ConfigService");
if (ptrConfigObj) pAppConfig = ptrConfigObj.GetInterface<core::IConfig>();
if (!pAppConfig) return core::EConfigProcessResult::failed;
bool bRunning = IsRunning();
SetConfigMode();
core::EConfigProcessResult eResult = pAppConfig->ProcessConfig(ssContent);
if (bRunning) SetRunningMode();
return eResult;
}
core::EConfigProcessResult LoadConfig(/*in*/ const sdv::u8string& ssFilename)
{
core::IConfig* pAppConfig = nullptr;
sdv::TInterfaceAccessPtr ptrConfigObj = core::GetObject("ConfigService");
if (ptrConfigObj) pAppConfig = ptrConfigObj.GetInterface<core::IConfig>();
if (!pAppConfig) return core::EConfigProcessResult::failed;
bool bRunning = IsRunning();
SetConfigMode();
core::EConfigProcessResult eResult = pAppConfig->LoadConfig(ssFilename);
if (bRunning) SetRunningMode();
return eResult;
}
bool AddConfigSearchDir(/*in*/ const std::filesystem::path& rpathDir)
{
core::IConfig* pAppConfig = nullptr;
sdv::TInterfaceAccessPtr ptrConfigObj = core::GetObject("ConfigService");
if (ptrConfigObj) pAppConfig = ptrConfigObj.GetInterface<core::IConfig>();
if (!pAppConfig) return false;
return pAppConfig->AddConfigSearchDir(rpathDir.generic_u8string());
}
bool AddConfigSearchDir(/*in*/ const sdv::u8string& ssDir)
{
core::IConfig* pAppConfig = nullptr;
sdv::TInterfaceAccessPtr ptrConfigObj = core::GetObject("ConfigService");
if (ptrConfigObj) pAppConfig = ptrConfigObj.GetInterface<core::IConfig>();
if (!pAppConfig) return false;
return pAppConfig->AddConfigSearchDir(ssDir);
}
bool AddConfigSearchDir(/*in*/ const std::string& ssDir)
{
core::IConfig* pAppConfig = nullptr;
sdv::TInterfaceAccessPtr ptrConfigObj = core::GetObject("ConfigService");
if (ptrConfigObj) pAppConfig = ptrConfigObj.GetInterface<core::IConfig>();
if (!pAppConfig) return false;
return pAppConfig->AddConfigSearchDir(ssDir);
}
bool AddConfigSearchDir(/*in*/ const char* szDir)
{
if (!szDir) return false;
core::IConfig* pAppConfig = nullptr;
sdv::TInterfaceAccessPtr ptrConfigObj = core::GetObject("ConfigService");
if (ptrConfigObj) pAppConfig = ptrConfigObj.GetInterface<core::IConfig>();
if (!pAppConfig) return false;
return pAppConfig->AddConfigSearchDir(szDir);
}
bool AddModuleSearchDir(/*in*/ const std::filesystem::path& rpathDir)
{
sdv::core::IModuleControlConfig* pModuleConfig = sdv::core::GetCore<sdv::core::IModuleControlConfig>();
if (!pModuleConfig) return false;
return pModuleConfig->AddModuleSearchDir(rpathDir.generic_u8string());
}
bool AddModuleSearchDir(/*in*/ const sdv::u8string& rssDir)
{
sdv::core::IModuleControlConfig* pModuleConfig = sdv::core::GetCore<sdv::core::IModuleControlConfig>();
if (!pModuleConfig) return false;
return pModuleConfig->AddModuleSearchDir(rssDir);
}
bool AddModuleSearchDir(/*in*/ const std::string& rssDir)
{
sdv::core::IModuleControlConfig* pModuleConfig = sdv::core::GetCore<sdv::core::IModuleControlConfig>();
if (!pModuleConfig) return false;
return pModuleConfig->AddModuleSearchDir(rssDir);
}
bool AddModuleSearchDir(/*in*/ const char* szDir)
{
if (!szDir) return false;
sdv::core::IModuleControlConfig* pModuleConfig = sdv::core::GetCore<sdv::core::IModuleControlConfig>();
if (!pModuleConfig) return false;
return pModuleConfig->AddModuleSearchDir(szDir);
}
private:
virtual void ProcessEvent(/*inout*/ SAppEvent& sEvent) override
{
// Only process state change events
if (sEvent.uiEventID != EVENT_OPERATION_STATE_CHANGED) return;
m_eState = static_cast<EAppOperationState>(sEvent.uiInfo);
}
EAppOperationState m_eState = EAppOperationState::not_started;
EAppContext m_eContext = EAppContext::no_context;
uint32_t m_uiInstanceID = 0u;
uint32_t m_uiRetries = 0u;
sdv::TObjectPtr m_ptrServerRepository;
};
} // namespace app
} // namespace sdv
#endif // !defined SDV_APP_CONTROL_H