| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | /****************************************************************************
 | 
					
						
							| 
									
										
										
										
											2011-02-22 12:08:19 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2013-01-28 17:12:19 +01:00
										 |  |  | ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). | 
					
						
							| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | ** Contact: http://www.qt-project.org/legal
 | 
					
						
							| 
									
										
										
										
											2011-02-22 12:08:19 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | ** This file is part of Qt Creator. | 
					
						
							| 
									
										
										
										
											2011-02-22 12:08:19 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | ** Commercial License Usage | 
					
						
							|  |  |  | ** Licensees holding valid commercial Qt licenses may use this file in | 
					
						
							|  |  |  | ** accordance with the commercial license agreement provided with the | 
					
						
							|  |  |  | ** Software or, alternatively, in accordance with the terms contained in | 
					
						
							|  |  |  | ** a written agreement between you and Digia.  For licensing terms and | 
					
						
							|  |  |  | ** conditions see http://qt.digia.com/licensing.  For further information
 | 
					
						
							|  |  |  | ** use the contact form at http://qt.digia.com/contact-us.
 | 
					
						
							| 
									
										
										
										
											2011-02-22 12:08:19 +01:00
										 |  |  | ** | 
					
						
							|  |  |  | ** GNU Lesser General Public License Usage | 
					
						
							| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | ** Alternatively, this file may be used under the terms of the GNU Lesser | 
					
						
							|  |  |  | ** General Public License version 2.1 as published by the Free Software | 
					
						
							|  |  |  | ** Foundation and appearing in the file LICENSE.LGPL included in the | 
					
						
							|  |  |  | ** packaging of this file.  Please review the following information to | 
					
						
							|  |  |  | ** ensure the GNU Lesser General Public License version 2.1 requirements | 
					
						
							|  |  |  | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** In addition, as a special exception, Digia gives you certain additional | 
					
						
							|  |  |  | ** rights.  These rights are described in the Digia Qt LGPL Exception | 
					
						
							| 
									
										
										
										
											2011-02-22 12:08:19 +01:00
										 |  |  | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. | 
					
						
							|  |  |  | ** | 
					
						
							| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | ****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2011-02-22 12:08:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-24 14:52:06 +01:00
										 |  |  | #include "valueschangedcommand.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  | #include <QSharedMemory>
 | 
					
						
							|  |  |  | #include <QCache>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-20 14:25:01 +02:00
										 |  |  | #include <cstring>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-24 14:52:06 +01:00
										 |  |  | namespace QmlDesigner { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  | static QCache<qint32, QSharedMemory> globalSharedMemoryCache(10000); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-24 14:52:06 +01:00
										 |  |  | ValuesChangedCommand::ValuesChangedCommand() | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  |     : m_keyNumber(0) | 
					
						
							| 
									
										
										
										
											2010-11-24 14:52:06 +01:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ValuesChangedCommand::ValuesChangedCommand(const QVector<PropertyValueContainer> &valueChangeVector) | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  |     : m_valueChangeVector (valueChangeVector), | 
					
						
							|  |  |  |       m_keyNumber(0) | 
					
						
							| 
									
										
										
										
											2010-11-24 14:52:06 +01:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QVector<PropertyValueContainer> ValuesChangedCommand::valueChanges() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_valueChangeVector; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  | quint32 ValuesChangedCommand::keyNumber() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_keyNumber; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ValuesChangedCommand::removeSharedMemorys(const QVector<qint32> &keyNumberVector) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     foreach (qint32 keyNumber, keyNumberVector) { | 
					
						
							|  |  |  |         QSharedMemory *sharedMemory = globalSharedMemoryCache.take(keyNumber); | 
					
						
							|  |  |  |         delete sharedMemory; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const QLatin1String valueKeyTemplateString("Values-%1"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static QSharedMemory *createSharedMemory(qint32 key, int byteCount) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QSharedMemory *sharedMemory = new QSharedMemory(QString(valueKeyTemplateString).arg(key)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bool sharedMemoryIsCreated = sharedMemory->create(byteCount); | 
					
						
							|  |  |  |     if (!sharedMemoryIsCreated) { | 
					
						
							|  |  |  |         if (sharedMemory->isAttached()) | 
					
						
							|  |  |  |             sharedMemory->attach(); | 
					
						
							|  |  |  |         sharedMemory->detach(); | 
					
						
							|  |  |  |         sharedMemoryIsCreated = sharedMemory->create(byteCount); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (sharedMemoryIsCreated) { | 
					
						
							|  |  |  |         globalSharedMemoryCache.insert(key, sharedMemory); | 
					
						
							|  |  |  |         return sharedMemory; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-24 14:52:06 +01:00
										 |  |  | QDataStream &operator<<(QDataStream &out, const ValuesChangedCommand &command) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-09-11 17:25:27 +02:00
										 |  |  |     static const bool dontUseSharedMemory = !qgetenv("DESIGNER_DONT_USE_SHARED_MEMORY").isEmpty(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!dontUseSharedMemory && command.valueChanges().count() > 5) { | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  |         static quint32 keyCounter = 0; | 
					
						
							|  |  |  |         ++keyCounter; | 
					
						
							|  |  |  |         command.m_keyNumber = keyCounter; | 
					
						
							|  |  |  |         QByteArray outDataStreamByteArray; | 
					
						
							|  |  |  |         QDataStream temporaryOutDataStream(&outDataStreamByteArray, QIODevice::WriteOnly); | 
					
						
							| 
									
										
										
										
											2012-09-20 11:30:11 +02:00
										 |  |  |         temporaryOutDataStream.setVersion(QDataStream::Qt_4_8); | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         temporaryOutDataStream << command.valueChanges();; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         QSharedMemory *sharedMemory = createSharedMemory(keyCounter, outDataStreamByteArray.size()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (sharedMemory) { | 
					
						
							| 
									
										
										
										
											2012-09-20 14:25:01 +02:00
										 |  |  |             std::memcpy(sharedMemory->data(), outDataStreamByteArray.constData(), sharedMemory->size()); | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  |             out << command.keyNumber(); | 
					
						
							|  |  |  |             return out; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     out << qint32(0); | 
					
						
							| 
									
										
										
										
											2010-11-24 14:52:06 +01:00
										 |  |  |     out << command.valueChanges(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return out; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  | void readSharedMemory(qint32 key, QVector<PropertyValueContainer> *valueChangeVector) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QSharedMemory sharedMemory(QString(valueKeyTemplateString).arg(key)); | 
					
						
							|  |  |  |     bool canAttach = sharedMemory.attach(QSharedMemory::ReadOnly); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (canAttach) { | 
					
						
							|  |  |  |         QDataStream in(QByteArray::fromRawData(static_cast<const char*>(sharedMemory.constData()), sharedMemory.size())); | 
					
						
							| 
									
										
										
										
											2012-09-20 11:30:11 +02:00
										 |  |  |         in.setVersion(QDataStream::Qt_4_8); | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  |         in >> *valueChangeVector; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-24 14:52:06 +01:00
										 |  |  | QDataStream &operator>>(QDataStream &in, ValuesChangedCommand &command) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  |     in >> command.m_keyNumber; | 
					
						
							| 
									
										
										
										
											2010-11-24 14:52:06 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  |     if (command.keyNumber() > 0) { | 
					
						
							|  |  |  |         readSharedMemory(command.keyNumber(), &command.m_valueChangeVector); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         in >> command.m_valueChangeVector; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-11-24 14:52:06 +01:00
										 |  |  |     return in; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } // namespace QmlDesigner
 |