Threaded the storage of the scene. Asynchronous reading of the previous and next scene to be stored on cache.

preferencesAboutTextFull
-f 11 years ago
parent 817b69fd4f
commit 61e588bb94
  1. 495
      src/adaptors/UBSvgSubsetAdaptor.cpp
  2. 5
      src/adaptors/UBSvgSubsetAdaptor.h
  3. 51
      src/core/UBPersistenceManager.cpp
  4. 9
      src/core/UBPersistenceManager.h
  5. 69
      src/core/UBPersistenceWorker.cpp
  6. 68
      src/core/UBPersistenceWorker.h
  7. 6
      src/core/core.pri

@ -256,6 +256,29 @@ UBGraphicsScene* UBSvgSubsetAdaptor::loadScene(UBDocumentProxy* proxy, const int
} }
QByteArray UBSvgSubsetAdaptor::loadSceneAsText(UBDocumentProxy* proxy, const int pageIndex)
{
QString fileName = proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.svg", pageIndex);
qDebug() << fileName;
QFile file(fileName);
if (file.exists())
{
if (!file.open(QIODevice::ReadOnly))
{
qWarning() << "Cannot open file " << fileName << " for reading ...";
return "";
}
return file.readAll();
file.close();
}
return "";
}
QUuid UBSvgSubsetAdaptor::sceneUuid(UBDocumentProxy* proxy, const int pageIndex) QUuid UBSvgSubsetAdaptor::sceneUuid(UBDocumentProxy* proxy, const int pageIndex)
{ {
QString fileName = proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.svg", pageIndex); QString fileName = proxy->persistencePath() + UBFileSystemUtils::digitFileFormat("/page%1.svg", pageIndex);
@ -1019,307 +1042,299 @@ void UBSvgSubsetAdaptor::UBSvgSubsetWriter::writeSvgElement()
bool UBSvgSubsetAdaptor::UBSvgSubsetWriter::persistScene(int pageIndex) bool UBSvgSubsetAdaptor::UBSvgSubsetWriter::persistScene(int pageIndex)
{ {
Q_UNUSED(pageIndex); Q_UNUSED(pageIndex);
if (mScene->isModified())
{
//Creating dom structure to store information //Creating dom structure to store information
QDomDocument groupDomDocument; QDomDocument groupDomDocument;
QDomElement groupRoot = groupDomDocument.createElement(tGroups); QDomElement groupRoot = groupDomDocument.createElement(tGroups);
groupDomDocument.appendChild(groupRoot); groupDomDocument.appendChild(groupRoot);
QBuffer buffer; QBuffer buffer;
buffer.open(QBuffer::WriteOnly); buffer.open(QBuffer::WriteOnly);
mXmlWriter.setDevice(&buffer); mXmlWriter.setDevice(&buffer);
mXmlWriter.setAutoFormatting(true); mXmlWriter.setAutoFormatting(true);
mXmlWriter.writeStartDocument(); mXmlWriter.writeStartDocument();
mXmlWriter.writeDefaultNamespace(nsSvg); mXmlWriter.writeDefaultNamespace(nsSvg);
mXmlWriter.writeNamespace(nsXLink, "xlink"); mXmlWriter.writeNamespace(nsXLink, "xlink");
mXmlWriter.writeNamespace(UBSettings::uniboardDocumentNamespaceUri, "ub"); mXmlWriter.writeNamespace(UBSettings::uniboardDocumentNamespaceUri, "ub");
mXmlWriter.writeNamespace(nsXHtml, "xhtml"); mXmlWriter.writeNamespace(nsXHtml, "xhtml");
writeSvgElement(); writeSvgElement();
// Get the items from the scene // Get the items from the scene
QList<QGraphicsItem*> items = mScene->items(); QList<QGraphicsItem*> items = mScene->items();
int strokes = 0; int polygons = 0; int strokes = 0; int polygons = 0;
foreach(QGraphicsItem *item, items) { foreach(QGraphicsItem *item, items) {
if (item->type() == UBGraphicsPolygonItem::Type) { if (item->type() == UBGraphicsPolygonItem::Type) {
polygons++; polygons++;
} else if (item->type() == UBGraphicsStrokesGroup::Type) { } else if (item->type() == UBGraphicsStrokesGroup::Type) {
strokes++; strokes++;
}
} }
qDebug() << "---Strokes count" << strokes << "Polygons count" << polygons; }
qDebug() << "---Strokes count" << strokes << "Polygons count" << polygons;
qSort(items.begin(), items.end(), itemZIndexComp); qSort(items.begin(), items.end(), itemZIndexComp);
UBGraphicsStroke *openStroke = 0; UBGraphicsStroke *openStroke = 0;
bool groupHoldsInfo = false; bool groupHoldsInfo = false;
while (!items.empty()) while (!items.empty())
{ {
QGraphicsItem *item = items.takeFirst(); QGraphicsItem *item = items.takeFirst();
// Is the item a strokes group? // Is the item a strokes group?
UBGraphicsStrokesGroup* strokesGroupItem = qgraphicsitem_cast<UBGraphicsStrokesGroup*>(item); UBGraphicsStrokesGroup* strokesGroupItem = qgraphicsitem_cast<UBGraphicsStrokesGroup*>(item);
if(strokesGroupItem && strokesGroupItem->isVisible()){ if(strokesGroupItem && strokesGroupItem->isVisible()){
// Add the polygons // Add the polygons
foreach(QGraphicsItem* item, strokesGroupItem->childItems()){ foreach(QGraphicsItem* item, strokesGroupItem->childItems()){
UBGraphicsPolygonItem* poly = qgraphicsitem_cast<UBGraphicsPolygonItem*>(item); UBGraphicsPolygonItem* poly = qgraphicsitem_cast<UBGraphicsPolygonItem*>(item);
if(NULL != poly){ if(NULL != poly){
polygonItemToSvgPolygon(poly, true); polygonItemToSvgPolygon(poly, true);
items.removeOne(poly); items.removeOne(poly);
}
} }
} }
}
// Is the item a polygon? // Is the item a polygon?
UBGraphicsPolygonItem *polygonItem = qgraphicsitem_cast<UBGraphicsPolygonItem*> (item); UBGraphicsPolygonItem *polygonItem = qgraphicsitem_cast<UBGraphicsPolygonItem*> (item);
if (polygonItem && polygonItem->isVisible()) if (polygonItem && polygonItem->isVisible())
{
UBGraphicsStroke* currentStroke = polygonItem->stroke();
if (openStroke && (currentStroke != openStroke))
{ {
UBGraphicsStroke* currentStroke = polygonItem->stroke(); mXmlWriter.writeEndElement(); //g
if (openStroke && (currentStroke != openStroke)) openStroke = 0;
{ groupHoldsInfo = false;
mXmlWriter.writeEndElement(); //g }
openStroke = 0;
groupHoldsInfo = false;
}
bool firstPolygonInStroke = currentStroke && !openStroke; bool firstPolygonInStroke = currentStroke && !openStroke;
if (firstPolygonInStroke) if (firstPolygonInStroke)
{ {
mXmlWriter.writeStartElement("g"); mXmlWriter.writeStartElement("g");
openStroke = currentStroke; openStroke = currentStroke;
QMatrix matrix = item->sceneMatrix(); QMatrix matrix = item->sceneMatrix();
if (!matrix.isIdentity()) if (!matrix.isIdentity())
mXmlWriter.writeAttribute("transform", toSvgTransform(matrix)); mXmlWriter.writeAttribute("transform", toSvgTransform(matrix));
UBGraphicsStroke* stroke = dynamic_cast<UBGraphicsStroke* >(currentStroke); UBGraphicsStroke* stroke = dynamic_cast<UBGraphicsStroke* >(currentStroke);
if (stroke) if (stroke)
{ {
QColor colorOnDarkBackground = polygonItem->colorOnDarkBackground(); QColor colorOnDarkBackground = polygonItem->colorOnDarkBackground();
QColor colorOnLightBackground = polygonItem->colorOnLightBackground(); QColor colorOnLightBackground = polygonItem->colorOnLightBackground();
if (colorOnDarkBackground.isValid() && colorOnLightBackground.isValid()) if (colorOnDarkBackground.isValid() && colorOnLightBackground.isValid())
{ {
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "z-value" mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "z-value"
, QString("%1").arg(polygonItem->zValue())); , QString("%1").arg(polygonItem->zValue()));
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri
, "fill-on-dark-background", colorOnDarkBackground.name()); , "fill-on-dark-background", colorOnDarkBackground.name());
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri
, "fill-on-light-background", colorOnLightBackground.name()); , "fill-on-light-background", colorOnLightBackground.name());
groupHoldsInfo = true; groupHoldsInfo = true;
}
} }
}
if (stroke && !stroke->hasPressure()) if (stroke && !stroke->hasPressure())
{ {
strokeToSvgPolyline(stroke, groupHoldsInfo); strokeToSvgPolyline(stroke, groupHoldsInfo);
//we can dequeue all polygons belonging to that stroke //we can dequeue all polygons belonging to that stroke
foreach(UBGraphicsPolygonItem* gi, stroke->polygons()) foreach(UBGraphicsPolygonItem* gi, stroke->polygons())
{ {
items.removeOne(gi); items.removeOne(gi);
}
continue;
} }
continue;
} }
if (polygonItem->isNominalLine())
polygonItemToSvgLine(polygonItem, groupHoldsInfo);
else
polygonItemToSvgPolygon(polygonItem, groupHoldsInfo);
continue;
} }
if (openStroke) if (polygonItem->isNominalLine())
{ polygonItemToSvgLine(polygonItem, groupHoldsInfo);
mXmlWriter.writeEndElement(); //g else
groupHoldsInfo = false; polygonItemToSvgPolygon(polygonItem, groupHoldsInfo);
openStroke = 0;
}
// Is the item a picture? continue;
UBGraphicsPixmapItem *pixmapItem = qgraphicsitem_cast<UBGraphicsPixmapItem*> (item); }
if (pixmapItem && pixmapItem->isVisible())
{
pixmapItemToLinkedImage(pixmapItem);
continue;
}
// Is the item a shape? if (openStroke)
UBGraphicsSvgItem *svgItem = qgraphicsitem_cast<UBGraphicsSvgItem*> (item); {
if (svgItem && svgItem->isVisible()) mXmlWriter.writeEndElement(); //g
{ groupHoldsInfo = false;
svgItemToLinkedSvg(svgItem); openStroke = 0;
continue; }
}
// Is the item a picture?
UBGraphicsPixmapItem *pixmapItem = qgraphicsitem_cast<UBGraphicsPixmapItem*> (item);
if (pixmapItem && pixmapItem->isVisible())
{
pixmapItemToLinkedImage(pixmapItem);
continue;
}
UBGraphicsMediaItem *mediaItem = qgraphicsitem_cast<UBGraphicsMediaItem*> (item); // Is the item a shape?
UBGraphicsSvgItem *svgItem = qgraphicsitem_cast<UBGraphicsSvgItem*> (item);
if (svgItem && svgItem->isVisible())
{
svgItemToLinkedSvg(svgItem);
continue;
}
if (mediaItem && mediaItem->isVisible()) UBGraphicsMediaItem *mediaItem = qgraphicsitem_cast<UBGraphicsMediaItem*> (item);
{
if (UBGraphicsMediaItem::mediaType_Video == mediaItem->getMediaType())
videoItemToLinkedVideo(mediaItem);
else
audioItemToLinkedAudio(mediaItem);
continue;
}
// Is the item an app? if (mediaItem && mediaItem->isVisible())
UBGraphicsAppleWidgetItem *appleWidgetItem = qgraphicsitem_cast<UBGraphicsAppleWidgetItem*> (item); {
if (appleWidgetItem && appleWidgetItem->isVisible()) if (UBGraphicsMediaItem::mediaType_Video == mediaItem->getMediaType())
{ videoItemToLinkedVideo(mediaItem);
graphicsAppleWidgetToSvg(appleWidgetItem); else
continue; audioItemToLinkedAudio(mediaItem);
} continue;
}
// Is the item a W3C? // Is the item an app?
UBGraphicsW3CWidgetItem *w3cWidgetItem = qgraphicsitem_cast<UBGraphicsW3CWidgetItem*> (item); UBGraphicsAppleWidgetItem *appleWidgetItem = qgraphicsitem_cast<UBGraphicsAppleWidgetItem*> (item);
if (w3cWidgetItem && w3cWidgetItem->isVisible()) if (appleWidgetItem && appleWidgetItem->isVisible())
{ {
graphicsW3CWidgetToSvg(w3cWidgetItem); graphicsAppleWidgetToSvg(appleWidgetItem);
continue; continue;
} }
// Is the item a PDF? // Is the item a W3C?
UBGraphicsPDFItem *pdfItem = qgraphicsitem_cast<UBGraphicsPDFItem*> (item); UBGraphicsW3CWidgetItem *w3cWidgetItem = qgraphicsitem_cast<UBGraphicsW3CWidgetItem*> (item);
if (pdfItem && pdfItem->isVisible()) if (w3cWidgetItem && w3cWidgetItem->isVisible())
{ {
pdfItemToLinkedPDF(pdfItem); graphicsW3CWidgetToSvg(w3cWidgetItem);
continue; continue;
} }
// Is the item a text? // Is the item a PDF?
UBGraphicsTextItem *textItem = qgraphicsitem_cast<UBGraphicsTextItem*> (item); UBGraphicsPDFItem *pdfItem = qgraphicsitem_cast<UBGraphicsPDFItem*> (item);
if (textItem && textItem->isVisible()) if (pdfItem && pdfItem->isVisible())
{ {
textItemToSvg(textItem); pdfItemToLinkedPDF(pdfItem);
continue; continue;
} }
// Is the item a curtain? // Is the item a text?
UBGraphicsCurtainItem *curtainItem = qgraphicsitem_cast<UBGraphicsCurtainItem*> (item); UBGraphicsTextItem *textItem = qgraphicsitem_cast<UBGraphicsTextItem*> (item);
if (curtainItem && curtainItem->isVisible()) if (textItem && textItem->isVisible())
{ {
curtainItemToSvg(curtainItem); textItemToSvg(textItem);
continue; continue;
} }
// Is the item a ruler? // Is the item a curtain?
UBGraphicsRuler *ruler = qgraphicsitem_cast<UBGraphicsRuler*> (item); UBGraphicsCurtainItem *curtainItem = qgraphicsitem_cast<UBGraphicsCurtainItem*> (item);
if (ruler && ruler->isVisible()) if (curtainItem && curtainItem->isVisible())
{ {
rulerToSvg(ruler); curtainItemToSvg(curtainItem);
continue; continue;
} }
// Is the item a cache? // Is the item a ruler?
UBGraphicsCache* cache = qgraphicsitem_cast<UBGraphicsCache*>(item); UBGraphicsRuler *ruler = qgraphicsitem_cast<UBGraphicsRuler*> (item);
if(cache && cache->isVisible()) if (ruler && ruler->isVisible())
{ {
cacheToSvg(cache); rulerToSvg(ruler);
continue; continue;
} }
// Is the item a compass // Is the item a cache?
UBGraphicsCompass *compass = qgraphicsitem_cast<UBGraphicsCompass*> (item); UBGraphicsCache* cache = qgraphicsitem_cast<UBGraphicsCache*>(item);
if (compass && compass->isVisible()) if(cache && cache->isVisible())
{ {
compassToSvg(compass); cacheToSvg(cache);
continue; continue;
} }
// Is the item a protractor? // Is the item a compass
UBGraphicsProtractor *protractor = qgraphicsitem_cast<UBGraphicsProtractor*> (item); UBGraphicsCompass *compass = qgraphicsitem_cast<UBGraphicsCompass*> (item);
if (protractor && protractor->isVisible()) if (compass && compass->isVisible())
{ {
protractorToSvg(protractor); compassToSvg(compass);
continue; continue;
} }
// Is the item a triangle? // Is the item a protractor?
UBGraphicsTriangle *triangle = qgraphicsitem_cast<UBGraphicsTriangle*> (item); UBGraphicsProtractor *protractor = qgraphicsitem_cast<UBGraphicsProtractor*> (item);
if (triangle && triangle->isVisible()) if (protractor && protractor->isVisible())
{ {
triangleToSvg(triangle); protractorToSvg(protractor);
continue; continue;
} }
// Is the item a group? // Is the item a triangle?
UBGraphicsGroupContainerItem *groupItem = qgraphicsitem_cast<UBGraphicsGroupContainerItem*>(item); UBGraphicsTriangle *triangle = qgraphicsitem_cast<UBGraphicsTriangle*> (item);
if (groupItem && groupItem->isVisible()) if (triangle && triangle->isVisible())
{ {
persistGroupToDom(groupItem, &groupRoot, &groupDomDocument); triangleToSvg(triangle);
continue; continue;
}
} }
if (openStroke) // Is the item a group?
UBGraphicsGroupContainerItem *groupItem = qgraphicsitem_cast<UBGraphicsGroupContainerItem*>(item);
if (groupItem && groupItem->isVisible())
{ {
mXmlWriter.writeEndElement(); persistGroupToDom(groupItem, &groupRoot, &groupDomDocument);
groupHoldsInfo = false; continue;
openStroke = 0;
} }
}
//writing group data if (openStroke)
if (groupRoot.hasChildNodes()) { {
mXmlWriter.writeStartElement(tGroups); mXmlWriter.writeEndElement();
QDomElement curElement = groupRoot.firstChildElement(); groupHoldsInfo = false;
while (!curElement.isNull()) { openStroke = 0;
if (curElement.hasAttribute(aId)) { }
mXmlWriter.writeStartElement(curElement.tagName());
mXmlWriter.writeAttribute(aId, curElement.attribute(aId)); //writing group data
if(curElement.hasAttribute("locked")){ if (groupRoot.hasChildNodes()) {
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri,"locked",curElement.attribute("locked")); mXmlWriter.writeStartElement(tGroups);
} QDomElement curElement = groupRoot.firstChildElement();
QDomElement curSubElement = curElement.firstChildElement(); while (!curElement.isNull()) {
while (!curSubElement.isNull()) { if (curElement.hasAttribute(aId)) {
if (curSubElement.hasAttribute(aId)) { mXmlWriter.writeStartElement(curElement.tagName());
mXmlWriter.writeStartElement(curSubElement.tagName()); mXmlWriter.writeAttribute(aId, curElement.attribute(aId));
mXmlWriter.writeAttribute(aId, curSubElement.attribute(aId)); if(curElement.hasAttribute("locked")){
mXmlWriter.writeEndElement(); mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri,"locked",curElement.attribute("locked"));
curSubElement = curSubElement.nextSiblingElement(); }
} QDomElement curSubElement = curElement.firstChildElement();
while (!curSubElement.isNull()) {
if (curSubElement.hasAttribute(aId)) {
mXmlWriter.writeStartElement(curSubElement.tagName());
mXmlWriter.writeAttribute(aId, curSubElement.attribute(aId));
mXmlWriter.writeEndElement();
curSubElement = curSubElement.nextSiblingElement();
} }
mXmlWriter.writeEndElement();
} }
curElement = curElement.nextSiblingElement(); mXmlWriter.writeEndElement();
} }
mXmlWriter.writeEndElement(); curElement = curElement.nextSiblingElement();
} }
mXmlWriter.writeEndElement();
}
mXmlWriter.writeEndDocument(); mXmlWriter.writeEndDocument();
QString fileName = mDocumentPath + UBFileSystemUtils::digitFileFormat("/page%1.svg", mPageIndex); QString fileName = mDocumentPath + UBFileSystemUtils::digitFileFormat("/page%1.svg", mPageIndex);
QFile file(fileName); QFile file(fileName);
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
{
qCritical() << "cannot open " << fileName << " for writing ...";
return false;
}
file.write(buffer.data());
file.flush();
file.close();
} if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
else
{ {
qDebug() << "ignoring unmodified page" << UBApplication::boardController->pageFromSceneIndex(mPageIndex); qCritical() << "cannot open " << fileName << " for writing ...";
return false;
} }
file.write(buffer.data());
file.flush();
file.close();
return true; return true;
} }

@ -65,6 +65,9 @@ class UBSvgSubsetAdaptor
public: public:
static UBGraphicsScene* loadScene(UBDocumentProxy* proxy, const int pageIndex); static UBGraphicsScene* loadScene(UBDocumentProxy* proxy, const int pageIndex);
static QByteArray loadSceneAsText(UBDocumentProxy* proxy, const int pageIndex);
static UBGraphicsScene* loadScene(UBDocumentProxy* proxy, const QByteArray& pArray);
static void persistScene(UBDocumentProxy* proxy, UBGraphicsScene* pScene, const int pageIndex); static void persistScene(UBDocumentProxy* proxy, UBGraphicsScene* pScene, const int pageIndex);
static void upgradeScene(UBDocumentProxy* proxy, const int pageIndex); static void upgradeScene(UBDocumentProxy* proxy, const int pageIndex);
@ -88,8 +91,6 @@ class UBSvgSubsetAdaptor
private: private:
static UBGraphicsScene* loadScene(UBDocumentProxy* proxy, const QByteArray& pArray);
static QDomDocument loadSceneDocument(UBDocumentProxy* proxy, const int pPageIndex); static QDomDocument loadSceneDocument(UBDocumentProxy* proxy, const int pPageIndex);
static QString uniboardDocumentNamespaceUriFromVersion(int fileVersion); static QString uniboardDocumentNamespaceUriFromVersion(int fileVersion);

@ -75,6 +75,17 @@ UBPersistenceManager::UBPersistenceManager(QObject *pParent)
documentProxies = allDocumentProxies(); documentProxies = allDocumentProxies();
mThread = new QThread;
mWorker = new UBPersistenceWorker();
mWorker->moveToThread(mThread);
connect(mWorker, SIGNAL(error(QString)), this, SLOT(errorString(QString)));
connect(mThread, SIGNAL(started()), mWorker, SLOT(process()));
connect(mWorker, SIGNAL(finished()), mThread, SLOT(quit()));
connect(mWorker, SIGNAL(finished()), mWorker, SLOT(deleteLater()));
connect(mThread, SIGNAL(finished()), mThread, SLOT(deleteLater()));
connect(mWorker,SIGNAL(sceneLoaded(QByteArray,UBDocumentProxy*,int)),this,SLOT(onSceneLoaded(QByteArray,UBDocumentProxy*,int)));
mThread->start();
} }
UBPersistenceManager* UBPersistenceManager::persistenceManager() UBPersistenceManager* UBPersistenceManager::persistenceManager()
@ -96,11 +107,31 @@ void UBPersistenceManager::destroy()
UBPersistenceManager::~UBPersistenceManager() UBPersistenceManager::~UBPersistenceManager()
{ {
if(mWorker)
mWorker->applicationWillClose();
foreach(QPointer<UBDocumentProxy> proxyGuard, documentProxies) foreach(QPointer<UBDocumentProxy> proxyGuard, documentProxies)
{ {
if (!proxyGuard.isNull()) if (!proxyGuard.isNull())
delete proxyGuard.data(); delete proxyGuard.data();
} }
// to be sure that all the scenes are stored on disk
mThread->wait(10*1000);
}
void UBPersistenceManager::errorString(QString error)
{
qDebug() << "peristence thread return the error " << error;
}
void UBPersistenceManager::onSceneLoaded(QByteArray scene, UBDocumentProxy* proxy, int sceneIndex)
{
qDebug() << "scene loaded " << sceneIndex;
QTime time;
time.start();
mSceneCache.insert(proxy,sceneIndex,UBSvgSubsetAdaptor::loadScene(proxy,scene));
qDebug() << "millisecond for sceneCache " << time.elapsed();
} }
QList<QPointer<UBDocumentProxy> > UBPersistenceManager::allDocumentProxies() QList<QPointer<UBDocumentProxy> > UBPersistenceManager::allDocumentProxies()
@ -653,16 +684,24 @@ void UBPersistenceManager::moveSceneToIndex(UBDocumentProxy* proxy, int source,
UBGraphicsScene* UBPersistenceManager::loadDocumentScene(UBDocumentProxy* proxy, int sceneIndex) UBGraphicsScene* UBPersistenceManager::loadDocumentScene(UBDocumentProxy* proxy, int sceneIndex)
{ {
UBGraphicsScene* scene = NULL;
if (mSceneCache.contains(proxy, sceneIndex)) if (mSceneCache.contains(proxy, sceneIndex))
return mSceneCache.value(proxy, sceneIndex); scene = mSceneCache.value(proxy, sceneIndex);
else { else {
UBGraphicsScene* scene = UBSvgSubsetAdaptor::loadScene(proxy, sceneIndex); scene = UBSvgSubsetAdaptor::loadScene(proxy, sceneIndex);
if (scene) if (scene)
mSceneCache.insert(proxy, sceneIndex, scene); mSceneCache.insert(proxy, sceneIndex, scene);
return scene;
} }
if(sceneIndex + 1 < proxy->pageCount() && !mSceneCache.contains(proxy, sceneIndex + 1))
mWorker->readScene(proxy,sceneIndex+1);
if(sceneIndex - 1 >= 0 && !mSceneCache.contains(proxy, sceneIndex - 1))
mWorker->readScene(proxy,sceneIndex-1);
return scene;
} }
void UBPersistenceManager::persistDocumentScene(UBDocumentProxy* pDocumentProxy, UBGraphicsScene* pScene, const int pSceneIndex, bool isAnAutomaticBackup) void UBPersistenceManager::persistDocumentScene(UBDocumentProxy* pDocumentProxy, UBGraphicsScene* pScene, const int pSceneIndex, bool isAnAutomaticBackup)
@ -682,10 +721,8 @@ void UBPersistenceManager::persistDocumentScene(UBDocumentProxy* pDocumentProxy,
if (pScene->isModified()) if (pScene->isModified())
{ {
UBSvgSubsetAdaptor::persistScene(pDocumentProxy, pScene, pSceneIndex);
UBThumbnailAdaptor::persistScene(pDocumentProxy, pScene, pSceneIndex); UBThumbnailAdaptor::persistScene(pDocumentProxy, pScene, pSceneIndex);
mWorker->saveScene(pDocumentProxy, pScene, pSceneIndex);
pScene->setModified(false); pScene->setModified(false);
} }

@ -32,6 +32,8 @@
#include "UBSceneCache.h" #include "UBSceneCache.h"
#include "UBPersistenceWorker.h"
class UBDocument; class UBDocument;
class UBDocumentProxy; class UBDocumentProxy;
class UBGraphicsScene; class UBGraphicsScene;
@ -148,11 +150,14 @@ class UBPersistenceManager : public QObject
QString mDocumentRepositoryPath; QString mDocumentRepositoryPath;
QHash<int,QString>teacherBarNodeString; UBPersistenceWorker* mWorker;
QThread* mThread;
private slots: private slots:
void documentRepositoryChanged(const QString& path); void documentRepositoryChanged(const QString& path);
void errorString(QString error);
void onSceneLoaded(QByteArray,UBDocumentProxy*,int);
}; };

@ -0,0 +1,69 @@
/*
* Copyright (C) 2013 Open Education Foundation
*
*
* This file is part of OpenBoard.
*
* OpenBoard is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License,
* with a specific linking exception for the OpenSSL project's
* "OpenSSL" library (or with modified versions of it that use the
* same license as the "OpenSSL" library).
*
* OpenBoard is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenBoard. If not, see <http://www.gnu.org/licenses/>.
*/
#include "UBPersistenceWorker.h"
#include "adaptors/UBSvgSubsetAdaptor.h"
#include "adaptors/UBThumbnailAdaptor.h"
UBPersistenceWorker::UBPersistenceWorker(QObject *parent) :
QObject(parent)
, mReceivedApplicationClosing(false)
{
}
void UBPersistenceWorker::saveScene(UBDocumentProxy* proxy, UBGraphicsScene* scene, const int pageIndex)
{
saves.append({WriteScene,proxy,scene,pageIndex});
mSemaphore.release();
}
void UBPersistenceWorker::readScene(UBDocumentProxy* proxy, const int pageIndex)
{
saves.append({ReadScene,proxy,0,pageIndex});
mSemaphore.release();
}
void UBPersistenceWorker::applicationWillClose()
{
qDebug() << "applicaiton Will close signal received";
mReceivedApplicationClosing = true;
mSemaphore.release();
}
void UBPersistenceWorker::process()
{
qDebug() << "process starts";
mSemaphore.acquire();
do{
PersistenceInformation info = saves.takeFirst();
if(info.action == WriteScene)
UBSvgSubsetAdaptor::persistScene(info.proxy, info.scene, info.sceneIndex);
else{
emit sceneLoaded(UBSvgSubsetAdaptor::loadSceneAsText(info.proxy,info.sceneIndex), info.proxy, info.sceneIndex);
}
mSemaphore.acquire();
}while(!mReceivedApplicationClosing);
qDebug() << "process will stop";
emit finished();
}

@ -0,0 +1,68 @@
/*
* Copyright (C) 2013-2014 Open Education Foundation
*
*
* This file is part of OpenBoard.
*
* OpenBoard is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License,
* with a specific linking exception for the OpenSSL project's
* "OpenSSL" library (or with modified versions of it that use the
* same license as the "OpenSSL" library).
*
* OpenBoard is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenBoard. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef UBPERSISTENCEWORKER_H
#define UBPERSISTENCEWORKER_H
#include <QObject>
#include <QSemaphore>
#include "document/UBDocumentProxy.h"
#include "domain/UBGraphicsScene.h"
typedef enum{
WriteScene = 0,
ReadScene
}ActionType;
typedef struct{
ActionType action;
UBDocumentProxy* proxy;
UBGraphicsScene* scene;
int sceneIndex;
}PersistenceInformation;
class UBPersistenceWorker : public QObject
{
Q_OBJECT
public:
explicit UBPersistenceWorker(QObject *parent = 0);
void saveScene(UBDocumentProxy* proxy, UBGraphicsScene* scene, const int pageIndex);
void readScene(UBDocumentProxy* proxy, const int pageIndex);
signals:
void finished();
void error(QString string);
void sceneLoaded(QByteArray text,UBDocumentProxy* proxy, const int pageIndex);
public slots:
void process();
void applicationWillClose();
protected:
bool mReceivedApplicationClosing;
QSemaphore mSemaphore;
QList<PersistenceInformation> saves;
};
#endif // UBPERSISTENCEWORKER_H

@ -14,7 +14,8 @@ HEADERS += src/core/UB.h \
src/core/UBDownloadManager.h \ src/core/UBDownloadManager.h \
src/core/UBDownloadThread.h \ src/core/UBDownloadThread.h \
src/core/UBOpenSankoreImporter.h \ src/core/UBOpenSankoreImporter.h \
src/core/UBTextTools.h src/core/UBTextTools.h \
src/core/UBPersistenceWorker.h
SOURCES += src/core/main.cpp \ SOURCES += src/core/main.cpp \
src/core/UBApplication.cpp \ src/core/UBApplication.cpp \
@ -31,6 +32,7 @@ SOURCES += src/core/main.cpp \
src/core/UBDownloadManager.cpp \ src/core/UBDownloadManager.cpp \
src/core/UBDownloadThread.cpp \ src/core/UBDownloadThread.cpp \
src/core/UBOpenSankoreImporter.cpp \ src/core/UBOpenSankoreImporter.cpp \
src/core/UBTextTools.cpp src/core/UBTextTools.cpp \
src/core/UBPersistenceWorker.cpp

Loading…
Cancel
Save