0
0
mirror of https://github.com/yse/easy_profiler.git synced 2024-12-28 17:28:14 +08:00

Moved working with files from QFile to std::fstream because QFile has no overwrite mode (old file should be removed first);

Added merging algorithm for block descriptions when refreshing descriptions list.
This commit is contained in:
Victor Zarubkin 2016-10-02 16:17:22 +03:00
parent 4eef4daf30
commit 5de9fcf824

View File

@ -392,23 +392,54 @@ void EasyMainWindow::onSaveFileClicked(bool)
auto filename = QFileDialog::getSaveFileName(this, "Save profiler log", dir, "Profiler Log File (*.prof);;All Files (*.*)"); auto filename = QFileDialog::getSaveFileName(this, "Save profiler log", dir, "Profiler Log File (*.prof);;All Files (*.*)");
if (!filename.isEmpty()) if (!filename.isEmpty())
{ {
auto result = QFile::copy(m_bNetworkFileRegime ? QString(NETWORK_CACHE_FILE) : m_lastFile, filename); bool inOk = false, outOk = false;
if (result) int8_t retry1 = -1;
while (++retry1 < 4)
{
::std::ifstream inFile(m_bNetworkFileRegime ? NETWORK_CACHE_FILE : m_lastFile.toStdString().c_str(), ::std::fstream::binary);
if (!inFile.is_open())
{
::std::this_thread::sleep_for(::std::chrono::milliseconds(500));
continue;
}
inOk = true;
int8_t retry2 = -1;
while (++retry2 < 4)
{
::std::ofstream outFile(filename.toStdString(), ::std::fstream::binary);
if (!outFile.is_open())
{
::std::this_thread::sleep_for(::std::chrono::milliseconds(500));
continue;
}
outFile << inFile.rdbuf();
outOk = true;
break;
}
break;
}
if (outOk)
{ {
m_lastFile = filename;
if (m_bNetworkFileRegime) if (m_bNetworkFileRegime)
{ QFile::remove(QString(NETWORK_CACHE_FILE));
m_lastFile = filename;
m_bNetworkFileRegime = false; m_bNetworkFileRegime = false;
QFile::remove(NETWORK_CACHE_FILE);
} }
} else if (inOk)
else if (m_bNetworkFileRegime)
{ {
QMessageBox::warning(this, "Warning", "Can not save network cahce to file.\nSaving incomplete.", QMessageBox::Close); QMessageBox::warning(this, "Warning", "Can not open destination file.\nSaving incomplete.", QMessageBox::Close);
} }
else else
{ {
QMessageBox::warning(this, "Warning", "Can not copy last file.\nSaving incomplete.", QMessageBox::Close); if (m_bNetworkFileRegime)
QMessageBox::warning(this, "Warning", "Can not open network cache file.\nSaving incomplete.", QMessageBox::Close);
else
QMessageBox::warning(this, "Warning", "Can not open source file.\nSaving incomplete.", QMessageBox::Close);
} }
} }
} }
@ -1094,17 +1125,20 @@ void EasyMainWindow::onGetBlockDescriptionsClicked(bool)
if (m_listener.size() != 0) if (m_listener.size() != 0)
{ {
// Read descriptions from stream // Read descriptions from stream
decltype(EASY_GLOBALS.descriptors) descriptors; decltype(EASY_GLOBALS.descriptors) descriptors;
decltype(m_serializedDescriptors) serializedDescriptors; decltype(m_serializedDescriptors) serializedDescriptors;
::std::stringstream errorMessage; ::std::stringstream errorMessage;
if (readDescriptionsFromStream(m_listener.data(), serializedDescriptors, descriptors, errorMessage)) if (readDescriptionsFromStream(m_listener.data(), serializedDescriptors, descriptors, errorMessage))
{ {
// Merge old and new descriptions
bool cancel = false; bool cancel = false;
const bool doFlush = m_descriptorsNumberInFile != descriptors.size(); const bool doFlush = m_descriptorsNumberInFile > descriptors.size();
if (doFlush && !m_serializedBlocks.empty()) if (doFlush && !m_serializedBlocks.empty())
{ {
auto button = QMessageBox::question(this, "Information", auto button = QMessageBox::question(this, "Information",
QString("New blocks description number = %1\ndiffers from the old one = %2.\nTo avoid possible conflicts\nall profiled data will be deleted.\nPress \"Yes\" to continue or \"No\" to cancel.") QString("New blocks description number = %1\nis less than the old one = %2.\nTo avoid possible conflicts\nall profiled data will be deleted.\nContinue?")
.arg(descriptors.size()) .arg(descriptors.size())
.arg(m_descriptorsNumberInFile), .arg(m_descriptorsNumberInFile),
QMessageBox::Yes, QMessageBox::No); QMessageBox::Yes, QMessageBox::No);
@ -1117,42 +1151,60 @@ void EasyMainWindow::onGetBlockDescriptionsClicked(bool)
if (!cancel) if (!cancel)
{ {
auto oldnumber = m_descriptorsNumberInFile; if (!doFlush && m_descriptorsNumberInFile < EASY_GLOBALS.descriptors.size())
m_descriptorsNumberInFile = static_cast<uint32_t>(descriptors.size());
EASY_GLOBALS.descriptors.swap(descriptors);
m_serializedDescriptors.swap(serializedDescriptors);
if (!doFlush && !m_serializedBlocks.empty() && descriptors.size() > oldnumber)
{ {
// There are dynamically added descriptors, add them to the new list too // There are dynamically added descriptors, add them to the new list too
auto diff = descriptors.size() - oldnumber; auto newnumber = static_cast<decltype(m_descriptorsNumberInFile)>(descriptors.size());
EASY_GLOBALS.descriptors.reserve(EASY_GLOBALS.descriptors.size() + diff); auto size = static_cast<decltype(m_descriptorsNumberInFile)>(EASY_GLOBALS.descriptors.size());
for (decltype(diff) i = 0; i < diff; ++i) auto diff = newnumber - size;
decltype(newnumber) failnumber = 0;
descriptors.reserve(descriptors.size() + EASY_GLOBALS.descriptors.size() - m_descriptorsNumberInFile);
for (auto i = m_descriptorsNumberInFile; i < size; ++i)
{ {
auto desc = descriptors[oldnumber + i]; auto id = EASY_GLOBALS.descriptors[i]->id();
for (decltype(oldnumber) j = 0; j < oldnumber; ++j) if (id < newnumber)
{ descriptors.push_back(descriptors[id]);
if (descriptors[j] == desc) else
{ ++failnumber;
EASY_GLOBALS.descriptors.push_back(EASY_GLOBALS.descriptors[j]);
desc = nullptr;
break;
}
} }
if (desc != nullptr) if (failnumber != 0)
{ {
QMessageBox::warning(this, "Warning", "Conflict with dynamically added block descriptions.\nAll profiled data will be cleared.", QMessageBox::Close); // There are some errors...
clear();
// revert changes
descriptors.resize(newnumber);
// clear all profiled data to avoid conflicts
auto button = QMessageBox::question(this, "Information",
"There are errors while merging block descriptions lists.\nTo avoid possible conflicts\nall profiled data will be deleted.\nContinue?",
QMessageBox::Yes, QMessageBox::No);
if (button == QMessageBox::Yes)
clear(); // Clear all contents because new descriptors list conflicts with old one
else
cancel = true; cancel = true;
break;
} }
if (!cancel && diff != 0)
{
for (auto& b : EASY_GLOBALS.gui_blocks)
{
if (b.tree.node->id() >= m_descriptorsNumberInFile)
b.tree.node->setId(b.tree.node->id() + diff);
}
m_descriptorsNumberInFile = newnumber;
} }
} }
if (!cancel) if (!cancel)
{ {
EASY_GLOBALS.descriptors.swap(descriptors);
m_serializedDescriptors.swap(serializedDescriptors);
if (m_descTreeDialog != nullptr) if (m_descTreeDialog != nullptr)
{ {
#if EASY_GUI_USE_DESCRIPTORS_DOCK_WINDOW != 0 #if EASY_GUI_USE_DESCRIPTORS_DOCK_WINDOW != 0