Streaming cleanup, streaming script strings as repeated values.

This commit is contained in:
Andrzej Kapolka 2014-02-04 18:31:18 -08:00
parent ca52d67041
commit 4f4c4c68d9
8 changed files with 206 additions and 214 deletions

View file

@ -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);
})

View file

@ -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;

View file

@ -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();

View file

@ -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();
}
}

View file

@ -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();
}

View file

@ -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;
};

View file

@ -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;
}

View file

@ -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__) */