You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Code/Editor/WipFeatureManager.cpp

455 lines
12 KiB
C++

/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "EditorDefs.h"
#include "WipFeatureManager.h"
#ifdef USE_WIP_FEATURES_MANAGER
#include "WipFeaturesDlg.h"
#if defined(AZ_PLATFORM_WINDOWS)
const char* CWipFeatureManager::kWipFeaturesFilename = "@user@\\Editor\\UI\\WipFeatures.xml";
#else
const char* CWipFeatureManager::kWipFeaturesFilename = "@user@/Editor/UI/WipFeatures.xml";
#endif
CWipFeatureManager* CWipFeatureManager::s_pInstance = nullptr;
static void WipFeatureVarChange(ICVar* pVar)
{
QString strParams = pVar->GetString();
QStringList params;
SplitString(strParams, params, ' ');
if (strParams == "edit")
{
static CWipFeaturesDlg dlg;
dlg.show();
return;
}
if (params.size() >= 2)
{
QString featName = params[0].trimmed();
QString attr = params[1].trimmed();
if (featName.isEmpty())
{
return;
}
int id = featName.toInt();
// if all features
if (featName == "*")
{
if (attr == "enable")
{
CWipFeatureManager::Instance()->EnableAllFeatures(true);
}
else
if (attr == "disable")
{
CWipFeatureManager::Instance()->EnableAllFeatures(false);
}
else
if (attr == "hide")
{
CWipFeatureManager::Instance()->ShowAllFeatures(false);
}
else
if (attr == "show")
{
CWipFeatureManager::Instance()->ShowAllFeatures(true);
}
else
if (attr == "safemode")
{
CWipFeatureManager::Instance()->SetAllFeaturesSafeMode(true);
}
else
if (attr == "fullmode")
{
CWipFeatureManager::Instance()->SetAllFeaturesSafeMode(false);
}
else
{
CWipFeatureManager::Instance()->SetAllFeaturesParams(attr.toUtf8().data());
}
return;
}
if (attr == "enable")
{
CWipFeatureManager::Instance()->EnableFeature(id, true);
}
else
if (attr == "disable")
{
CWipFeatureManager::Instance()->EnableFeature(id, false);
}
else
if (attr == "hide")
{
CWipFeatureManager::Instance()->ShowFeature(id, false);
}
else
if (attr == "show")
{
CWipFeatureManager::Instance()->ShowFeature(id, true);
}
else
if (attr == "safemode")
{
CWipFeatureManager::Instance()->SetFeatureSafeMode(id, true);
}
else
if (attr == "fullmode")
{
CWipFeatureManager::Instance()->SetFeatureSafeMode(id, false);
}
else
{
CWipFeatureManager::Instance()->SetFeatureParams(id, attr.toUtf8().data());
}
}
}
CWipFeatureManager::CWipFeatureManager()
{
m_bEnabled = true;
}
CWipFeatureManager::~CWipFeatureManager()
{
}
bool CWipFeatureManager::Init(bool bLoadXml)
{
if (!gEnv)
{
return false;
}
IConsole* pConsole = gEnv->pConsole;
if (!pConsole)
{
return false;
}
REGISTER_CVAR2_CB("e_wipfeature", (const char**)&CWipFeatureManager::Instance()->m_consoleCmdParams, "", VF_ALWAYSONCHANGE | VF_CHEAT, "wipfeature <featureName> enable|disable|hide|show|safemode|fullmode", WipFeatureVarChange);
if (bLoadXml)
{
CWipFeatureManager::Instance()->Load();
}
return true;
}
void CWipFeatureManager::Shutdown()
{
CWipFeatureManager::Instance()->Save();
delete s_pInstance;
s_pInstance = nullptr;
}
bool CWipFeatureManager::Load(const char* pFilename, bool bClearExisting)
{
if (!GetISystem())
{
return false;
}
XmlNodeRef root = GetISystem()->LoadXmlFromFile(pFilename);
if (!root)
{
return false;
}
if (bClearExisting)
{
m_features.clear();
}
Log("Loading WIP features file: '%s'...", pFilename);
for (size_t i = 0, iCount = root->getChildCount(); i < iCount; ++i)
{
SWipFeatureInfo wf;
XmlNodeRef node = root->getChild(static_cast<int>(i));
XmlString str;
node->getAttr("id", wf.m_id);
node->getAttr("displayName", str);
wf.m_displayName = str;
node->getAttr("visible", wf.m_bVisible);
node->getAttr("enabled", wf.m_bEnabled);
node->getAttr("safeMode", wf.m_bSafeMode);
node->getAttr("params", str);
wf.m_params = str;
wf.m_bLoadedFromXml = true;
TWipFeatures::iterator iter = m_features.find(wf.m_id);
if (iter == m_features.end())
{
m_features[wf.m_id] = wf;
}
else
{
m_features[wf.m_id].m_bVisible = wf.m_bVisible;
m_features[wf.m_id].m_bEnabled = wf.m_bEnabled;
m_features[wf.m_id].m_bSafeMode = wf.m_bSafeMode;
m_features[wf.m_id].m_params = wf.m_params;
}
}
Log("Loaded %d WIP features.", m_features.size());
return true;
}
bool CWipFeatureManager::Save(const char* pFilename)
{
if (!gEnv)
{
return false;
}
if (!GetISystem())
{
return false;
}
ISystem* pISystem = GetISystem();
XmlNodeRef root = pISystem->CreateXmlNode("features");
for (TWipFeatures::iterator iter = m_features.begin(), iterEnd = m_features.end(); iter != iterEnd; ++iter)
{
SWipFeatureInfo& wf = iter->second;
XmlNodeRef node = root->createNode("feature");
node->setAttr("id", wf.m_id);
node->setAttr("displayName", wf.m_displayName.c_str());
node->setAttr("visible", wf.m_bVisible);
node->setAttr("enabled", wf.m_bEnabled);
node->setAttr("safeMode", wf.m_bSafeMode);
node->setAttr("params", wf.m_params.c_str());
root->addChild(node);
}
root->saveToFile(pFilename);
return true;
}
int CWipFeatureManager::RegisterFeature(const char* pDisplayName, bool bVisible, bool bEnabled, bool bSafeMode, const char* pParams, bool bSaveToXml)
{
int aMaxId = -1;
for (TWipFeatures::iterator iter = m_features.begin(), iterEnd = m_features.end(); iter != iterEnd; ++iter)
{
if (iter->first > aMaxId)
{
aMaxId = iter->first;
}
}
++aMaxId;
SetFeature(aMaxId, pDisplayName, bVisible, bEnabled, bSafeMode, pParams, bSaveToXml);
return aMaxId;
}
void CWipFeatureManager::SetFeature(int aFeatureId, const char* pDisplayName, bool bVisible, bool bEnabled, bool bSafeMode, const char* pParams, bool bSaveToXml)
{
m_features[aFeatureId].m_id = aFeatureId;
m_features[aFeatureId].m_displayName = pDisplayName;
m_features[aFeatureId].m_bVisible = bVisible;
m_features[aFeatureId].m_bEnabled = bEnabled;
m_features[aFeatureId].m_bSafeMode = bSafeMode;
m_features[aFeatureId].m_bSaveToXml = bSaveToXml;
m_features[aFeatureId].m_params = pParams;
if (m_features[aFeatureId].m_pfnUpdateFeature)
{
m_features[aFeatureId].m_pfnUpdateFeature(aFeatureId, &bVisible, &bEnabled, &bSafeMode, pParams);
}
}
void CWipFeatureManager::SetDefaultFeatureStates(int aFeatureId, const char* pDisplayName, bool bVisible, bool bEnabled, bool bSafeMode, const char* pParams)
{
TWipFeatures::iterator iter = m_features.find(aFeatureId);
// set feature if not existing
if (iter == m_features.end() || (iter != m_features.end() && !iter->second.m_bLoadedFromXml))
{
m_features[aFeatureId].m_id = aFeatureId;
m_features[aFeatureId].m_displayName = pDisplayName;
m_features[aFeatureId].m_bVisible = bVisible;
m_features[aFeatureId].m_bEnabled = bEnabled;
m_features[aFeatureId].m_bSafeMode = bSafeMode;
m_features[aFeatureId].m_params = pParams;
}
else
if (iter != m_features.end() && iter->second.m_bLoadedFromXml)
{
m_features[aFeatureId].m_id = aFeatureId;
m_features[aFeatureId].m_displayName = pDisplayName;
}
if (m_features[aFeatureId].m_pfnUpdateFeature)
{
m_features[aFeatureId].m_pfnUpdateFeature(aFeatureId, &bVisible, &bEnabled, &bSafeMode, pParams);
}
}
bool CWipFeatureManager::IsFeatureVisible(int aFeatureId)
{
return m_features[aFeatureId].m_bVisible || !m_bEnabled;
}
bool CWipFeatureManager::IsFeatureEnabled(int aFeatureId)
{
return m_features[aFeatureId].m_bEnabled || !m_bEnabled;
}
bool CWipFeatureManager::IsFeatureInSafeMode(int aFeatureId)
{
if (!m_bEnabled)
{
return false;
}
return m_features[aFeatureId].m_bSafeMode;
}
const char* CWipFeatureManager::GetFeatureParams(int aFeatureId)
{
return m_features[aFeatureId].m_params.c_str();
}
void CWipFeatureManager::ShowFeature(int aFeatureId, bool bShow)
{
m_features[aFeatureId].m_bVisible = bShow;
if (m_features[aFeatureId].m_pfnUpdateFeature)
{
m_features[aFeatureId].m_pfnUpdateFeature(aFeatureId, &bShow, nullptr, nullptr, nullptr);
}
}
void CWipFeatureManager::EnableFeature(int aFeatureId, bool bEnable)
{
m_features[aFeatureId].m_bEnabled = bEnable;
if (m_features[aFeatureId].m_pfnUpdateFeature)
{
m_features[aFeatureId].m_pfnUpdateFeature(aFeatureId, nullptr, &bEnable, nullptr, nullptr);
}
}
void CWipFeatureManager::SetFeatureSafeMode(int aFeatureId, bool bSafeMode)
{
m_features[aFeatureId].m_bSafeMode = bSafeMode;
if (m_features[aFeatureId].m_pfnUpdateFeature)
{
m_features[aFeatureId].m_pfnUpdateFeature(aFeatureId, nullptr, nullptr, &bSafeMode, nullptr);
}
}
void CWipFeatureManager::SetFeatureParams(int aFeatureId, const char* pParams)
{
m_features[aFeatureId].m_params = pParams;
if (m_features[aFeatureId].m_pfnUpdateFeature)
{
m_features[aFeatureId].m_pfnUpdateFeature(aFeatureId, nullptr, nullptr, nullptr, pParams);
}
}
void CWipFeatureManager::ShowAllFeatures(bool bShow)
{
for (TWipFeatures::iterator iter = m_features.begin(), iterEnd = m_features.end(); iter != iterEnd; ++iter)
{
iter->second.m_bVisible = bShow;
if (iter->second.m_pfnUpdateFeature)
{
iter->second.m_pfnUpdateFeature(iter->first, &bShow, nullptr, nullptr, nullptr);
}
}
}
void CWipFeatureManager::EnableAllFeatures(bool bEnable)
{
for (TWipFeatures::iterator iter = m_features.begin(), iterEnd = m_features.end(); iter != iterEnd; ++iter)
{
iter->second.m_bEnabled = bEnable;
if (iter->second.m_pfnUpdateFeature)
{
iter->second.m_pfnUpdateFeature(iter->first, nullptr, &bEnable, nullptr, nullptr);
}
}
}
void CWipFeatureManager::SetAllFeaturesSafeMode(bool bSafeMode)
{
for (TWipFeatures::iterator iter = m_features.begin(), iterEnd = m_features.end(); iter != iterEnd; ++iter)
{
iter->second.m_bSafeMode = bSafeMode;
if (iter->second.m_pfnUpdateFeature)
{
iter->second.m_pfnUpdateFeature(iter->first, nullptr, nullptr, &bSafeMode, nullptr);
}
}
}
void CWipFeatureManager::SetAllFeaturesParams(const char* pParams)
{
for (TWipFeatures::iterator iter = m_features.begin(), iterEnd = m_features.end(); iter != iterEnd; ++iter)
{
iter->second.m_params = pParams;
if (iter->second.m_pfnUpdateFeature)
{
iter->second.m_pfnUpdateFeature(iter->first, nullptr, nullptr, nullptr, pParams);
}
}
}
void CWipFeatureManager::EnableManager(bool bEnable)
{
m_bEnabled = bEnable;
}
void CWipFeatureManager::SetFeatureUpdateCallback(int aFeatureId, TWipFeatureUpdateCallback pfnUpdate)
{
m_features[aFeatureId].m_pfnUpdateFeature = pfnUpdate;
}
AZStd::map<int, CWipFeatureManager::SWipFeatureInfo>& CWipFeatureManager::GetFeatures()
{
return m_features;
}
#endif