mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-27 04:11:05 +00:00
Save and load persistant config file
This commit is contained in:
@@ -32,7 +32,8 @@
|
||||
#include "Windows/MainWindow.h"
|
||||
|
||||
CaptureContext::CaptureContext(QString paramFilename, QString remoteHost, uint32_t remoteIdent,
|
||||
bool temp)
|
||||
bool temp, PersistantConfig &cfg)
|
||||
: Config(cfg)
|
||||
{
|
||||
m_LogLoaded = false;
|
||||
m_LoadInProgress = false;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <QString>
|
||||
#include <QtWidgets/QWidget>
|
||||
#include "CommonPipelineState.h"
|
||||
#include "PersistantConfig.h"
|
||||
#include "RenderManager.h"
|
||||
|
||||
#if defined(RENDERDOC_PLATFORM_LINUX)
|
||||
@@ -56,14 +57,15 @@ class MainWindow;
|
||||
class CaptureContext
|
||||
{
|
||||
public:
|
||||
CaptureContext(QString paramFilename, QString remoteHost, uint32_t remoteIdent, bool temp);
|
||||
CaptureContext(QString paramFilename, QString remoteHost, uint32_t remoteIdent, bool temp,
|
||||
PersistantConfig &cfg);
|
||||
~CaptureContext();
|
||||
|
||||
bool isRunning();
|
||||
|
||||
QString ConfigFile(const QString &filename);
|
||||
static QString ConfigFile(const QString &filename);
|
||||
|
||||
QString TempLogFilename(QString appname);
|
||||
static QString TempLogFilename(QString appname);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Control functions
|
||||
@@ -140,6 +142,8 @@ public:
|
||||
VulkanPipelineState CurVulkanPipelineState;
|
||||
CommonPipelineState CurPipelineState;
|
||||
|
||||
PersistantConfig &Config;
|
||||
|
||||
private:
|
||||
RenderManager m_Renderer;
|
||||
|
||||
|
||||
@@ -0,0 +1,243 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Baldur Karlsson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#include "PersistantConfig.h"
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QJsonDocument>
|
||||
#include "renderdoc_replay.h"
|
||||
|
||||
// helper templates to convert some more complex types to/from appropriate variants
|
||||
template <typename variantType, typename origType>
|
||||
variantType convertToVariant(const origType &val)
|
||||
{
|
||||
return variantType(val);
|
||||
}
|
||||
|
||||
template <>
|
||||
QVariantMap convertToVariant(const QStringMap &val)
|
||||
{
|
||||
QVariantMap ret;
|
||||
for(const QString &k : val.keys())
|
||||
{
|
||||
ret[k] = val[k];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <>
|
||||
QVariantList convertToVariant(const QList<QString> &val)
|
||||
{
|
||||
QVariantList ret;
|
||||
ret.reserve(val.count());
|
||||
for(const QString &s : val)
|
||||
ret.push_back(s);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename origType, typename variantType>
|
||||
origType convertFromVariant(const variantType &val)
|
||||
{
|
||||
return origType(val);
|
||||
}
|
||||
|
||||
template <>
|
||||
QStringMap convertFromVariant(const QVariantMap &val)
|
||||
{
|
||||
QStringMap ret;
|
||||
for(const QString &k : val.keys())
|
||||
{
|
||||
ret[k] = val[k].toString();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <>
|
||||
QList<QString> convertFromVariant(const QVariantList &val)
|
||||
{
|
||||
QList<QString> ret;
|
||||
ret.reserve(val.count());
|
||||
for(const QVariant &s : val)
|
||||
ret.push_back(s.toString());
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool PersistantConfig::Deserialize(QString filename)
|
||||
{
|
||||
QFile f(filename);
|
||||
|
||||
// silently allow missing configs
|
||||
if(!f.exists())
|
||||
return true;
|
||||
|
||||
if(f.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||
{
|
||||
QByteArray json = f.readAll();
|
||||
|
||||
if(json.isEmpty())
|
||||
{
|
||||
qCritical() << "Read invalid empty JSON data from file " << f.errorString();
|
||||
return false;
|
||||
}
|
||||
|
||||
QJsonDocument doc = QJsonDocument::fromJson(json);
|
||||
|
||||
if(doc.isEmpty() || doc.isNull())
|
||||
{
|
||||
qCritical() << "Failed to convert file to JSON document";
|
||||
return false;
|
||||
}
|
||||
|
||||
QVariantMap values = doc.toVariant().toMap();
|
||||
|
||||
if(values.isEmpty() || !values.contains("renderdocConfigData"))
|
||||
{
|
||||
qCritical() << "Converted config data is invalid or unrecognised";
|
||||
return false;
|
||||
}
|
||||
|
||||
applyValues(values);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
qInfo() << "Couldn't load layout from " << filename << " " << f.errorString();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PersistantConfig::Serialize(QString filename)
|
||||
{
|
||||
QVariantMap values = storeValues();
|
||||
|
||||
// marker that this is indeed a valid config to load from
|
||||
values["renderdocConfigData"] = 1;
|
||||
|
||||
QFile f(filename);
|
||||
if(f.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text))
|
||||
{
|
||||
QJsonDocument doc = QJsonDocument::fromVariant(values);
|
||||
|
||||
if(doc.isEmpty() || doc.isNull())
|
||||
{
|
||||
qCritical() << "Failed to convert config data to JSON document";
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray jsontext = doc.toJson(QJsonDocument::Indented);
|
||||
|
||||
qint64 ret = f.write(jsontext);
|
||||
|
||||
if(ret != jsontext.size())
|
||||
{
|
||||
qCritical() << "Failed to write JSON data to file: " << ret << " " << f.errorString();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
qWarning() << "Couldn't write to " << filename << " " << f.errorString();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QVariantMap PersistantConfig::storeValues() const
|
||||
{
|
||||
QVariantMap ret;
|
||||
|
||||
#undef CONFIG_SETTING_VAL
|
||||
#undef CONFIG_SETTING
|
||||
|
||||
#define CONFIG_SETTING_VAL(access, variantType, type, name, defaultValue) \
|
||||
ret[#name] = convertToVariant<variantType>(name);
|
||||
#define CONFIG_SETTING(access, variantType, type, name) \
|
||||
ret[#name] = convertToVariant<variantType>(name);
|
||||
|
||||
CONFIG_SETTINGS()
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void PersistantConfig::applyValues(const QVariantMap &values)
|
||||
{
|
||||
#undef CONFIG_SETTING_VAL
|
||||
#undef CONFIG_SETTING
|
||||
|
||||
#define CONFIG_SETTING_VAL(access, variantType, type, name, defaultValue) \
|
||||
if(values.contains(#name)) \
|
||||
name = convertFromVariant<type>(values[#name].value<variantType>());
|
||||
#define CONFIG_SETTING(access, variantType, type, name) \
|
||||
if(values.contains(#name)) \
|
||||
name = convertFromVariant<type>(values[#name].value<variantType>());
|
||||
|
||||
CONFIG_SETTINGS()
|
||||
}
|
||||
|
||||
void PersistantConfig::SetupFormatting()
|
||||
{
|
||||
/*
|
||||
Formatter.MinFigures = Formatter_MinFigures;
|
||||
Formatter.MaxFigures = Formatter_MaxFigures;
|
||||
Formatter.ExponentialNegCutoff = Formatter_NegExp;
|
||||
Formatter.ExponentialPosCutoff = Formatter_PosExp;
|
||||
|
||||
PreferredFont = Font_PreferMonospaced
|
||||
? new System.Drawing.Font("Consolas", 9.25F, System.Drawing.FontStyle.Regular,
|
||||
System.Drawing.GraphicsUnit.Point, ((byte)(0)))
|
||||
: new System.Drawing.Font("Tahoma", 8.25F);
|
||||
*/
|
||||
}
|
||||
|
||||
void PersistantConfig::AddRecentFile(QList<QString> &recentList, const QString &file, int maxItems)
|
||||
{
|
||||
QDir dir(file);
|
||||
QString path = dir.canonicalPath();
|
||||
|
||||
if(!recentList.contains(path))
|
||||
{
|
||||
recentList.push_back(path);
|
||||
if(recentList.count() >= maxItems)
|
||||
recentList.removeAt(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
recentList.removeOne(path);
|
||||
recentList.push_back(path);
|
||||
}
|
||||
}
|
||||
|
||||
void PersistantConfig::SetConfigSetting(QString name, QString value)
|
||||
{
|
||||
ConfigSettings[name] = value;
|
||||
RENDERDOC_SetConfigSetting(name.toUtf8().data(), value.toUtf8().data());
|
||||
}
|
||||
|
||||
QString PersistantConfig::GetConfigSetting(QString name)
|
||||
{
|
||||
if(ConfigSettings.contains(name))
|
||||
return ConfigSettings[name];
|
||||
|
||||
return "";
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Baldur Karlsson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
|
||||
typedef QMap<QString, QString> QStringMap;
|
||||
|
||||
#define CONFIG_SETTING_VAL(access, variantType, type, name, defaultValue) \
|
||||
access: \
|
||||
type name = defaultValue;
|
||||
#define CONFIG_SETTING(access, variantType, type, name) \
|
||||
access: \
|
||||
type name;
|
||||
|
||||
#define CONFIG_SETTINGS() \
|
||||
\
|
||||
CONFIG_SETTING_VAL(public, QString, QString, LastLogPath, "") \
|
||||
\
|
||||
CONFIG_SETTING(public, QVariantList, QList<QString>, RecentLogFiles) \
|
||||
\
|
||||
CONFIG_SETTING_VAL(public, QString, QString, LastCapturePath, "") \
|
||||
\
|
||||
CONFIG_SETTING_VAL(public, QString, QString, LastCaptureExe, "") \
|
||||
\
|
||||
CONFIG_SETTING(public, QVariantList, QList<QString>, RecentCaptureSettings) \
|
||||
\
|
||||
CONFIG_SETTING_VAL(public, int, int, CallstackLevelSkip, 0) \
|
||||
\
|
||||
CONFIG_SETTING_VAL(public, QString, QString, TemporaryCaptureDirectory, "") \
|
||||
\
|
||||
CONFIG_SETTING_VAL(public, QString, QString, DefaultCaptureSaveDirectory, "") \
|
||||
\
|
||||
CONFIG_SETTING_VAL(public, bool, bool, TextureViewer_ResetRange, false) \
|
||||
\
|
||||
CONFIG_SETTING_VAL(public, bool, bool, TextureViewer_PerTexSettings, true) \
|
||||
\
|
||||
CONFIG_SETTING_VAL(public, bool, bool, ShaderViewer_FriendlyNaming, true) \
|
||||
\
|
||||
CONFIG_SETTING_VAL(public, bool, bool, AlwaysReplayLocally, false) \
|
||||
\
|
||||
CONFIG_SETTING_VAL(public, int, int, LocalProxy, 0) \
|
||||
\
|
||||
CONFIG_SETTING_VAL(public, int, TimeUnit, EventBrowser_TimeUnit, TimeUnit::Microseconds) \
|
||||
\
|
||||
CONFIG_SETTING_VAL(public, bool, bool, EventBrowser_HideEmpty, false) \
|
||||
\
|
||||
CONFIG_SETTING_VAL(public, bool, bool, EventBrowser_ApplyColours, true) \
|
||||
\
|
||||
CONFIG_SETTING_VAL(public, bool, bool, EventBrowser_ColourEventRow, true) \
|
||||
\
|
||||
CONFIG_SETTING_VAL(public, int, int, Formatter_MinFigures, 2) \
|
||||
\
|
||||
CONFIG_SETTING_VAL(public, int, int, Formatter_MaxFigures, 5) \
|
||||
\
|
||||
CONFIG_SETTING_VAL(public, int, int, Formatter_NegExp, 5) \
|
||||
\
|
||||
CONFIG_SETTING_VAL(public, int, int, Formatter_PosExp, 7) \
|
||||
\
|
||||
CONFIG_SETTING_VAL(public, bool, bool, Font_PreferMonospaced, false) \
|
||||
\
|
||||
CONFIG_SETTING_VAL(public, bool, bool, CheckUpdate_AllowChecks, true) \
|
||||
\
|
||||
CONFIG_SETTING_VAL(public, bool, bool, CheckUpdate_UpdateAvailable, false) \
|
||||
\
|
||||
CONFIG_SETTING_VAL(public, QString, QString, CheckUpdate_UpdateResponse, "") \
|
||||
\
|
||||
CONFIG_SETTING_VAL(public, QDateTime, QDateTime, CheckUpdate_LastUpdate, \
|
||||
QDateTime(QDate(2012, 06, 27), QTime(0, 0, 0))) \
|
||||
\
|
||||
CONFIG_SETTING_VAL(public, QDateTime, QDateTime, DegradedLog_LastUpdate, \
|
||||
QDateTime(QDate(2015, 01, 01), QTime(0, 0, 0))) \
|
||||
\
|
||||
CONFIG_SETTING_VAL(public, bool, bool, Tips_SeenFirst, false) \
|
||||
\
|
||||
CONFIG_SETTING_VAL(public, bool, bool, AllowGlobalHook, false) \
|
||||
\
|
||||
CONFIG_SETTING(private, QVariantMap, QStringMap, ConfigSettings)
|
||||
|
||||
class PersistantConfig
|
||||
{
|
||||
public:
|
||||
enum class TimeUnit : int
|
||||
{
|
||||
Seconds = 0,
|
||||
Milliseconds,
|
||||
Microseconds,
|
||||
Nanoseconds,
|
||||
};
|
||||
|
||||
CONFIG_SETTINGS()
|
||||
|
||||
public:
|
||||
PersistantConfig() {}
|
||||
bool Deserialize(QString filename);
|
||||
bool Serialize(QString filename);
|
||||
|
||||
void SetupFormatting();
|
||||
|
||||
static QString UnitPrefix(TimeUnit t)
|
||||
{
|
||||
if(t == TimeUnit::Seconds)
|
||||
return "s";
|
||||
else if(t == TimeUnit::Milliseconds)
|
||||
return "ms";
|
||||
else if(t == TimeUnit::Microseconds)
|
||||
return "µs";
|
||||
else if(t == TimeUnit::Nanoseconds)
|
||||
return "ns";
|
||||
|
||||
return "s";
|
||||
}
|
||||
|
||||
static void AddRecentFile(QList<QString> &recentList, const QString &file, int maxItems);
|
||||
|
||||
void SetConfigSetting(QString name, QString value);
|
||||
QString GetConfigSetting(QString name);
|
||||
|
||||
private:
|
||||
QVariantMap storeValues() const;
|
||||
void applyValues(const QVariantMap &values);
|
||||
};
|
||||
@@ -116,13 +116,30 @@ int main(int argc, char *argv[])
|
||||
QApplication application(argc, argv_mod);
|
||||
|
||||
{
|
||||
CaptureContext ctx(filename, remoteHost, remoteIdent, temp);
|
||||
PersistantConfig config;
|
||||
|
||||
QString configFilename = CaptureContext::ConfigFile("UI.config");
|
||||
|
||||
if(!config.Deserialize(configFilename))
|
||||
{
|
||||
RDDialog::critical(
|
||||
NULL, "Error loading config",
|
||||
QString(
|
||||
"Error loading config file\n%1\nA default config is loaded and will be saved out.")
|
||||
.arg(configFilename));
|
||||
}
|
||||
|
||||
config.SetupFormatting();
|
||||
|
||||
CaptureContext ctx(filename, remoteHost, remoteIdent, temp, config);
|
||||
|
||||
while(ctx.isRunning())
|
||||
{
|
||||
application.processEvents(QEventLoop::WaitForMoreEvents);
|
||||
QCoreApplication::sendPostedEvents();
|
||||
}
|
||||
|
||||
config.Serialize(configFilename);
|
||||
}
|
||||
|
||||
delete[] argv_mod;
|
||||
|
||||
@@ -227,9 +227,6 @@ QVariantMap MainWindow::saveState()
|
||||
{
|
||||
QVariantMap state = ui->toolWindowManager->saveState();
|
||||
|
||||
// marker that this is indeed a valid state to load from
|
||||
state["renderdocLayoutData"] = 1;
|
||||
|
||||
state["mainWindowGeometry"] = saveGeometry().toBase64();
|
||||
|
||||
return state;
|
||||
@@ -250,6 +247,9 @@ bool MainWindow::SaveLayout(int layout)
|
||||
|
||||
QVariantMap state = saveState();
|
||||
|
||||
// marker that this is indeed a valid state to load from
|
||||
state["renderdocLayoutData"] = 1;
|
||||
|
||||
QFile f(path);
|
||||
if(f.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text))
|
||||
{
|
||||
|
||||
@@ -89,6 +89,7 @@ SOURCES += Code/main.cpp \
|
||||
3rdparty/toolwindowmanager/ToolWindowManagerArea.cpp \
|
||||
3rdparty/toolwindowmanager/ToolWindowManagerWrapper.cpp \
|
||||
Code/RenderManager.cpp \
|
||||
Code/PersistantConfig.cpp \
|
||||
Code/CaptureContext.cpp \
|
||||
Widgets/RDLineEdit.cpp \
|
||||
3rdparty/flowlayout/FlowLayout.cpp \
|
||||
@@ -107,6 +108,7 @@ HEADERS += Windows/MainWindow.h \
|
||||
3rdparty/toolwindowmanager/ToolWindowManagerWrapper.h \
|
||||
Code/CaptureContext.h \
|
||||
Code/RenderManager.h \
|
||||
Code/PersistantConfig.h \
|
||||
Widgets/RDLineEdit.h \
|
||||
3rdparty/flowlayout/FlowLayout.h \
|
||||
Widgets/ResourcePreview.h \
|
||||
|
||||
@@ -277,6 +277,7 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Code\CommonPipelineState.cpp" />
|
||||
<ClCompile Include="Code\PersistantConfig.cpp" />
|
||||
<ClCompile Include="generated\moc_AboutDialog.cpp" />
|
||||
<ClCompile Include="generated\moc_CaptureContext.cpp" />
|
||||
<ClCompile Include="generated\moc_CustomPaintWidget.cpp" />
|
||||
@@ -318,6 +319,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Code\CommonPipelineState.h" />
|
||||
<ClInclude Include="Code\PersistantConfig.h" />
|
||||
<ClInclude Include="generated\ui_AboutDialog.h" />
|
||||
<ClInclude Include="generated\ui_EventBrowser.h" />
|
||||
<ClInclude Include="generated\ui_MainWindow.h" />
|
||||
|
||||
@@ -133,6 +133,9 @@
|
||||
<ClCompile Include="Code\CommonPipelineState.cpp">
|
||||
<Filter>Generated Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Code\PersistantConfig.cpp">
|
||||
<Filter>Generated Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="3rdparty\flowlayout\FlowLayout.h">
|
||||
@@ -189,6 +192,9 @@
|
||||
<ClInclude Include="Code\CommonPipelineState.h">
|
||||
<Filter>Code</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Code\PersistantConfig.h">
|
||||
<Filter>Generated Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="resources.qrc">
|
||||
|
||||
Reference in New Issue
Block a user