mirror of
https://github.com/overte-org/overte.git
synced 2025-08-04 16:30:10 +02:00
Streaming cleanup, streaming script strings as repeated values.
This commit is contained in:
parent
ca52d67041
commit
4f4c4c68d9
8 changed files with 206 additions and 214 deletions
|
@ -1,171 +0,0 @@
|
|||
//
|
||||
// sphere.js
|
||||
// interface
|
||||
//
|
||||
// Created by Andrzej Kapolka on 12/17/13.
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
function strictIndexOf(array, element) {
|
||||
for (var i = 0; i < array.length; i++) {
|
||||
if (array[i] == element) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
var colorIndex;
|
||||
var normalIndex;
|
||||
var visitor;
|
||||
var info;
|
||||
|
||||
var MAX_DEPTH = 4;
|
||||
|
||||
var sphereCenter = [ 0.5, 0.5, 0.5 ];
|
||||
var sphereColor = 0xFFFF00FF;
|
||||
var sphereRadius = 0.25;
|
||||
var sphereRadiusSquared = sphereRadius * sphereRadius;
|
||||
|
||||
function lengthSquared(x, y, z) {
|
||||
return x*x + y*y + z*z;
|
||||
}
|
||||
|
||||
function setNormal(vector) {
|
||||
if (normalIndex != -1) {
|
||||
var length = Math.sqrt(lengthSquared(vector[0], vector[1], vector[2]));
|
||||
if (length == 0.0) {
|
||||
info.inputValues[normalIndex] = 0x007F00;
|
||||
|
||||
} else {
|
||||
var scale = 127.0 / length;
|
||||
info.inputValues[normalIndex] =
|
||||
(Math.floor(vector[0] * scale) & 0xFF) << 16 |
|
||||
(Math.floor(vector[1] * scale) & 0xFF) << 8 |
|
||||
Math.floor(vector[2] * scale) & 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function guide(minimum, size, depth) {
|
||||
info.minimum = minimum;
|
||||
info.size = size;
|
||||
|
||||
// start with a relative fast bounding volume test to find most non-intersecting states
|
||||
var maximum = [ minimum[0] + size, minimum[1] + size, minimum[2] + size ];
|
||||
if (minimum[0] >= sphereCenter[0] + sphereRadius ||
|
||||
minimum[1] >= sphereCenter[1] + sphereRadius ||
|
||||
minimum[2] >= sphereCenter[2] + sphereRadius ||
|
||||
maximum[0] <= sphereCenter[0] - sphereRadius ||
|
||||
maximum[1] <= sphereCenter[1] - sphereRadius ||
|
||||
maximum[2] <= sphereCenter[2] - sphereRadius) {
|
||||
info.isLeaf = true;
|
||||
if (colorIndex != -1) {
|
||||
info.inputValues[colorIndex] = 0x0;
|
||||
}
|
||||
visitor.visit(info);
|
||||
return;
|
||||
}
|
||||
|
||||
var halfSize = size / 2;
|
||||
var center = [ minimum[0] + halfSize, minimum[1] + halfSize, minimum[2] + halfSize ];
|
||||
var vector = [ center[0] - sphereCenter[0], center[1] - sphereCenter[1], center[2] - sphereCenter[2] ];
|
||||
|
||||
// count the number of points inside the sphere
|
||||
var inside = 0;
|
||||
if (lengthSquared(sphereCenter[0] - minimum[0], sphereCenter[1] - minimum[1], sphereCenter[2] - minimum[2]) <=
|
||||
sphereRadiusSquared) {
|
||||
inside++;
|
||||
}
|
||||
if (lengthSquared(sphereCenter[0] - maximum[0], sphereCenter[1] - minimum[1], sphereCenter[2] - minimum[2]) <=
|
||||
sphereRadiusSquared) {
|
||||
inside++;
|
||||
}
|
||||
if (lengthSquared(sphereCenter[0] - minimum[0], sphereCenter[1] - maximum[1], sphereCenter[2] - minimum[2]) <=
|
||||
sphereRadiusSquared) {
|
||||
inside++;
|
||||
}
|
||||
if (lengthSquared(sphereCenter[0] - maximum[0], sphereCenter[1] - maximum[1], sphereCenter[2] - minimum[2]) <=
|
||||
sphereRadiusSquared) {
|
||||
inside++;
|
||||
}
|
||||
if (lengthSquared(sphereCenter[0] - minimum[0], sphereCenter[1] - minimum[1], sphereCenter[2] - maximum[2]) <=
|
||||
sphereRadiusSquared) {
|
||||
inside++;
|
||||
}
|
||||
if (lengthSquared(sphereCenter[0] - maximum[0], sphereCenter[1] - minimum[1], sphereCenter[2] - maximum[2]) <=
|
||||
sphereRadiusSquared) {
|
||||
inside++;
|
||||
}
|
||||
if (lengthSquared(sphereCenter[0] - minimum[0], sphereCenter[1] - maximum[1], sphereCenter[2] - maximum[2]) <=
|
||||
sphereRadiusSquared) {
|
||||
inside++;
|
||||
}
|
||||
if (lengthSquared(sphereCenter[0] - maximum[0], sphereCenter[1] - maximum[1], sphereCenter[2] - maximum[2]) <=
|
||||
sphereRadiusSquared) {
|
||||
inside++;
|
||||
}
|
||||
|
||||
// see if all points are in the sphere
|
||||
if (inside == 8) {
|
||||
info.isLeaf = true;
|
||||
if (colorIndex != -1) {
|
||||
info.inputValues[colorIndex] = sphereColor;
|
||||
}
|
||||
setNormal(vector);
|
||||
visitor.visit(info);
|
||||
return;
|
||||
}
|
||||
|
||||
// if we've reached max depth, compute alpha using a volume estimate
|
||||
if (depth == MAX_DEPTH) {
|
||||
info.isLeaf = true;
|
||||
if (inside >= 3) {
|
||||
if (colorIndex != -1) {
|
||||
info.inputValues[colorIndex] = sphereColor;
|
||||
}
|
||||
setNormal(vector);
|
||||
|
||||
} else {
|
||||
if (colorIndex != -1) {
|
||||
info.inputValues[colorIndex] = 0x0;
|
||||
}
|
||||
}
|
||||
visitor.visit(info);
|
||||
return;
|
||||
}
|
||||
|
||||
// recurse
|
||||
info.isLeaf = false;
|
||||
if (!visitor.visit(info)) {
|
||||
return;
|
||||
}
|
||||
depth += 1;
|
||||
guide(minimum, halfSize, depth);
|
||||
guide([ center[0], minimum[1], minimum[2] ], halfSize, depth);
|
||||
guide([ minimum[0], center[1], minimum[2] ], halfSize, depth);
|
||||
guide([ center[0], center[1], minimum[2] ], halfSize, depth);
|
||||
guide([ minimum[0], minimum[1], center[2] ], halfSize, depth);
|
||||
guide([ center[0], minimum[1], center[2] ], halfSize, depth);
|
||||
guide([ minimum[0], center[1], center[2] ], halfSize, depth);
|
||||
guide([ center[0], center[1], center[2] ], halfSize, depth);
|
||||
}
|
||||
|
||||
(function(visitation) {
|
||||
var inputs = visitation.visitor.getInputs();
|
||||
colorIndex = strictIndexOf(inputs, AttributeRegistry.colorAttribute);
|
||||
normalIndex = strictIndexOf(inputs, AttributeRegistry.normalAttribute);
|
||||
visitor = visitation.visitor;
|
||||
info = { inputValues: new Array(inputs.length) };
|
||||
|
||||
// have the sphere orbit the center and pulse in size
|
||||
var time = new Date().getTime();
|
||||
var ROTATE_PERIOD = 400.0;
|
||||
sphereCenter[0] = 0.5 + 0.25 * Math.cos(time / ROTATE_PERIOD);
|
||||
sphereCenter[2] = 0.5 + 0.25 * Math.sin(time / ROTATE_PERIOD);
|
||||
var PULSE_PERIOD = 300.0;
|
||||
sphereRadius = 0.25 + 0.0625 * Math.cos(time / PULSE_PERIOD);
|
||||
sphereRadiusSquared = sphereRadius * sphereRadius;
|
||||
|
||||
guide(visitation.info.minimum, visitation.info.size, 0);
|
||||
})
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "AttributeRegistry.h"
|
||||
#include "Bitstream.h"
|
||||
#include "ScriptCache.h"
|
||||
|
||||
REGISTER_SIMPLE_TYPE_STREAMER(bool)
|
||||
REGISTER_SIMPLE_TYPE_STREAMER(int)
|
||||
|
@ -88,7 +89,8 @@ Bitstream::Bitstream(QDataStream& underlying) :
|
|||
_position(0),
|
||||
_metaObjectStreamer(*this),
|
||||
_typeStreamerStreamer(*this),
|
||||
_attributeStreamer(*this) {
|
||||
_attributeStreamer(*this),
|
||||
_scriptStringStreamer(*this) {
|
||||
}
|
||||
|
||||
const int BITS_IN_BYTE = 8;
|
||||
|
@ -145,7 +147,8 @@ void Bitstream::reset() {
|
|||
Bitstream::WriteMappings Bitstream::getAndResetWriteMappings() {
|
||||
WriteMappings mappings = { _metaObjectStreamer.getAndResetTransientOffsets(),
|
||||
_typeStreamerStreamer.getAndResetTransientOffsets(),
|
||||
_attributeStreamer.getAndResetTransientOffsets() };
|
||||
_attributeStreamer.getAndResetTransientOffsets(),
|
||||
_scriptStringStreamer.getAndResetTransientOffsets() };
|
||||
return mappings;
|
||||
}
|
||||
|
||||
|
@ -153,12 +156,14 @@ void Bitstream::persistWriteMappings(const WriteMappings& mappings) {
|
|||
_metaObjectStreamer.persistTransientOffsets(mappings.metaObjectOffsets);
|
||||
_typeStreamerStreamer.persistTransientOffsets(mappings.typeStreamerOffsets);
|
||||
_attributeStreamer.persistTransientOffsets(mappings.attributeOffsets);
|
||||
_scriptStringStreamer.persistTransientOffsets(mappings.scriptStringOffsets);
|
||||
}
|
||||
|
||||
Bitstream::ReadMappings Bitstream::getAndResetReadMappings() {
|
||||
ReadMappings mappings = { _metaObjectStreamer.getAndResetTransientValues(),
|
||||
_typeStreamerStreamer.getAndResetTransientValues(),
|
||||
_attributeStreamer.getAndResetTransientValues() };
|
||||
_attributeStreamer.getAndResetTransientValues(),
|
||||
_scriptStringStreamer.getAndResetTransientValues() };
|
||||
return mappings;
|
||||
}
|
||||
|
||||
|
@ -166,6 +171,7 @@ void Bitstream::persistReadMappings(const ReadMappings& mappings) {
|
|||
_metaObjectStreamer.persistTransientValues(mappings.metaObjectValues);
|
||||
_typeStreamerStreamer.persistTransientValues(mappings.typeStreamerValues);
|
||||
_attributeStreamer.persistTransientValues(mappings.attributeValues);
|
||||
_scriptStringStreamer.persistTransientValues(mappings.scriptStringValues);
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator<<(bool value) {
|
||||
|
@ -238,6 +244,16 @@ Bitstream& Bitstream::operator>>(QString& string) {
|
|||
return read(string.data(), size * sizeof(QChar) * BITS_IN_BYTE);
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator<<(const QScriptString& string) {
|
||||
_scriptStringStreamer << string;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator>>(QScriptString& string) {
|
||||
_scriptStringStreamer >> string;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator<<(const QUrl& url) {
|
||||
return *this << url.toString();
|
||||
}
|
||||
|
@ -334,11 +350,41 @@ Bitstream& Bitstream::operator>>(QObject*& object) {
|
|||
}
|
||||
|
||||
Bitstream& Bitstream::operator<<(const QMetaObject* metaObject) {
|
||||
return *this << (metaObject ? QByteArray::fromRawData(
|
||||
metaObject->className(), strlen(metaObject->className())) : QByteArray());
|
||||
_metaObjectStreamer << metaObject;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator>>(const QMetaObject*& metaObject) {
|
||||
_metaObjectStreamer >> metaObject;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator<<(const TypeStreamer* streamer) {
|
||||
_typeStreamerStreamer << streamer;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator>>(const TypeStreamer*& streamer) {
|
||||
_typeStreamerStreamer >> streamer;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator<<(const AttributePointer& attribute) {
|
||||
_attributeStreamer << attribute;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator>>(AttributePointer& attribute) {
|
||||
_attributeStreamer >> attribute;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator<(const QMetaObject* metaObject) {
|
||||
return *this << (metaObject ? QByteArray::fromRawData(metaObject->className(),
|
||||
strlen(metaObject->className())) : QByteArray());
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator>(const QMetaObject*& metaObject) {
|
||||
QByteArray className;
|
||||
*this >> className;
|
||||
if (className.isEmpty()) {
|
||||
|
@ -352,12 +398,12 @@ Bitstream& Bitstream::operator>>(const QMetaObject*& metaObject) {
|
|||
return *this;
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator<<(const TypeStreamer* streamer) {
|
||||
Bitstream& Bitstream::operator<(const TypeStreamer* streamer) {
|
||||
const char* typeName = QMetaType::typeName(streamer->getType());
|
||||
return *this << QByteArray::fromRawData(typeName, strlen(typeName));
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator>>(const TypeStreamer*& streamer) {
|
||||
Bitstream& Bitstream::operator>(const TypeStreamer*& streamer) {
|
||||
QByteArray typeName;
|
||||
*this >> typeName;
|
||||
streamer = getTypeStreamers().value(QMetaType::type(typeName.constData()));
|
||||
|
@ -367,17 +413,28 @@ Bitstream& Bitstream::operator>>(const TypeStreamer*& streamer) {
|
|||
return *this;
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator<<(const AttributePointer& attribute) {
|
||||
Bitstream& Bitstream::operator<(const AttributePointer& attribute) {
|
||||
return *this << (QObject*)attribute.data();
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator>>(AttributePointer& attribute) {
|
||||
Bitstream& Bitstream::operator>(AttributePointer& attribute) {
|
||||
QObject* object;
|
||||
*this >> object;
|
||||
attribute = AttributeRegistry::getInstance()->registerAttribute(static_cast<Attribute*>(object));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator<(const QScriptString& string) {
|
||||
return *this << string.toString();
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator>(QScriptString& string) {
|
||||
QString rawString;
|
||||
*this >> rawString;
|
||||
string = ScriptCache::getInstance()->getEngine()->toStringHandle(rawString);
|
||||
return *this;
|
||||
}
|
||||
|
||||
QHash<QByteArray, const QMetaObject*>& Bitstream::getMetaObjects() {
|
||||
static QHash<QByteArray, const QMetaObject*> metaObjects;
|
||||
return metaObjects;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <QHash>
|
||||
#include <QMetaType>
|
||||
#include <QScriptString>
|
||||
#include <QSharedPointer>
|
||||
#include <QVariant>
|
||||
#include <QtDebug>
|
||||
|
@ -127,7 +128,7 @@ template<class T> inline RepeatedValueStreamer<T>& RepeatedValueStreamer<T>::ope
|
|||
int& offset = _transientOffsets[value];
|
||||
if (offset == 0) {
|
||||
_idStreamer << (_lastPersistentID + (offset = ++_lastTransientOffset));
|
||||
_stream << value;
|
||||
_stream < value;
|
||||
|
||||
} else {
|
||||
_idStreamer << (_lastPersistentID + offset);
|
||||
|
@ -148,7 +149,7 @@ template<class T> inline RepeatedValueStreamer<T>& RepeatedValueStreamer<T>::ope
|
|||
int offset = id - _lastPersistentID;
|
||||
typename QHash<int, T>::iterator it = _transientValues.find(offset);
|
||||
if (it == _transientValues.end()) {
|
||||
_stream >> value;
|
||||
_stream > value;
|
||||
_transientValues.insert(offset, value);
|
||||
|
||||
} else {
|
||||
|
@ -167,6 +168,7 @@ public:
|
|||
QHash<const QMetaObject*, int> metaObjectOffsets;
|
||||
QHash<const TypeStreamer*, int> typeStreamerOffsets;
|
||||
QHash<AttributePointer, int> attributeOffsets;
|
||||
QHash<QScriptString, int> scriptStringOffsets;
|
||||
};
|
||||
|
||||
class ReadMappings {
|
||||
|
@ -174,6 +176,7 @@ public:
|
|||
QHash<int, const QMetaObject*> metaObjectValues;
|
||||
QHash<int, const TypeStreamer*> typeStreamerValues;
|
||||
QHash<int, AttributePointer> attributeValues;
|
||||
QHash<int, QScriptString> scriptStringValues;
|
||||
};
|
||||
|
||||
/// Registers a metaobject under its name so that instances of it can be streamed.
|
||||
|
@ -206,9 +209,6 @@ public:
|
|||
/// Resets to the initial state.
|
||||
void reset();
|
||||
|
||||
/// Returns a reference to the attribute streamer.
|
||||
RepeatedValueStreamer<AttributePointer>& getAttributeStreamer() { return _attributeStreamer; }
|
||||
|
||||
/// Returns the set of transient mappings gathered during writing and resets them.
|
||||
WriteMappings getAndResetWriteMappings();
|
||||
|
||||
|
@ -239,6 +239,9 @@ public:
|
|||
Bitstream& operator<<(const QString& string);
|
||||
Bitstream& operator>>(QString& string);
|
||||
|
||||
Bitstream& operator<<(const QScriptString& string);
|
||||
Bitstream& operator>>(QScriptString& string);
|
||||
|
||||
Bitstream& operator<<(const QUrl& url);
|
||||
Bitstream& operator>>(QUrl& url);
|
||||
|
||||
|
@ -266,6 +269,18 @@ public:
|
|||
Bitstream& operator<<(const AttributePointer& attribute);
|
||||
Bitstream& operator>>(AttributePointer& attribute);
|
||||
|
||||
Bitstream& operator<(const QMetaObject* metaObject);
|
||||
Bitstream& operator>(const QMetaObject*& metaObject);
|
||||
|
||||
Bitstream& operator<(const TypeStreamer* streamer);
|
||||
Bitstream& operator>(const TypeStreamer*& streamer);
|
||||
|
||||
Bitstream& operator<(const AttributePointer& attribute);
|
||||
Bitstream& operator>(AttributePointer& attribute);
|
||||
|
||||
Bitstream& operator<(const QScriptString& string);
|
||||
Bitstream& operator>(QScriptString& string);
|
||||
|
||||
private:
|
||||
|
||||
QDataStream& _underlying;
|
||||
|
@ -275,6 +290,7 @@ private:
|
|||
RepeatedValueStreamer<const QMetaObject*> _metaObjectStreamer;
|
||||
RepeatedValueStreamer<const TypeStreamer*> _typeStreamerStreamer;
|
||||
RepeatedValueStreamer<AttributePointer> _attributeStreamer;
|
||||
RepeatedValueStreamer<QScriptString> _scriptStringStreamer;
|
||||
|
||||
static QHash<QByteArray, const QMetaObject*>& getMetaObjects();
|
||||
static QMultiHash<const QMetaObject*, const QMetaObject*>& getMetaObjectSubClasses();
|
||||
|
|
|
@ -136,7 +136,7 @@ void MetavoxelData::read(Bitstream& in) {
|
|||
in >> rootCount;
|
||||
for (int i = 0; i < rootCount; i++) {
|
||||
AttributePointer attribute;
|
||||
in.getAttributeStreamer() >> attribute;
|
||||
in >> attribute;
|
||||
MetavoxelNode*& root = _roots[attribute];
|
||||
root = new MetavoxelNode(attribute);
|
||||
root->read(attribute, in);
|
||||
|
@ -147,7 +147,7 @@ void MetavoxelData::write(Bitstream& out) const {
|
|||
out << _size;
|
||||
out << _roots.size();
|
||||
for (QHash<AttributePointer, MetavoxelNode*>::const_iterator it = _roots.constBegin(); it != _roots.constEnd(); it++) {
|
||||
out.getAttributeStreamer() << it.key();
|
||||
out << it.key();
|
||||
it.value()->write(it.key(), out);
|
||||
}
|
||||
}
|
||||
|
@ -176,7 +176,7 @@ void MetavoxelData::readDelta(const MetavoxelData& reference, Bitstream& in) {
|
|||
in >> changedCount;
|
||||
for (int i = 0; i < changedCount; i++) {
|
||||
AttributePointer attribute;
|
||||
in.getAttributeStreamer() >> attribute;
|
||||
in >> attribute;
|
||||
MetavoxelNode*& root = _roots[attribute];
|
||||
if (root) {
|
||||
MetavoxelNode* oldRoot = root;
|
||||
|
@ -194,7 +194,7 @@ void MetavoxelData::readDelta(const MetavoxelData& reference, Bitstream& in) {
|
|||
in >> removedCount;
|
||||
for (int i = 0; i < removedCount; i++) {
|
||||
AttributePointer attribute;
|
||||
in.getAttributeStreamer() >> attribute;
|
||||
in >> attribute;
|
||||
_roots.take(attribute)->decrementReferenceCount(attribute);
|
||||
}
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ void MetavoxelData::writeDelta(const MetavoxelData& reference, Bitstream& out) c
|
|||
for (QHash<AttributePointer, MetavoxelNode*>::const_iterator it = _roots.constBegin(); it != _roots.constEnd(); it++) {
|
||||
MetavoxelNode* referenceRoot = expandedReference->_roots.value(it.key());
|
||||
if (it.value() != referenceRoot) {
|
||||
out.getAttributeStreamer() << it.key();
|
||||
out << it.key();
|
||||
if (referenceRoot) {
|
||||
it.value()->writeDelta(it.key(), *referenceRoot, out);
|
||||
} else {
|
||||
|
@ -255,7 +255,7 @@ void MetavoxelData::writeDelta(const MetavoxelData& reference, Bitstream& out) c
|
|||
for (QHash<AttributePointer, MetavoxelNode*>::const_iterator it = expandedReference->_roots.constBegin();
|
||||
it != expandedReference->_roots.constEnd(); it++) {
|
||||
if (!_roots.contains(it.key())) {
|
||||
out.getAttributeStreamer() << it.key();
|
||||
out << it.key();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,9 +21,12 @@
|
|||
#include <PacketHeaders.h>
|
||||
|
||||
#include "MetavoxelUtil.h"
|
||||
#include "ScriptCache.h"
|
||||
|
||||
static int scriptHashType = qRegisterMetaType<ScriptHash>();
|
||||
static int parameterizedURLType = qRegisterMetaType<ParameterizedURL>();
|
||||
|
||||
REGISTER_SIMPLE_TYPE_STREAMER(ScriptHash)
|
||||
REGISTER_SIMPLE_TYPE_STREAMER(ParameterizedURL)
|
||||
|
||||
class DelegatingItemEditorFactory : public QItemEditorFactory {
|
||||
|
@ -106,7 +109,7 @@ bool Box::contains(const Box& other) const {
|
|||
other.minimum.z >= minimum.z && other.maximum.z <= maximum.z;
|
||||
}
|
||||
|
||||
ParameterizedURL::ParameterizedURL(const QUrl& url, const QVariantHash& parameters) :
|
||||
ParameterizedURL::ParameterizedURL(const QUrl& url, const ScriptHash& parameters) :
|
||||
_url(url),
|
||||
_parameters(parameters) {
|
||||
}
|
||||
|
@ -133,7 +136,7 @@ Bitstream& operator<<(Bitstream& out, const ParameterizedURL& url) {
|
|||
Bitstream& operator>>(Bitstream& in, ParameterizedURL& url) {
|
||||
QUrl qurl;
|
||||
in >> qurl;
|
||||
QVariantHash parameters;
|
||||
ScriptHash parameters;
|
||||
in >> parameters;
|
||||
url = ParameterizedURL(qurl, parameters);
|
||||
return in;
|
||||
|
@ -146,16 +149,47 @@ ParameterizedURLEditor::ParameterizedURLEditor(QWidget* parent) :
|
|||
layout->setContentsMargins(QMargins());
|
||||
setLayout(layout);
|
||||
|
||||
layout->addWidget(_line = new QLineEdit());
|
||||
QWidget* lineContainer = new QWidget();
|
||||
layout->addWidget(lineContainer);
|
||||
|
||||
QHBoxLayout* lineLayout = new QHBoxLayout();
|
||||
lineContainer->setLayout(lineLayout);
|
||||
lineLayout->setContentsMargins(QMargins());
|
||||
|
||||
lineLayout->addWidget(_line = new QLineEdit(), 1);
|
||||
connect(_line, SIGNAL(textChanged(const QString&)), SLOT(updateURL()));
|
||||
|
||||
QPushButton* refresh = new QPushButton("...");
|
||||
connect(refresh, SIGNAL(clicked(bool)), SLOT(updateParameters()));
|
||||
lineLayout->addWidget(refresh);
|
||||
}
|
||||
|
||||
void ParameterizedURLEditor::setURL(const ParameterizedURL& url) {
|
||||
_url = url;
|
||||
_line->setText(url.getURL().toString());
|
||||
updateParameters();
|
||||
}
|
||||
|
||||
void ParameterizedURLEditor::updateURL() {
|
||||
_url = ParameterizedURL(_line->text());
|
||||
emit urlChanged(_url);
|
||||
if (_program) {
|
||||
_program->disconnect(this);
|
||||
}
|
||||
}
|
||||
|
||||
void ParameterizedURLEditor::updateParameters() {
|
||||
if (_program) {
|
||||
_program->disconnect(this);
|
||||
}
|
||||
_program = ScriptCache::getInstance()->getProgram(_url.getURL());
|
||||
if (_program->isLoaded()) {
|
||||
continueUpdatingParameters();
|
||||
} else {
|
||||
connect(_program.data(), SIGNAL(loaded()), SLOT(continueUpdatingParameters()));
|
||||
}
|
||||
}
|
||||
|
||||
void ParameterizedURLEditor::continueUpdatingParameters() {
|
||||
QScriptValue value = ScriptCache::getInstance()->getValue(_url.getURL())->getValue();
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#ifndef __interface__MetavoxelUtil__
|
||||
#define __interface__MetavoxelUtil__
|
||||
|
||||
#include <QSharedPointer>
|
||||
#include <QUrl>
|
||||
#include <QUuid>
|
||||
#include <QWidget>
|
||||
|
@ -19,6 +20,7 @@ class QByteArray;
|
|||
class QLineEdit;
|
||||
|
||||
class HifiSockAddr;
|
||||
class NetworkProgram;
|
||||
|
||||
/// Reads and returns the session ID from a datagram.
|
||||
/// \param[out] headerPlusIDSize the size of the header (including the session ID) within the data
|
||||
|
@ -39,19 +41,23 @@ public:
|
|||
|
||||
DECLARE_STREAMABLE_METATYPE(Box)
|
||||
|
||||
typedef QHash<QScriptString, QVariant> ScriptHash;
|
||||
|
||||
Q_DECLARE_METATYPE(ScriptHash)
|
||||
|
||||
/// Combines a URL with a set of typed parameters.
|
||||
class ParameterizedURL {
|
||||
public:
|
||||
|
||||
ParameterizedURL(const QUrl& url = QUrl(), const QVariantHash& parameters = QVariantHash());
|
||||
ParameterizedURL(const QUrl& url = QUrl(), const ScriptHash& parameters = ScriptHash());
|
||||
|
||||
bool isValid() const { return _url.isValid(); }
|
||||
|
||||
void setURL(const QUrl& url) { _url = url; }
|
||||
const QUrl& getURL() const { return _url; }
|
||||
|
||||
void setParameters(const QVariantHash& parameters) { _parameters = parameters; }
|
||||
const QVariantHash& getParameters() const { return _parameters; }
|
||||
void setParameters(const ScriptHash& parameters) { _parameters = parameters; }
|
||||
const ScriptHash& getParameters() const { return _parameters; }
|
||||
|
||||
bool operator==(const ParameterizedURL& other) const;
|
||||
bool operator!=(const ParameterizedURL& other) const;
|
||||
|
@ -59,7 +65,7 @@ public:
|
|||
private:
|
||||
|
||||
QUrl _url;
|
||||
QVariantHash _parameters;
|
||||
ScriptHash _parameters;
|
||||
};
|
||||
|
||||
uint qHash(const ParameterizedURL& url, uint seed = 0);
|
||||
|
@ -89,10 +95,14 @@ public slots:
|
|||
private slots:
|
||||
|
||||
void updateURL();
|
||||
void updateParameters();
|
||||
void continueUpdatingParameters();
|
||||
|
||||
private:
|
||||
|
||||
ParameterizedURL _url;
|
||||
QSharedPointer<NetworkProgram> _program;
|
||||
|
||||
QLineEdit* _line;
|
||||
};
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include <QtDebug>
|
||||
|
||||
#include "AttributeRegistry.h"
|
||||
#include "MetavoxelUtil.h"
|
||||
#include "ScriptCache.h"
|
||||
|
||||
ScriptCache* ScriptCache::getInstance() {
|
||||
|
@ -49,7 +48,9 @@ QSharedPointer<NetworkProgram> ScriptCache::getProgram(const QUrl& url) {
|
|||
QSharedPointer<NetworkValue> ScriptCache::getValue(const ParameterizedURL& url) {
|
||||
QSharedPointer<NetworkValue> value = _networkValues.value(url);
|
||||
if (value.isNull()) {
|
||||
value = QSharedPointer<NetworkValue>(new NetworkValue(getProgram(url.getURL()), url.getParameters()));
|
||||
value = QSharedPointer<NetworkValue>(url.getParameters().isEmpty() ?
|
||||
(NetworkValue*)new RootNetworkValue(getProgram(url.getURL())) :
|
||||
(NetworkValue*)new DerivedNetworkValue(getValue(url.getURL()), url.getParameters()));
|
||||
_networkValues.insert(url, value);
|
||||
}
|
||||
return value;
|
||||
|
@ -94,6 +95,8 @@ void NetworkProgram::handleDownloadProgress(qint64 bytesReceived, qint64 bytesTo
|
|||
_reply->disconnect(this);
|
||||
_reply->deleteLater();
|
||||
_reply = NULL;
|
||||
|
||||
emit loaded();
|
||||
}
|
||||
|
||||
void NetworkProgram::handleReplyError() {
|
||||
|
@ -112,14 +115,28 @@ void NetworkProgram::handleReplyError() {
|
|||
}
|
||||
}
|
||||
|
||||
NetworkValue::NetworkValue(const QSharedPointer<NetworkProgram>& program, const QVariantHash& parameters) :
|
||||
_program(program),
|
||||
_parameters(parameters) {
|
||||
NetworkValue::~NetworkValue() {
|
||||
}
|
||||
|
||||
QScriptValue& NetworkValue::getValue() {
|
||||
RootNetworkValue::RootNetworkValue(const QSharedPointer<NetworkProgram>& program) :
|
||||
_program(program) {
|
||||
}
|
||||
|
||||
QScriptValue& RootNetworkValue::getValue() {
|
||||
if (!_value.isValid() && _program->isLoaded()) {
|
||||
_value = _program->getCache()->getEngine()->evaluate(_program->getProgram());
|
||||
}
|
||||
return _value;
|
||||
}
|
||||
|
||||
DerivedNetworkValue::DerivedNetworkValue(const QSharedPointer<NetworkValue>& baseValue, const ScriptHash& parameters) :
|
||||
_baseValue(baseValue),
|
||||
_parameters(parameters) {
|
||||
}
|
||||
|
||||
QScriptValue& DerivedNetworkValue::getValue() {
|
||||
if (!_value.isValid() && _baseValue->isLoaded()) {
|
||||
_value = _baseValue->getValue();
|
||||
}
|
||||
return _value;
|
||||
}
|
||||
|
|
|
@ -15,17 +15,16 @@
|
|||
#include <QScriptProgram>
|
||||
#include <QScriptValue>
|
||||
#include <QSharedPointer>
|
||||
#include <QVariantHash>
|
||||
#include <QWeakPointer>
|
||||
|
||||
#include "MetavoxelUtil.h"
|
||||
|
||||
class QNetworkAccessManager;
|
||||
class QNetworkReply;
|
||||
class QScriptEngine;
|
||||
class QUrl;
|
||||
|
||||
class NetworkProgram;
|
||||
class NetworkValue;
|
||||
class ParameterizedURL;
|
||||
|
||||
/// Maintains a cache of loaded scripts.
|
||||
class ScriptCache : public QObject {
|
||||
|
@ -55,6 +54,7 @@ private:
|
|||
QScriptEngine* _engine;
|
||||
QHash<QUrl, QWeakPointer<NetworkProgram> > _networkPrograms;
|
||||
QHash<ParameterizedURL, QWeakPointer<NetworkValue> > _networkValues;
|
||||
|
||||
};
|
||||
|
||||
/// A program loaded from the network.
|
||||
|
@ -71,7 +71,11 @@ public:
|
|||
bool isLoaded() const { return !_program.isNull(); }
|
||||
|
||||
const QScriptProgram& getProgram() const { return _program; }
|
||||
|
||||
|
||||
signals:
|
||||
|
||||
void loaded();
|
||||
|
||||
private slots:
|
||||
|
||||
void makeRequest();
|
||||
|
@ -87,21 +91,46 @@ private:
|
|||
QScriptProgram _program;
|
||||
};
|
||||
|
||||
/// A value loaded from the network.
|
||||
/// Abstract base class of values loaded from the network.
|
||||
class NetworkValue {
|
||||
public:
|
||||
|
||||
NetworkValue(const QSharedPointer<NetworkProgram>& program, const QVariantHash& parameters);
|
||||
|
||||
virtual ~NetworkValue();
|
||||
|
||||
bool isLoaded() { return getValue().isValid(); }
|
||||
|
||||
QScriptValue& getValue();
|
||||
virtual QScriptValue& getValue() = 0;
|
||||
|
||||
protected:
|
||||
|
||||
QScriptValue _value;
|
||||
};
|
||||
|
||||
/// The direct result of running a program.
|
||||
class RootNetworkValue : public NetworkValue {
|
||||
public:
|
||||
|
||||
RootNetworkValue(const QSharedPointer<NetworkProgram>& program);
|
||||
|
||||
virtual QScriptValue& getValue();
|
||||
|
||||
private:
|
||||
|
||||
QSharedPointer<NetworkProgram> _program;
|
||||
QVariantHash _parameters;
|
||||
QScriptValue _value;
|
||||
};
|
||||
|
||||
/// The result of running a program's generator using a set of arguments.
|
||||
class DerivedNetworkValue : public NetworkValue {
|
||||
public:
|
||||
|
||||
DerivedNetworkValue(const QSharedPointer<NetworkValue>& baseValue, const ScriptHash& parameters);
|
||||
|
||||
virtual QScriptValue& getValue();
|
||||
|
||||
private:
|
||||
|
||||
QSharedPointer<NetworkValue> _baseValue;
|
||||
ScriptHash _parameters;
|
||||
};
|
||||
|
||||
#endif /* defined(__interface__ScriptCache__) */
|
||||
|
|
Loading…
Reference in a new issue