void CDataStorage::operator+=(CUnit* from) { /* * constructor already positioned the CUnit; make sure our assumption sticks: * * we assume a usage style like this, i.e. += add in order AND BEFORE the next * unit is requested/constructed: * * p1 = new CUnit(store, ...); * ... * store += p1; * p2 = new CUnit(store, ...); * ... * store += p2; * * and we currently FAIL for any other 'mixed' usage pattern, e.g. this will b0rk: * * p1 = new CUnit(store, ...); * p2 = new CUnit(store, ...); * ... * store += p1; * store += p2; */ XL_ASSERT(from->m_Index == (int)store.size() - 1); m_DataSize += from->GetDataSize(); // and 'persist' the data associated with the CUnit from here-on after... // (that way, we can safely 'delete CUnit' and still have the data generated by the CUnit intact) store[(size_t)from->m_Index].MakeSticky(); // and signal that we've made our data 'sticky': XL_ASSERT(from->m_Index >= 0); from->m_Index = -1 ^ from->m_Index; XL_ASSERT(from->m_Index < 0); }
/* * This copy constructor is required as otherwise you'd get nuked by CDataStore * when it has to redimension its vector store when more units than * anticipated are requested: internally, STL detroys each unit during this * vector resize operation, so we'll need to copy the data to new space, especially * when we're m_varying_width !!! */ CUnitStore::CUnitStore(const CUnitStore &src) { if (&src == this) { return; } m_varying_width = src.m_varying_width; m_is_in_use = src.m_is_in_use; m_is_sticky = src.m_is_sticky; m_nDataSize = src.m_nDataSize; if (!m_varying_width) { XL_ASSERT(m_nDataSize <= FIXEDWIDTH_STORAGEUNIT_SIZE); memcpy(&s, &src.s, sizeof(s)); } else { XL_ASSERT(m_is_in_use); XL_ASSERT(src.s.vary.m_nSize > 0); s.vary.m_pData = (unsigned8_t *)malloc(src.s.vary.m_nSize); if (!s.vary.m_pData) { // ret = ERR_UNABLE_TOALLOCATE_MEMORY; m_nDataSize = s.vary.m_nSize = 0; } else { memcpy(s.vary.m_pData, src.s.vary.m_pData, m_nDataSize); s.vary.m_nSize = src.s.vary.m_nSize; } } }
void UpdateApplication::startDownload() // ---------------------------------------------------------------------------- // Start downloading the URL of the Tao file // ---------------------------------------------------------------------------- { IFTRACE(update) debug() << "Downloading: '" << +url.toString() << "'\n"; XL_ASSERT(!reply); XL_ASSERT(!url.isEmpty()); progress->setLabelText(tr("Downloading %1 %2...").arg(appName()) .arg(remoteVer())); progress->show(); state = Downloading; downloadTime.start(); request.setUrl(url); reply = manager->get(request); connect(reply, SIGNAL(metaDataChanged()), this, SLOT(processReply())); connect(reply, SIGNAL(finished()), this, SLOT(downloadFinished())); connect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(downloadProgress(qint64,qint64))); }
CUnitStore& CDataStorage::operator[](signed32_t index) { XL_ASSERT(index != INVALID_STORE_INDEX); XL_ASSERT(index >= 0 ? index < (int)store.size() : 1); XL_ASSERT(index < 0 ? (~index) < (int)store.size() : 1); return index >= 0 ? store[(size_t)index] : store[~(size_t)index]; }
void CUnitStore::Reset() { if (m_varying_width && s.vary.m_pData) { XL_ASSERT(m_is_in_use); free((void *)s.vary.m_pData); } m_varying_width = false; m_is_in_use = false; m_is_sticky = false; m_nDataSize = 0; memset(&s, 0, sizeof(s)); XL_ASSERT(s.vary.m_pData == NULL); }
signed8_t CUnitStore::InitWithValue(unsigned8_t value, size_t size) { signed8_t ret; XL_ASSERT(m_is_in_use); XL_ASSERT(size > 0); ret = Resize(size); if (ret == NO_ERRORS) { memset(GetBuffer(), value, size); SetDataSize(size); } return ret; }
signed8_t CUnitStore::Init(const unsigned8_t *data, size_t size, size_t datasize) { signed8_t ret; XL_ASSERT(m_is_in_use); XL_ASSERT(size > 0); XL_ASSERT(datasize <= size); ret = Resize(size); if (ret == NO_ERRORS) { memcpy(GetBuffer(), data, datasize); SetDataSize(datasize); } return ret; }
void PointCloudVBO::checkGLContext() // ---------------------------------------------------------------------------- // Do what's needed if GL context has changed // ---------------------------------------------------------------------------- { if (QGLContext::currentContext() != context) { IFTRACE(pointcloud) debug() << "GL context changed\n"; // Re-create VBO(s) genPointBuffer(); if (colored()) genColorBuffer(); if (optimized) { IFTRACE(pointcloud) debug() << "GL context changed on optimized cloud\n"; XL_ASSERT(file != "" || nbRandom != 0); if (file != "") { IFTRACE(pointcloud) debug() << "Reloading file\n"; text f = file; clear(); loadData(f, sep, xi, yi, zi, colorScale, ri, gi, bi, ai); } else if (nbRandom != 0) { IFTRACE(pointcloud) debug() << "Re-creating random points\n"; unsigned n = nbRandom; clear(); randomPoints(n, coloredRandom); } optimized = false; XL_ASSERT(!dirty); } else updateVbo(); context = QGLContext::currentContext(); } }
signed8_t CUnitStore::Prepare(size_t minimum_size) { signed8_t ret = NO_ERRORS; // allocate space in the 'variable sized store' if we cannot fit in a fixed-width unit: if (minimum_size <= FIXEDWIDTH_STORAGEUNIT_SIZE) { m_varying_width = false; m_is_in_use = true; m_is_sticky = false; m_nDataSize = 0; memset(&s, 0, sizeof(s)); // range: 0 ... +oo } else { m_varying_width = true; m_is_in_use = true; m_is_sticky = false; m_nDataSize = 0; memset(&s, 0, sizeof(s)); XL_ASSERT(s.vary.m_pData == NULL); if (minimum_size > 0) { s.vary.m_pData = (unsigned8_t *)malloc(minimum_size); if (!s.vary.m_pData) { ret = ERR_UNABLE_TOALLOCATE_MEMORY; minimum_size = 0; } s.vary.m_nSize = minimum_size; } } return ret; }
CUnitStore::CUnitStore() : m_varying_width(false), m_is_in_use(false), m_is_sticky(false), m_nDataSize(0) { memset(&s, 0, sizeof(s)); XL_ASSERT(s.vary.m_pData == NULL); }
void PointCloudVBO::genColorBuffer() // ---------------------------------------------------------------------------- // Allocate new VBO for colors // ---------------------------------------------------------------------------- { XL_ASSERT(colored()); GL.GenBuffers(1, &colorVbo); IFTRACE(pointcloud) debug() << "Allocated VBO #" << colorVbo << " for colors\n"; }
void PerLayoutStatistics::endDraw(XL::Tree *body) // ---------------------------------------------------------------------------- // End of drawing phase timing // ---------------------------------------------------------------------------- { if (body) { PerLayoutStatistics *info = body->GetInfo<PerLayoutStatistics>(); XL_ASSERT(info); info->totalDrawTime += info->drawTime.nsecsElapsed(); } }
void PerLayoutStatistics::endExec(XL::Tree *body) // ---------------------------------------------------------------------------- // End of execution phase timing // ---------------------------------------------------------------------------- { if (body) { PerLayoutStatistics *info = body->GetInfo<PerLayoutStatistics>(); XL_ASSERT(info); info->totalExecTime += info->execTime.nsecsElapsed(); } }
void PointCloudVBO::removePoints(unsigned n) // ---------------------------------------------------------------------------- // Drop n points from the cloud // ---------------------------------------------------------------------------- { XL_ASSERT(!optimized); PointCloud::removePoints(n); if (useVbo()) updateVbo(); noOptimize = true; }
signed8_t CUnitStore::Resize(size_t newlen) { signed8_t ret = NO_ERRORS; XL_ASSERT(m_is_in_use); XL_ASSERT(newlen > 0); XL_ASSERT(newlen >= m_nDataSize); if (!m_varying_width) { if (newlen > FIXEDWIDTH_STORAGEUNIT_SIZE) { // turn this node into a varying-width unit store: unsigned8_t *p = (unsigned8_t *)malloc(newlen); if (!p) { ret = ERR_UNABLE_TOALLOCATE_MEMORY; newlen = 0; } else { memcpy(p, s.fixed.m_pData, m_nDataSize); } s.vary.m_pData = p; s.vary.m_nSize = newlen; m_varying_width = true; } } else { if (newlen != s.vary.m_nSize) { if (!s.vary.m_pData) { XL_ASSERT(m_nDataSize == 0); s.vary.m_pData = (unsigned8_t *)malloc(newlen); } else { s.vary.m_pData = (unsigned8_t *)realloc((void *)s.vary.m_pData, newlen); } if (!s.vary.m_pData) { ret = ERR_UNABLE_TOALLOCATE_MEMORY; newlen = 0; } s.vary.m_nSize = newlen; } } return ret; }
bool DDEWidget::ddeInitiate(MSG* message, long* result) // ---------------------------------------------------------------------------- // Process a Windows WM_DDE_INITIATE message // ---------------------------------------------------------------------------- { if ((0 != LOWORD(message->lParam)) && (0 != HIWORD(message->lParam)) && (LOWORD(message->lParam) == appAtom) && (HIWORD(message->lParam) == systemTopicAtom)) { // make duplicates of the incoming atoms (really adding a reference) wchar_t atomName[_MAX_PATH]; bool ok; ok = (::GlobalGetAtomNameW(appAtom, atomName, _MAX_PATH-1) != 0); XL_ASSERT(ok); if (ok) ok = (::GlobalAddAtomW(atomName) == appAtom); XL_ASSERT(ok); if (ok) ok = (::GlobalGetAtomNameW(systemTopicAtom, atomName, _MAX_PATH-1) != 0); XL_ASSERT(ok); if (ok) ok = (::GlobalAddAtomW(atomName) == systemTopicAtom); XL_ASSERT(ok); if (!ok) return false; // send the WM_DDE_ACK (caller will delete duplicate atoms) ::SendMessage((HWND)message->wParam, WM_DDE_ACK, (WPARAM)winId(), MAKELPARAM(appAtom, systemTopicAtom)); } *result = 0; return true; }
/* * Clip to Max Data Size, as the rest of the record will be placed in continue records. * This means that we will duplicate data. Its possible to create a new UnitStorage that takes just a pointer; * however, these records are quite rare, so why go to the effort. */ size_t CDataStorage::Clip(CUnit* unit) { XL_ASSERT(unit == m_FlushStack.back()); CRecord *record = (CRecord *)unit; // Use this record, but only record the first big chunk record->SetRecordLength(MAX_RECORD_SIZE); // No way to directly change the size of a Unit's storage space, so we fake it by telling the UnitStore that its now smaller CUnitStore& unitStore = (*this)[record->GetIndex()]; size_t realSize = unitStore.GetDataSize() - RECORD_HEADER_SIZE; unitStore.SetDataSize( MAX_RECORD_SIZE + RECORD_HEADER_SIZE ); return realSize; }
void UpdateApplication::saveDownloadedData() // ---------------------------------------------------------------------------- // Finish download: write data to file, show confirmation, cleanup // ---------------------------------------------------------------------------- { XL_ASSERT(file); file->write(reply->readAll()); file->close(); showDownloadSuccessful(); delete file; file = NULL; reply->deleteLater(); reply = NULL; progress->close(); state = Idle; }
bool DDEWidget::ddeExecute(MSG* message, long* result) // ---------------------------------------------------------------------------- // Process a Windows WM_DDE_EXECUTE message // ---------------------------------------------------------------------------- { // unpack the DDE message UINT_PTR unused; HGLOBAL hData; bool ok; //IA64: Assume DDE LPARAMs are still 32-bit ok = (::UnpackDDElParam(WM_DDE_EXECUTE, message->lParam, &unused, (UINT_PTR*)&hData) != 0); XL_ASSERT(ok); if (!ok) return false; QString command = QString::fromWCharArray((LPCWSTR)::GlobalLock(hData)); ::GlobalUnlock(hData); // acknowledge now - before attempting to execute ::PostMessage((HWND)message->wParam, WM_DDE_ACK, (WPARAM)winId(), //IA64: Assume DDE LPARAMs are still 32-bit ReuseDDElParam(message->lParam, WM_DDE_EXECUTE, WM_DDE_ACK, (UINT)0x8000, (UINT_PTR)hData)); // don't execute the command when the window is disabled if (!isEnabled()) { *result = 0; return true; } QRegExp regCommand("^\\[(\\w+)\\((.*)\\)\\]$"); if(regCommand.exactMatch(command)) { executeDdeCommand(regCommand.cap(1), regCommand.cap(2)); } *result = 0; return true; }
void PointCloudVBO::updateVbo() // ---------------------------------------------------------------------------- // Take into account a change in point data // ---------------------------------------------------------------------------- { XL_ASSERT(!optimized); if (QThread::currentThread() != qApp->thread()) { // OpenGL functions may be called only from the main thread, which // owns the GL context IFTRACE(pointcloud) debug() << "Not updating VBO (not main thread)\n"; return; } IFTRACE(pointcloud) debug() << "Updating VBO #" << vbo << " (" << size() << " points)\n"; GL.BindBuffer(GL_ARRAY_BUFFER, vbo); GL.BufferData(GL_ARRAY_BUFFER, size()*sizeof(Point), &points[0].x, GL_STATIC_DRAW); GL.BindBuffer(GL_ARRAY_BUFFER, 0); if (colored()) { if (colorVbo == 0) genColorBuffer(); IFTRACE(pointcloud) debug() << "Updating VBO #" << colorVbo << " (" << size() << " colors)\n"; GL.BindBuffer(GL_ARRAY_BUFFER, colorVbo); GL.BufferData(GL_ARRAY_BUFFER, size()*sizeof(Color), &colors[0].r, GL_STATIC_DRAW); GL.BindBuffer(GL_ARRAY_BUFFER, 0); } dirty = false; }
void UpdateApplication::readIniFile() // ---------------------------------------------------------------------------- // Get version, name and path of latest update from received .ini file // ---------------------------------------------------------------------------- { XL_ASSERT(file); IFTRACE(update) { file->open(QIODevice::ReadOnly | QIODevice::Text); while (file->bytesAvailable()) debug() << " " << +QString(file->readLine()); file->close(); } QSettings settings(file->fileName(), QSettings::IniFormat); settings.setIniCodec("UTF-8"); remoteVersion = settings.value("version", "-1").toDouble(); // Read optional, localized description text // For instance for french: read description-fr then description QString descKey = QString("description-%1").arg(TaoApp->lang); description = settings.value(descKey, settings.value("description")).toString(); settings.beginGroup(target); url.setUrl(settings.value(edition).toString()); settings.endGroup(); IFTRACE(update) { debug() << "Remote version is " << +remoteVersion << " download URL: '" << +url.toString() << "'\n"; if (!description.isEmpty()) debug() << "Description string for update dialog:\n" << +description << "\n"; } }
CUnitStore::~CUnitStore() { Reset(); XL_ASSERT(s.vary.m_pData == NULL); }
void UpdateApplication::downloadFinished() // ---------------------------------------------------------------------------- // Process downloaded data reply // ---------------------------------------------------------------------------- { if (state == NetworkErrorCheck || state == NetworkErrorDownload) { QString details = reply->errorString(); reply->abort(); progress->close(); if (state == NetworkErrorDownload || show) { QString msg = tr("<h3>Network error</h3>"); QString info = tr("<p>Impossible to obtain update information.</p>" "<p>Please make sure that you are connected to " "the Internet and try again.</p>"); QMessageBox box(TaoApp->windowWidget()); setBoxMinimumWidth(box, 400); box.setIconPixmap(connectionErrorIcon); box.setWindowTitle(dialogTitle); box.setText(msg); box.setInformativeText(info); box.setDetailedText(details); box.setStandardButtons(QMessageBox::Ok); box.exec(); } return; } if (code != 200) return; bool updateAvailable = false; qint64 pid = 0; QString name; switch (state) { case WaitingForUpdate: // Save and process the update information we have just received progress->hide(); XL_ASSERT(!file); pid = QCoreApplication::applicationPid(); name = QString("tao_update.%1").arg(pid); file = new QFile(QDir::temp().filePath(name)); if (!file->open(QIODevice::WriteOnly | QIODevice::Truncate)) { IFTRACE(update) debug() << "Failed to open: " << +file->fileName() << "\n"; delete file; file = NULL; return; } file->write(reply->readAll()); file->close(); reply->deleteLater(); reply = NULL; readIniFile(); file->remove(); delete file; file = NULL; setLastChecked(QDateTime::currentDateTime()); // Propose to update if current version is older than the remote one updateAvailable = (version < remoteVersion) && !url.isEmpty(); IFTRACE(update) debug() << "Update available: " << updateAvailable << " (local " << version << " remote " << remoteVersion << ")\n"; if (updateAvailable) { bool ok = false; double min = QSettings().value("AppUpdatePromptMinVersion", -1.0) .toDouble(&ok); if (!ok) min = -1.0; if (show || remoteVersion > min) { if (remoteVersion > min) { // Remember that user was prompted to download this // version. He/she will not be prompted again on application // startup, unless a newer version exists. QSettings().setValue("AppUpdatePromptMinVersion", remoteVersion); IFTRACE2(update, settings) debug() << "Saving AppUpdatePromptMinVersion=" << remoteVersion << "\n"; } // Show update dialog QString msg = tr("<h3>Update available</h3>"); QString info = tr("<p>%1 version %2 is available." " Do you want to download it now?</p>") .arg(appName()).arg(remoteVer()); QMessageBox box(TaoApp->windowWidget()); setBoxMinimumWidth(box, 400); box.setIconPixmap(downloadIcon); box.setWindowTitle(dialogTitle); box.setText(msg); box.setInformativeText(info); if (!description.isEmpty()) box.setDetailedText(description); box.setStandardButtons(QMessageBox::Yes | QMessageBox::No); if (box.exec() == QMessageBox::Yes) { startDownload(); break; } } else { IFTRACE(update) debug() << "Update available dialog not shown due to " "AppUpdatePromptMinVersion=" << min << "\n"; } } else { if (show) showNoUpdateAvailable(); } progress->close(); break; case Downloading: IFTRACE(update) debug() << "Download finished\n"; progress->hide(); state = Downloaded; if (file) saveDownloadedData(); break; default: break; } }
bool UpdateApplication::createFile() // ---------------------------------------------------------------------------- // Create the update file // ---------------------------------------------------------------------------- { XL_ASSERT(!file); // Keep the name of the remote file in the URL QString fileName = QFileInfo(url.path()).fileName(); // Choose folder #if QT_VERSION >= 0x050000 // Thank you Qt5 for this insanity, just in case we have several ~/Desktop QString desktop = ""; QStringList desktops = QStandardPaths::standardLocations( QStandardPaths::DesktopLocation); if (desktops.size() >= 1) desktop = desktops[0]; #else QString desktop = QDesktopServices::storageLocation(QDesktopServices::DesktopLocation); #endif QString folder = QFileDialog::getExistingDirectory(NULL, tr("Select destination folder"), desktop); if (!folder.isEmpty()) { // Set complete filename QString completeFileName = folder + "/" + fileName; file = new QFile(completeFileName); if (file->exists()) { QString msg = tr("<h3>File exists</h3>"); QString info = tr("<p>The selected folder already contains a file " "called <b>%1</b>.</p>" "<p>Save anyway?</p>").arg(fileName); QMessageBox box(TaoApp->windowWidget()); setBoxMinimumWidth(box, 400); box.setIcon(QMessageBox::Warning); box.setWindowTitle(dialogTitle); box.setText(msg); box.setInformativeText(info); box.setStandardButtons(QMessageBox::Yes | QMessageBox::No); box.setDefaultButton(QMessageBox::No); if (box.exec() == QMessageBox::No) { delete file; file = NULL; return false; } } if (!file->open(QIODevice::WriteOnly | QIODevice::Truncate)) { IFTRACE(update) debug() << "Could not open file for writing: '" << +completeFileName << "' error: " << +file->errorString() << "\n"; QString msg = tr("<h3>Write error</h3>"); QString info = tr("<p>The upgrade cannot be saved to <b>%1</b>.</p>") .arg(fileName); QString details = file->errorString(); QMessageBox box(TaoApp->windowWidget()); setBoxMinimumWidth(box, 400); box.setIcon(QMessageBox::Critical); box.setWindowTitle(dialogTitle); box.setText(msg); box.setInformativeText(info); box.setDetailedText(details); box.setStandardButtons(QMessageBox::Ok); box.exec(); delete file; file = NULL; return false; } IFTRACE(update) debug() << "Save to: '" << +completeFileName << "'\n"; if (state == Downloaded) { // Download completed while user was still choosing file path saveDownloadedData(); } return true; } return false; }
void CDataStorage::FlushEm(unsigned16_t backpatch_level) { /* * delete units which don't need to live any longer. * * In the same loop, we shrink the 'stack' for * future speed and to keep storage requirements in check. */ //printf("FLUSH-EM %d\n", backpatch_level); UnitList_Itor_t start = m_FlushStack.begin(); if (m_FlushLastEndLevel == backpatch_level && backpatch_level != BACKPATCH_LEVEL_EVERYONE // do not use cached position when 'flushing all' //&& m_FlushLastEndPos != m_FlushStack.begin() && m_FlushLastEndPos != m_FlushStack.size()) { //.end()) XL_ASSERT(start != m_FlushStack.end()); start = m_FlushStack.begin() + (signed32_t)m_FlushLastEndPos; XL_ASSERT(m_FlushLastEndPos <= m_FlushStack.size()); XL_ASSERT(start != m_FlushStack.end()); start++; } UnitList_Itor_t j = start; size_t cnt = 0; size_t cntleft = 0; for (UnitList_Itor_t i = j; i != m_FlushStack.end(); i++) { CUnit *up = *i; if (up->m_Backpatching_Level <= backpatch_level) { XL_ASSERT(up != NULL); delete up; (*i) = NULL; cnt++; continue; } XL_ASSERT(up->m_Backpatching_Level <= 4); // do we need to move-copy the unit reference down as part of a shrink operation? if (i != j) { (*j) = up; } j++; cntleft++; } size_t count = (size_t)(j - m_FlushStack.begin()); #if OLE_DEBUG std::cerr << "number of records deleted: " << cnt << ", left: " << cntleft << ", new.size: " << count << std::endl; #endif m_FlushStack.resize(count); XL_ASSERT(m_FlushStack.size() == count); // remember for the next time around m_FlushLastEndLevel = backpatch_level; j = m_FlushStack.end(); if (m_FlushStack.size() > 0) { j--; } else { #if OLE_DEBUG std::cerr << "empty!" << std::endl; #endif } m_FlushLastEndPos = (size_t)(j - m_FlushStack.begin()); }