Functional ArrayBuffer class following Qt standard

This commit is contained in:
Atlante45 2014-07-07 18:02:33 -07:00
parent c246205692
commit f9b739a0d1
6 changed files with 143 additions and 127 deletions

View file

@ -1,105 +0,0 @@
//
// ArrayBuffer.cpp
//
//
// Created by Clement on 7/3/14.
// Copyright 2014 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "ArrayBufferPrototype.h"
#include "ArrayBuffer.h"
Q_DECLARE_METATYPE(QByteArray*)
Q_DECLARE_METATYPE(ArrayBuffer*)
ArrayBuffer::ArrayBuffer(QScriptEngine* engine) : QObject(engine), QScriptClass(engine) {
qScriptRegisterMetaType<QByteArray>(engine, toScriptValue, fromScriptValue);
_byteLength = engine->toStringHandle(QLatin1String("byteLength"));
// _proto = engine->newQObject(new ArrayBufferPrototype(this),
// QScriptEngine::QtOwnership,
// QScriptEngine::SkipMethodsInEnumeration
// | QScriptEngine::ExcludeSuperClassMethods
// | QScriptEngine::ExcludeSuperClassProperties);
QScriptValue global = engine->globalObject();
_proto.setPrototype(global.property("Object").property("prototype"));
_ctor = engine->newFunction(construct, _proto);
_ctor.setData(engine->toScriptValue(this));
}
QScriptValue ArrayBuffer::newInstance(unsigned long size) {
engine()->reportAdditionalMemoryCost(size);
QScriptValue data = engine()->newVariant(QVariant::fromValue(QByteArray(size, 0)));
return engine()->newObject(this, data);
}
QScriptValue ArrayBuffer::newInstance(const QByteArray& ba) {
QScriptValue data = engine()->newVariant(QVariant::fromValue(ba));
return engine()->newObject(this, data);
}
QScriptValue ArrayBuffer::construct(QScriptContext* ctx, QScriptEngine* eng) {
ArrayBuffer* cls = qscriptvalue_cast<ArrayBuffer*>(ctx->callee().data());
QScriptValue arg = ctx->argument(0);
int size = arg.toInt32();
return cls ? cls->newInstance(size) : QScriptValue();
}
QScriptClass::QueryFlags ArrayBuffer::queryProperty(const QScriptValue& object,
const QScriptString& name,
QueryFlags flags, uint* id) {
QByteArray* ba = qscriptvalue_cast<QByteArray*>(object.data());
if (ba && name == _byteLength) {
// if the property queried is byteLength, only handle read access
return flags &= HandlesReadAccess;
}
return 0; // No access
}
QScriptValue ArrayBuffer::property(const QScriptValue &object,
const QScriptString &name, uint id) {
QByteArray* ba = qscriptvalue_cast<QByteArray*>(object.data());
if (ba && name == _byteLength) {
return ba->length();
}
return QScriptValue();
}
QScriptValue::PropertyFlags ArrayBuffer::propertyFlags(const QScriptValue& object,
const QScriptString& name, uint id) {
return QScriptValue::Undeletable;
}
QString ArrayBuffer::name() const {
return QLatin1String("ArrayBuffer");
}
QScriptValue ArrayBuffer::prototype() const {
return _proto;
}
QScriptValue ArrayBuffer::constructor() const {
return _ctor;
}
QScriptValue ArrayBuffer::toScriptValue(QScriptEngine* eng, const QByteArray& ba)
{
QScriptValue ctor = eng->globalObject().property("ArrayBuffer");
ArrayBuffer *cls = qscriptvalue_cast<ArrayBuffer*>(ctor.data());
if (!cls) {
return eng->newVariant(QVariant::fromValue(ba));
}
return cls->newInstance(ba);
}
void ArrayBuffer::fromScriptValue(const QScriptValue& obj, QByteArray& ba) {
ba = qvariant_cast<QByteArray>(obj.data().toVariant());
}

View file

@ -0,0 +1,119 @@
//
// ArrayBufferClass.cpp
//
//
// Created by Clement on 7/3/14.
// Copyright 2014 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "ArrayBufferPrototype.h"
#include "ArrayBufferClass.h"
static const QString CLASS_NAME = "ArrayBuffer";
static const QString BYTE_LENGTH_PROPERTY_NAME = "byteLength";
Q_DECLARE_METATYPE(QByteArray*)
ArrayBufferClass::ArrayBufferClass(QScriptEngine* engine) : QObject(engine), QScriptClass(engine) {
qScriptRegisterMetaType<QByteArray>(engine, toScriptValue, fromScriptValue);
QScriptValue global = engine->globalObject();
// Save string handles for quick lookup
_name = engine->toStringHandle(CLASS_NAME.toLatin1());
_byteLength = engine->toStringHandle(BYTE_LENGTH_PROPERTY_NAME.toLatin1());
// build prototype
_proto = engine->newQObject(new ArrayBufferPrototype(this),
QScriptEngine::QtOwnership,
QScriptEngine::SkipMethodsInEnumeration |
QScriptEngine::ExcludeSuperClassMethods |
QScriptEngine::ExcludeSuperClassProperties);
_proto.setPrototype(global.property("Object").property("prototype"));
_ctor = engine->newFunction(construct, _proto);
_ctor.setData(engine->toScriptValue(this));
engine->globalObject().setProperty(name(), _ctor);
}
QScriptValue ArrayBufferClass::newInstance(unsigned long size) {
engine()->reportAdditionalMemoryCost(size);
QScriptValue data = engine()->newVariant(QVariant::fromValue(QByteArray(size, 0)));
return engine()->newObject(this, data);
}
QScriptValue ArrayBufferClass::newInstance(const QByteArray& ba) {
QScriptValue data = engine()->newVariant(QVariant::fromValue(ba));
return engine()->newObject(this, data);
}
QScriptValue ArrayBufferClass::construct(QScriptContext* context, QScriptEngine* engine) {
ArrayBufferClass* cls = qscriptvalue_cast<ArrayBufferClass*>(context->callee().data());
if (!cls) {
return QScriptValue();
}
QScriptValue arg = context->argument(0);
unsigned long size = arg.toInt32();
QScriptValue newObject = cls->newInstance(size);
if (context->isCalledAsConstructor()) {
context->setThisObject(newObject);
return engine->undefinedValue();
}
return newObject;
}
QScriptClass::QueryFlags ArrayBufferClass::queryProperty(const QScriptValue& object,
const QScriptString& name,
QueryFlags flags, uint* id) {
QByteArray* ba = qscriptvalue_cast<QByteArray*>(object.data());
if (ba && name == _byteLength) {
// if the property queried is byteLength, only handle read access
return flags &= HandlesReadAccess;
}
return 0; // No access
}
QScriptValue ArrayBufferClass::property(const QScriptValue &object,
const QScriptString &name, uint id) {
QByteArray* ba = qscriptvalue_cast<QByteArray*>(object.data());
if (ba && name == _byteLength) {
return ba->length();
}
return QScriptValue();
}
QScriptValue::PropertyFlags ArrayBufferClass::propertyFlags(const QScriptValue& object,
const QScriptString& name, uint id) {
return QScriptValue::Undeletable;
}
QString ArrayBufferClass::name() const {
return _name.toString();
}
QScriptValue ArrayBufferClass::prototype() const {
return _proto;
}
QScriptValue ArrayBufferClass::toScriptValue(QScriptEngine* engine, const QByteArray& ba) {
QScriptValue ctor = engine->globalObject().property(CLASS_NAME);
ArrayBufferClass* cls = qscriptvalue_cast<ArrayBufferClass*>(ctor.data());
if (!cls) {
return engine->newVariant(QVariant::fromValue(ba));
}
return cls->newInstance(ba);
}
void ArrayBufferClass::fromScriptValue(const QScriptValue& obj, QByteArray& ba) {
ba = qvariant_cast<QByteArray>(obj.data().toVariant());
}

View file

@ -1,5 +1,5 @@
//
// ArrayBuffer.h
// ArrayBufferClass.h
//
//
// Created by Clement on 7/3/14.
@ -9,8 +9,8 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#ifndef hifi_ArrayBuffer_h
#define hifi_ArrayBuffer_h
#ifndef hifi_ArrayBufferClass_h
#define hifi_ArrayBufferClass_h
#include <QScriptClass>
#include <QtCore/QObject>
@ -20,28 +20,26 @@
#include <QtScript/QScriptString>
#include <QtScript/QScriptValue>
class ArrayBuffer : public QObject, public QScriptClass {
class ArrayBufferClass : public QObject, public QScriptClass {
Q_OBJECT
public:
ArrayBuffer(QScriptEngine* engine);
QScriptValue newInstance(unsigned long size = 0);
ArrayBufferClass(QScriptEngine* engine);
QScriptValue newInstance(unsigned long size);
QScriptValue newInstance(const QByteArray& ba);
QueryFlags queryProperty(const QScriptValue& object,
const QScriptString& name,
QueryFlags flags, uint* id);
QScriptValue property(const QScriptValue& object,
const QScriptString& name,
uint id);
QScriptValue property(const QScriptValue &object,
const QScriptString &name, uint id);
QScriptValue::PropertyFlags propertyFlags(const QScriptValue& object,
const QScriptString& name,
uint id);
const QScriptString& name, uint id);
QString name() const;
QScriptValue prototype() const;
QScriptValue constructor() const;
private:
static QScriptValue construct(QScriptContext* ctx, QScriptEngine* eng);
static QScriptValue construct(QScriptContext* context, QScriptEngine* engine);
static QScriptValue toScriptValue(QScriptEngine* eng, const QByteArray& ba);
static void fromScriptValue(const QScriptValue& obj, QByteArray& ba);
@ -50,7 +48,8 @@ private:
QScriptValue _ctor;
// JS Object attributes
QScriptString _name;
QScriptString _byteLength;
};
#endif // hifi_ArrayBuffer_h
#endif // hifi_ArrayBufferClass_h

View file

@ -11,19 +11,19 @@
#include <QScriptEngine>
#include "ArrayBufferClass.h"
#include "ArrayBufferPrototype.h"
Q_DECLARE_METATYPE(QByteArray*)
ArrayBufferPrototype::ArrayBufferPrototype(QObject* parent) : QObject(parent) {
}
QByteArray ArrayBufferPrototype::slice(long begin, long end) const {
if (end == -1) {
return thisArrayBuffer().mid(begin);
} else {
return thisArrayBuffer().mid(begin, end);
}
return thisArrayBuffer()->mid(begin, end);
}
QByteArray ArrayBufferPrototype::thisArrayBuffer() const {
return qscriptvalue_cast<QByteArray>(thisObject().data());
QByteArray* ArrayBufferPrototype::thisArrayBuffer() const {
return qscriptvalue_cast<QByteArray*>(thisObject().data());
}

View file

@ -26,7 +26,7 @@ public slots:
QByteArray slice(long begin, long end = -1) const;
private:
QByteArray thisArrayBuffer() const;
QByteArray* thisArrayBuffer() const;
};
#endif // hifi_ArrayBufferPrototype_h

View file

@ -32,6 +32,7 @@
#include <VoxelDetail.h>
#include "AnimationObject.h"
#include "ArrayBufferClass.h"
#include "MenuItemProperties.h"
#include "MIDIEvent.h"
#include "LocalVoxels.h"
@ -211,6 +212,8 @@ void ScriptEngine::init() {
return; // only initialize once
}
new ArrayBufferClass(&_engine);
_isInitialized = true;
_voxelsScriptingInterface.init();