Script value streaming tests, fixes.

This commit is contained in:
Andrzej Kapolka 2014-06-09 16:51:41 -07:00
parent 7bf8fd155d
commit 590f045ed1
5 changed files with 106 additions and 6 deletions

View file

@ -411,7 +411,7 @@ void Bitstream::writeRawDelta(const QScriptValue& value, const QScriptValue& ref
*this << value;
}
} else if (reference.isObject()) {
if (value.isObject()) {
if (value.isObject()) {
*this << false;
for (QScriptValueIterator it(value); it.hasNext(); ) {
it.next();
@ -1401,14 +1401,17 @@ Bitstream& Bitstream::operator>(AttributePointer& attribute) {
return *this;
}
const QString INVALID_STRING("%INVALID%");
Bitstream& Bitstream::operator<(const QScriptString& string) {
return *this << string.toString();
return *this << (string.isValid() ? string.toString() : INVALID_STRING);
}
Bitstream& Bitstream::operator>(QScriptString& string) {
QString rawString;
*this >> rawString;
string = ScriptCache::getInstance()->getEngine()->toStringHandle(rawString);
string = (rawString == INVALID_STRING) ? QScriptString() :
ScriptCache::getInstance()->getEngine()->toStringHandle(rawString);
return *this;
}

View file

@ -20,6 +20,7 @@
#include "ScriptCache.h"
static int scriptValueMetaTypeId = qRegisterMetaType<QScriptValue>();
static bool scriptValueComparators = QMetaType::registerComparators<QScriptValue>();
bool operator==(const QScriptValue& first, const QScriptValue& second) {
if (first.isUndefined()) {
@ -97,6 +98,10 @@ bool operator!=(const QScriptValue& first, const QScriptValue& second) {
return !(first == second);
}
bool operator<(const QScriptValue& first, const QScriptValue& second) {
return first.lessThan(second);
}
ScriptCache* ScriptCache::getInstance() {
static ScriptCache cache;
return &cache;

View file

@ -69,6 +69,7 @@ Q_DECLARE_METATYPE(QScriptValue)
bool operator==(const QScriptValue& first, const QScriptValue& second);
bool operator!=(const QScriptValue& first, const QScriptValue& second);
bool operator<(const QScriptValue& first, const QScriptValue& second);
/// A program loaded from the network.
class NetworkProgram : public Resource {

View file

@ -11,6 +11,8 @@
#include <stdlib.h>
#include <QScriptValueIterator>
#include <SharedUtil.h>
#include <MetavoxelMessages.h>
@ -41,6 +43,8 @@ static int streamedBytesReceived = 0;
static int sharedObjectsCreated = 0;
static int sharedObjectsDestroyed = 0;
static int objectMutationsPerformed = 0;
static int scriptObjectsCreated = 0;
static int scriptMutationsPerformed = 0;
static QByteArray createRandomBytes(int minimumSize, int maximumSize) {
QByteArray bytes(randIntInRange(minimumSize, maximumSize), 0);
@ -79,6 +83,49 @@ static TestSharedObjectA::TestFlags getRandomTestFlags() {
return flags;
}
static QScriptValue createRandomScriptValue() {
scriptObjectsCreated++;
switch (randIntInRange(0, 3)) {
case 0:
return QScriptValue(QScriptValue::NullValue);
case 1:
return QScriptValue(randomBoolean());
case 2:
return QScriptValue(randFloat());
case 3:
default:
return QScriptValue(QString(createRandomBytes()));
case 4: {
int length = randIntInRange(2, 6);
QScriptValue value = ScriptCache::getInstance()->getEngine()->newArray(length);
for (int i = 0; i < length; i++) {
value.setProperty(i, createRandomScriptValue());
}
return value;
}
case 5: {
QScriptValue value = ScriptCache::getInstance()->getEngine()->newObject();
if (randomBoolean()) {
value.setProperty("foo", createRandomScriptValue());
}
if (randomBoolean()) {
value.setProperty("bar", createRandomScriptValue());
}
if (randomBoolean()) {
value.setProperty("baz", createRandomScriptValue());
}
if (randomBoolean()) {
value.setProperty("bong", createRandomScriptValue());
}
return value;
}
}
}
static TestMessageC createRandomMessageC() {
TestMessageC message;
message.foo = randomBoolean();
@ -86,6 +133,7 @@ static TestMessageC createRandomMessageC() {
message.baz = randFloat();
message.bong.foo = createRandomBytes();
message.bong.baz = getRandomTestEnum();
message.bizzle = createRandomScriptValue();
return message;
}
@ -201,6 +249,7 @@ bool MetavoxelTests::run() {
datagramsReceived << "with" << bytesReceived << "bytes";
qDebug() << "Created" << sharedObjectsCreated << "shared objects, destroyed" << sharedObjectsDestroyed;
qDebug() << "Performed" << objectMutationsPerformed << "object mutations";
qDebug() << "Created" << scriptObjectsCreated << "script objects, mutated" << scriptMutationsPerformed;
qDebug();
qDebug() << "Running serialization tests...";
@ -284,7 +333,7 @@ static QVariant createRandomMessage() {
}
static SharedObjectPointer mutate(const SharedObjectPointer& state) {
switch(randIntInRange(0, 3)) {
switch (randIntInRange(0, 4)) {
case 0: {
SharedObjectPointer newState = state->clone(true);
static_cast<TestSharedObjectA*>(newState.data())->setFoo(randFloat());
@ -303,6 +352,38 @@ static SharedObjectPointer mutate(const SharedObjectPointer& state) {
objectMutationsPerformed++;
return newState;
}
case 3: {
SharedObjectPointer newState = state->clone(true);
QScriptValue oldValue = static_cast<TestSharedObjectA*>(newState.data())->getBizzle();
QScriptValue newValue = ScriptCache::getInstance()->getEngine()->newObject();
for (QScriptValueIterator it(oldValue); it.hasNext(); ) {
it.next();
newValue.setProperty(it.scriptName(), it.value());
}
switch (randIntInRange(0, 3)) {
case 0: {
QScriptValue oldArray = oldValue.property("foo");
int oldLength = oldArray.property(ScriptCache::getInstance()->getLengthString()).toInt32();
QScriptValue newArray = ScriptCache::getInstance()->getEngine()->newArray(oldLength);
for (int i = 0; i < oldLength; i++) {
newArray.setProperty(i, oldArray.property(i));
}
newArray.setProperty(randIntInRange(0, oldLength - 1), createRandomScriptValue());
break;
}
case 1:
newValue.setProperty("bar", QScriptValue(randFloat()));
break;
default:
newValue.setProperty("baz", createRandomScriptValue());
break;
}
static_cast<TestSharedObjectA*>(newState.data())->setBizzle(newValue);
scriptMutationsPerformed++;
objectMutationsPerformed++;
return newState;
}
default:
return state;
}
@ -503,7 +584,10 @@ TestSharedObjectA::TestSharedObjectA(float foo, TestEnum baz, TestFlags bong) :
_foo(foo),
_baz(baz),
_bong(bong) {
sharedObjectsCreated++;
sharedObjectsCreated++;
_bizzle = ScriptCache::getInstance()->getEngine()->newObject();
_bizzle.setProperty("foo", ScriptCache::getInstance()->getEngine()->newArray(4));
}
TestSharedObjectA::~TestSharedObjectA() {

View file

@ -16,6 +16,7 @@
#include <QVariantList>
#include <DatagramSequencer.h>
#include <ScriptCache.h>
class SequencedTestMessage;
@ -96,7 +97,8 @@ class TestSharedObjectA : public SharedObject {
Q_PROPERTY(float foo READ getFoo WRITE setFoo NOTIFY fooChanged)
Q_PROPERTY(TestEnum baz READ getBaz WRITE setBaz)
Q_PROPERTY(TestFlags bong READ getBong WRITE setBong)
Q_PROPERTY(QScriptValue bizzle READ getBizzle WRITE setBizzle)
public:
enum TestEnum { FIRST_TEST_ENUM, SECOND_TEST_ENUM, THIRD_TEST_ENUM };
@ -116,6 +118,9 @@ public:
void setBong(TestFlags bong) { _bong = bong; }
TestFlags getBong() const { return _bong; }
void setBizzle(const QScriptValue& bizzle) { _bizzle = bizzle; }
const QScriptValue& getBizzle() const { return _bizzle; }
signals:
void fooChanged(float foo);
@ -125,6 +130,7 @@ private:
float _foo;
TestEnum _baz;
TestFlags _bong;
QScriptValue _bizzle;
};
DECLARE_ENUM_METATYPE(TestSharedObjectA, TestEnum)
@ -204,6 +210,7 @@ class TestMessageC : STREAM public TestMessageA {
public:
STREAM TestMessageB bong;
STREAM QScriptValue bizzle;
};
DECLARE_STREAMABLE_METATYPE(TestMessageC)