Added first draft of DataView scriptable objects

This commit is contained in:
Atlante45 2014-07-08 16:09:45 -07:00
parent 13fe8b579f
commit 2e48076408
4 changed files with 394 additions and 0 deletions

View file

@ -0,0 +1,81 @@
//
// DataViewClass.cpp
//
//
// Created by Clement on 7/8/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 "DataViewPrototype.h"
#include "DataViewClass.h"
Q_DECLARE_METATYPE(QByteArray*)
static const QString DATA_VIEW_NAME = "DataView";
DataViewClass::DataViewClass(QScriptEngine* engine) : ArrayBufferViewClass(engine) {
QScriptValue global = engine->globalObject();
// Save string handles for quick lookup
_name = engine->toStringHandle(DATA_VIEW_NAME.toLatin1());
// build prototype
_proto = engine->newQObject(new DataViewPrototype(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 DataViewClass::newInstance(QScriptValue buffer, quint32 byteOffset, quint32 byteLentgh) {
QScriptValue data = engine()->newObject();
data.setProperty(_bufferName, buffer);
data.setProperty(_byteOffsetName, byteOffset);
data.setProperty(_byteLengthName, byteLentgh);
return engine()->newObject(this, data);
}
QScriptValue DataViewClass::construct(QScriptContext *context, QScriptEngine *engine) {
DataViewClass* cls = qscriptvalue_cast<DataViewClass*>(context->callee().data());
if (!cls || context->argumentCount() < 1) {
return QScriptValue();
}
QScriptValue bufferArg = context->argument(0);
QScriptValue byteOffsetArg = (context->argumentCount() >= 2) ? context->argument(1) : QScriptValue(-1);
QScriptValue byteLengthArg = (context->argumentCount() >= 3) ? context->argument(2) : QScriptValue(-1);
QByteArray* arrayBuffer = (bufferArg.isValid()) ? qscriptvalue_cast<QByteArray*>(bufferArg.data()) :NULL;
if (!arrayBuffer) {
return QScriptValue();
}
QScriptValue newObject = cls->newInstance(bufferArg, byteOffsetArg.toInt32(), byteLengthArg.toInt32());
if (context->isCalledAsConstructor()) {
context->setThisObject(newObject);
return engine->undefinedValue();
}
return newObject;
}
QString DataViewClass::name() const {
return _name.toString();
}
QScriptValue DataViewClass::prototype() const {
return _proto;
}

View file

@ -0,0 +1,36 @@
//
// DataViewClass.h
//
//
// Created by Clement on 7/8/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
//
#ifndef hifi_DataViewClass_h
#define hifi_DataViewClass_h
#include "ArrayBufferViewClass.h"
class DataViewClass : public ArrayBufferViewClass {
Q_OBJECT
public:
DataViewClass(QScriptEngine* engine);
QScriptValue newInstance(QScriptValue buffer, quint32 byteOffset = -1, quint32 byteLength = -1);
QString name() const;
QScriptValue prototype() const;
private:
static QScriptValue construct(QScriptContext* context, QScriptEngine* engine);
QScriptValue _proto;
QScriptValue _ctor;
QScriptString _name;
};
#endif // hifi_DataViewClass_h

View file

@ -0,0 +1,209 @@
//
// DataViewPrototype.cpp
//
//
// Created by Clement on 7/8/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 <QDebug>
#include <glm/glm.hpp>
#include "DataViewClass.h"
#include "DataViewPrototype.h"
Q_DECLARE_METATYPE(QByteArray*)
DataViewPrototype::DataViewPrototype(QObject* parent) : QObject(parent) {
}
QByteArray* DataViewPrototype::thisArrayBuffer() const {
QScriptValue bufferObject = thisObject().data().property(BUFFER_PROPERTY_NAME);
return qscriptvalue_cast<QByteArray*>(bufferObject.data());
}
bool DataViewPrototype::realOffset(quint32& offset, size_t size) const {
quint32 viewOffset = thisObject().data().property(BYTE_OFFSET_PROPERTY_NAME).toInt32();
quint32 viewLength = thisObject().data().property(BYTE_LENGTH_PROPERTY_NAME).toInt32();
qDebug() << "View Offset: " << viewOffset << ", View Lenght: " << viewLength;
qDebug() << "Offset: " << offset << ", Size: " << size;
offset += viewOffset;
qDebug() << "New offset: " << offset << ", bool: " << ((offset + size) <= viewOffset + viewLength);
return (offset + size) <= viewOffset + viewLength;
}
///////////////// GETTERS ////////////////////////////
qint8 DataViewPrototype::getInt8(quint32 byteOffset) {
if (realOffset(byteOffset, sizeof(qint8))) {
qDebug() << "Value: " << (qint8)thisArrayBuffer()->at(byteOffset);
return (qint8)thisArrayBuffer()->at(byteOffset);
}
qDebug() << "42 powaaaa!!!";
return 42;
}
quint8 DataViewPrototype::getUint8(quint32 byteOffset) {
if (realOffset(byteOffset, sizeof(quint8))) { return thisArrayBuffer()->at(byteOffset);
}
return 42;
}
qint16 DataViewPrototype::getInt16(quint32 byteOffset, bool littleEndian) {
if (realOffset(byteOffset, sizeof(qint16))) {
QDataStream stream(*thisArrayBuffer());
stream.setByteOrder((littleEndian) ? QDataStream::LittleEndian : QDataStream::BigEndian);
stream.skipRawData(byteOffset);
qint16 result;
stream >> result;
return result;
}
return 42;
}
quint16 DataViewPrototype::getUint16(quint32 byteOffset, bool littleEndian) {
if (realOffset(byteOffset, sizeof(quint16))) {
QDataStream stream(*thisArrayBuffer());
stream.setByteOrder((littleEndian) ? QDataStream::LittleEndian : QDataStream::BigEndian);
stream.skipRawData(byteOffset);
qint16 result;
stream >> result;
return result;
}
return 42;
}
qint32 DataViewPrototype::getInt32(quint32 byteOffset, bool littleEndian) {
if (realOffset(byteOffset, sizeof(qint32))) {
QDataStream stream(*thisArrayBuffer());
stream.setByteOrder((littleEndian) ? QDataStream::LittleEndian : QDataStream::BigEndian);
stream.skipRawData(byteOffset);
qint16 result;
stream >> result;
return result;
}
return 42;
}
quint32 DataViewPrototype::getUint32(quint32 byteOffset, bool littleEndian) {
if (realOffset(byteOffset, sizeof(quint32))) {
QDataStream stream(*thisArrayBuffer());
stream.setByteOrder((littleEndian) ? QDataStream::LittleEndian : QDataStream::BigEndian);
stream.skipRawData(byteOffset);
qint16 result;
stream >> result;
return result;
}
return 42;
}
float DataViewPrototype::getFloat32(quint32 byteOffset, bool littleEndian) {
if (realOffset(byteOffset, sizeof(float))) {
QDataStream stream(*thisArrayBuffer());
stream.setByteOrder((littleEndian) ? QDataStream::LittleEndian : QDataStream::BigEndian);
stream.skipRawData(byteOffset);
qint16 result;
stream >> result;
return result;
}
return 42;
}
double DataViewPrototype::getFloat64(quint32 byteOffset, bool littleEndian) {
if (realOffset(byteOffset, sizeof(double))) {
QDataStream stream(*thisArrayBuffer());
stream.setByteOrder((littleEndian) ? QDataStream::LittleEndian : QDataStream::BigEndian);
stream.skipRawData(byteOffset);
qint16 result;
stream >> result;
return result;
}
return 42;
}
///////////////// SETTERS ////////////////////////////
void DataViewPrototype::setInt8(quint32 byteOffset, qint8 value) {
if (realOffset(byteOffset, sizeof(qint8))) {
QDataStream stream(thisArrayBuffer(), QIODevice::ReadWrite);
stream.skipRawData(byteOffset);
stream << value;
}
}
void DataViewPrototype::setUint8(quint32 byteOffset, quint8 value) {
if (realOffset(byteOffset, sizeof(quint8))) {
QDataStream stream(thisArrayBuffer(), QIODevice::ReadWrite);
stream.skipRawData(byteOffset);
stream << value;
}
}
void DataViewPrototype::setInt16(quint32 byteOffset, qint16 value, bool littleEndian) {
if (realOffset(byteOffset, sizeof(qint16))) {
QDataStream stream(thisArrayBuffer(), QIODevice::ReadWrite);
stream.skipRawData(byteOffset);
stream << value;
}
}
void DataViewPrototype::setUint16(quint32 byteOffset, quint16 value, bool littleEndian) {
if (realOffset(byteOffset, sizeof(quint16))) {
QDataStream stream(thisArrayBuffer(), QIODevice::ReadWrite);
stream.skipRawData(byteOffset);
stream << value;
}
}
void DataViewPrototype::setInt32(quint32 byteOffset, quint32 value, bool littleEndian) {
if (realOffset(byteOffset, sizeof(qint32))) {
QDataStream stream(thisArrayBuffer(), QIODevice::ReadWrite);
stream.skipRawData(byteOffset);
stream << value;
}
}
void DataViewPrototype::setUint32(quint32 byteOffset, quint32 value, bool littleEndian) {
if (realOffset(byteOffset, sizeof(quint32))) {
QDataStream stream(thisArrayBuffer(), QIODevice::ReadWrite);
stream.skipRawData(byteOffset);
stream << value;
}
}
void DataViewPrototype::setFloat32(quint32 byteOffset, float value, bool littleEndian) {
if (realOffset(byteOffset, sizeof(float))) {
QDataStream stream(thisArrayBuffer(), QIODevice::ReadWrite);
stream.skipRawData(byteOffset);
stream << value;
}
}
void DataViewPrototype::setFloat64(quint32 byteOffset, double value, bool littleEndian) {
if (realOffset(byteOffset, sizeof(double))) {
QDataStream stream(thisArrayBuffer(), QIODevice::ReadWrite);
stream.skipRawData(byteOffset);
stream << value;
}
}

View file

@ -0,0 +1,68 @@
//
// DataViewPrototype.h
//
//
// Created by Clement on 7/8/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
//
#ifndef hifi_DataViewPrototype_h
#define hifi_DataViewPrototype_h
#include <QtCore/QObject>
#include <QtScript/QScriptable>
class DataViewPrototype : public QObject, public QScriptable {
Q_OBJECT
public:
DataViewPrototype(QObject* parent = NULL);
public slots:
// Gets the value of the given type at the specified byte offset
// from the start of the view. There is no alignment constraint;
// multi-byte values may be fetched from any offset.
//
// For multi-byte values, the optional littleEndian argument
// indicates whether a big-endian or little-endian value should be
// read. If false or undefined, a big-endian value is read.
//
// These methods raise an exception if they would read
// beyond the end of the view.
qint8 getInt8(quint32 byteOffset);
quint8 getUint8(quint32 byteOffset);
qint16 getInt16(quint32 byteOffset, bool littleEndian = false);
quint16 getUint16(quint32 byteOffset, bool littleEndian = false);
qint32 getInt32(quint32 byteOffset, bool littleEndian = false);
quint32 getUint32(quint32 byteOffset, bool littleEndian = false);
float getFloat32(quint32 byteOffset, bool littleEndian = false);
double getFloat64(quint32 byteOffset, bool littleEndian = false);
// Stores a value of the given type at the specified byte offset
// from the start of the view. There is no alignment constraint;
// multi-byte values may be stored at any offset.
//
// For multi-byte values, the optional littleEndian argument
// indicates whether the value should be stored in big-endian or
// little-endian byte order. If false or undefined, the value is
// stored in big-endian byte order.
//
// These methods raise an exception if they would write
// beyond the end of the view.
void setInt8(quint32 byteOffset, qint8 value);
void setUint8(quint32 byteOffset, quint8 value);
void setInt16(quint32 byteOffset, qint16 value, bool littleEndian = false);
void setUint16(quint32 byteOffset, quint16 value, bool littleEndian = false);
void setInt32(quint32 byteOffset, quint32 value, bool littleEndian = false);
void setUint32(quint32 byteOffset, quint32 value, bool littleEndian = false);
void setFloat32(quint32 byteOffset, float value, bool littleEndian = false);
void setFloat64(quint32 byteOffset, double value, bool littleEndian = false);
private:
QByteArray* thisArrayBuffer() const;
bool realOffset(quint32& offset, size_t size) const;
};
#endif // hifi_DataViewPrototype_h