mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-04 20:13:09 +02:00
- Bunch of fixes to typed arrays
- First working prototype for Int8Array - Base classes for all other typed arrays
This commit is contained in:
parent
a76ebae771
commit
b2b1701965
10 changed files with 412 additions and 37 deletions
|
@ -9,8 +9,10 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include "ArrayBufferPrototype.h"
|
||||
#include "ScriptEngine.h"
|
||||
|
||||
#include "ArrayBufferClass.h"
|
||||
|
||||
|
@ -19,16 +21,20 @@ 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();
|
||||
ArrayBufferClass::ArrayBufferClass(ScriptEngine* scriptEngine) :
|
||||
QObject(scriptEngine->getScriptEngine()),
|
||||
QScriptClass(scriptEngine->getScriptEngine()),
|
||||
_scriptEngine(scriptEngine) {
|
||||
qDebug() << "Created with engine: " << 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());
|
||||
_name = engine()->toStringHandle(CLASS_NAME.toLatin1());
|
||||
_byteLength = engine()->toStringHandle(BYTE_LENGTH_PROPERTY_NAME.toLatin1());
|
||||
|
||||
// build prototype
|
||||
_proto = engine->newQObject(new ArrayBufferPrototype(this),
|
||||
_proto = engine()->newQObject(new ArrayBufferPrototype(this),
|
||||
QScriptEngine::QtOwnership,
|
||||
QScriptEngine::SkipMethodsInEnumeration |
|
||||
QScriptEngine::ExcludeSuperClassMethods |
|
||||
|
@ -36,15 +42,17 @@ ArrayBufferClass::ArrayBufferClass(QScriptEngine* engine) : QObject(engine), QSc
|
|||
|
||||
_proto.setPrototype(global.property("Object").property("prototype"));
|
||||
|
||||
_ctor = engine->newFunction(construct, _proto);
|
||||
_ctor.setData(engine->toScriptValue(this));
|
||||
_ctor = engine()->newFunction(construct, _proto);
|
||||
_ctor.setData(engine()->toScriptValue(this));
|
||||
|
||||
engine->globalObject().setProperty(name(), _ctor);
|
||||
engine()->globalObject().setProperty(name(), _ctor);
|
||||
}
|
||||
|
||||
QScriptValue ArrayBufferClass::newInstance(quint32 size) {
|
||||
engine()->reportAdditionalMemoryCost(size);
|
||||
QScriptValue data = engine()->newVariant(QVariant::fromValue(QByteArray(size, 0)));
|
||||
QScriptEngine* eng = engine();
|
||||
QVariant variant = QVariant::fromValue(QByteArray(size, 0));
|
||||
QScriptValue data = eng->newVariant(variant);
|
||||
return engine()->newObject(this, data);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,13 +20,17 @@
|
|||
#include <QtScript/QScriptString>
|
||||
#include <QtScript/QScriptValue>
|
||||
|
||||
class ScriptEngine;
|
||||
|
||||
class ArrayBufferClass : public QObject, public QScriptClass {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ArrayBufferClass(QScriptEngine* engine);
|
||||
ArrayBufferClass(ScriptEngine* scriptEngine);
|
||||
QScriptValue newInstance(quint32 size);
|
||||
QScriptValue newInstance(const QByteArray& ba);
|
||||
|
||||
ScriptEngine* getScriptEngine() { return _scriptEngine; }
|
||||
|
||||
QueryFlags queryProperty(const QScriptValue& object,
|
||||
const QScriptString& name,
|
||||
QueryFlags flags, uint* id);
|
||||
|
@ -50,6 +54,8 @@ private:
|
|||
// JS Object attributes
|
||||
QScriptString _name;
|
||||
QScriptString _byteLength;
|
||||
|
||||
ScriptEngine* _scriptEngine;
|
||||
};
|
||||
|
||||
#endif // hifi_ArrayBufferClass_h
|
|
@ -13,13 +13,14 @@
|
|||
|
||||
Q_DECLARE_METATYPE(QByteArray*)
|
||||
|
||||
ArrayBufferViewClass::ArrayBufferViewClass(QScriptEngine* engine) :
|
||||
QObject(engine),
|
||||
QScriptClass(engine) {
|
||||
ArrayBufferViewClass::ArrayBufferViewClass(ScriptEngine* scriptEngine) :
|
||||
QObject(scriptEngine->getScriptEngine()),
|
||||
QScriptClass(scriptEngine->getScriptEngine()),
|
||||
_scriptEngine(scriptEngine) {
|
||||
// Save string handles for quick lookup
|
||||
_bufferName = engine->toStringHandle(BUFFER_PROPERTY_NAME.toLatin1());
|
||||
_byteOffsetName = engine->toStringHandle(BYTE_OFFSET_PROPERTY_NAME.toLatin1());
|
||||
_byteLengthName = engine->toStringHandle(BYTE_LENGTH_PROPERTY_NAME.toLatin1());
|
||||
_bufferName = engine()->toStringHandle(BUFFER_PROPERTY_NAME.toLatin1());
|
||||
_byteOffsetName = engine()->toStringHandle(BYTE_OFFSET_PROPERTY_NAME.toLatin1());
|
||||
_byteLengthName = engine()->toStringHandle(BYTE_LENGTH_PROPERTY_NAME.toLatin1());
|
||||
}
|
||||
|
||||
QScriptClass::QueryFlags ArrayBufferViewClass::queryProperty(const QScriptValue& object,
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include <QtScript/QScriptString>
|
||||
#include <QtScript/QScriptValue>
|
||||
|
||||
#include "ScriptEngine.h"
|
||||
|
||||
static const QString BUFFER_PROPERTY_NAME = "buffer";
|
||||
static const QString BYTE_OFFSET_PROPERTY_NAME = "byteOffset";
|
||||
static const QString BYTE_LENGTH_PROPERTY_NAME = "byteLength";
|
||||
|
@ -27,21 +29,24 @@ static const QString BYTE_LENGTH_PROPERTY_NAME = "byteLength";
|
|||
class ArrayBufferViewClass : public QObject, public QScriptClass {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ArrayBufferViewClass(QScriptEngine* engine);
|
||||
ArrayBufferViewClass(ScriptEngine* scriptEngine);
|
||||
|
||||
ScriptEngine* getScriptEngine() { return _scriptEngine; }
|
||||
|
||||
QueryFlags queryProperty(const QScriptValue& object,
|
||||
virtual QueryFlags queryProperty(const QScriptValue& object,
|
||||
const QScriptString& name,
|
||||
QueryFlags flags, uint* id);
|
||||
QScriptValue property(const QScriptValue &object,
|
||||
virtual QScriptValue property(const QScriptValue &object,
|
||||
const QScriptString &name, uint id);
|
||||
QScriptValue::PropertyFlags propertyFlags(const QScriptValue& object,
|
||||
virtual QScriptValue::PropertyFlags propertyFlags(const QScriptValue& object,
|
||||
const QScriptString& name, uint id);
|
||||
protected:
|
||||
// JS Object attributes
|
||||
QScriptString _bufferName;
|
||||
QScriptString _byteOffsetName;
|
||||
QScriptString _byteLengthName;
|
||||
|
||||
ScriptEngine* _scriptEngine;
|
||||
};
|
||||
|
||||
#endif // hifi_ArrayBufferViewClass_h
|
|
@ -17,14 +17,14 @@ Q_DECLARE_METATYPE(QByteArray*)
|
|||
|
||||
static const QString DATA_VIEW_NAME = "DataView";
|
||||
|
||||
DataViewClass::DataViewClass(QScriptEngine* engine) : ArrayBufferViewClass(engine) {
|
||||
QScriptValue global = engine->globalObject();
|
||||
DataViewClass::DataViewClass(ScriptEngine* scriptEngine) : ArrayBufferViewClass(scriptEngine) {
|
||||
QScriptValue global = engine()->globalObject();
|
||||
|
||||
// Save string handles for quick lookup
|
||||
_name = engine->toStringHandle(DATA_VIEW_NAME.toLatin1());
|
||||
_name = engine()->toStringHandle(DATA_VIEW_NAME.toLatin1());
|
||||
|
||||
// build prototype
|
||||
_proto = engine->newQObject(new DataViewPrototype(this),
|
||||
_proto = engine()->newQObject(new DataViewPrototype(this),
|
||||
QScriptEngine::QtOwnership,
|
||||
QScriptEngine::SkipMethodsInEnumeration |
|
||||
QScriptEngine::ExcludeSuperClassMethods |
|
||||
|
@ -32,10 +32,10 @@ DataViewClass::DataViewClass(QScriptEngine* engine) : ArrayBufferViewClass(engin
|
|||
|
||||
_proto.setPrototype(global.property("Object").property("prototype"));
|
||||
|
||||
_ctor = engine->newFunction(construct, _proto);
|
||||
_ctor.setData(engine->toScriptValue(this));
|
||||
_ctor = engine()->newFunction(construct, _proto);
|
||||
_ctor.setData(engine()->toScriptValue(this));
|
||||
|
||||
engine->globalObject().setProperty(name(), _ctor);
|
||||
engine()->globalObject().setProperty(name(), _ctor);
|
||||
}
|
||||
|
||||
QScriptValue DataViewClass::newInstance(QScriptValue buffer, quint32 byteOffset, quint32 byteLentgh) {
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
class DataViewClass : public ArrayBufferViewClass {
|
||||
Q_OBJECT
|
||||
public:
|
||||
DataViewClass(QScriptEngine* engine);
|
||||
DataViewClass(ScriptEngine* scriptEngine);
|
||||
QScriptValue newInstance(QScriptValue buffer, quint32 byteOffset, quint32 byteLength);
|
||||
|
||||
QString name() const;
|
||||
|
|
|
@ -32,13 +32,13 @@
|
|||
#include <VoxelDetail.h>
|
||||
|
||||
#include "AnimationObject.h"
|
||||
#include "ArrayBufferClass.h"
|
||||
#include "ArrayBufferViewClass.h"
|
||||
#include "DataViewClass.h"
|
||||
#include "MenuItemProperties.h"
|
||||
#include "MIDIEvent.h"
|
||||
#include "LocalVoxels.h"
|
||||
#include "ScriptEngine.h"
|
||||
#include "TypedArrays.h"
|
||||
#include "XMLHttpRequestClass.h"
|
||||
|
||||
VoxelsScriptingInterface ScriptEngine::_voxelsScriptingInterface;
|
||||
|
@ -93,8 +93,15 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNam
|
|||
_quatLibrary(),
|
||||
_vec3Library(),
|
||||
_uuidLibrary(),
|
||||
_animationCache(this)
|
||||
_animationCache(this),
|
||||
_arrayBufferClass(NULL)
|
||||
{
|
||||
_arrayBufferClass = new ArrayBufferClass(this);
|
||||
qDebug() << "Engine: " << this;
|
||||
qDebug() << "ArrayBuffer: " <<_arrayBufferClass;
|
||||
qDebug() << "DataView: " << new DataViewClass(this);
|
||||
qDebug() << "Int8Array: " << new Int8ArrayClass(this);
|
||||
qDebug() << "Initial thread: " << QThread::currentThread() << " " << thread();
|
||||
}
|
||||
|
||||
ScriptEngine::ScriptEngine(const QUrl& scriptURL,
|
||||
|
@ -118,13 +125,21 @@ ScriptEngine::ScriptEngine(const QUrl& scriptURL,
|
|||
_quatLibrary(),
|
||||
_vec3Library(),
|
||||
_uuidLibrary(),
|
||||
_animationCache(this)
|
||||
_animationCache(this),
|
||||
_arrayBufferClass(NULL)
|
||||
{
|
||||
QString scriptURLString = scriptURL.toString();
|
||||
_fileNameString = scriptURLString;
|
||||
|
||||
QUrl url(scriptURL);
|
||||
|
||||
|
||||
_arrayBufferClass = new ArrayBufferClass(this);
|
||||
qDebug() << "Engine: " << this;
|
||||
qDebug() << "ArrayBuffer: " <<_arrayBufferClass;
|
||||
qDebug() << "DataView: " << new DataViewClass(this);
|
||||
qDebug() << "Int8Array: " << new Int8ArrayClass(this);
|
||||
qDebug() << "Initial thread: " << QThread::currentThread() << " " << thread();
|
||||
|
||||
// if the scheme length is one or lower, maybe they typed in a file, let's try
|
||||
const int WINDOWS_DRIVE_LETTER_SIZE = 1;
|
||||
if (url.scheme().size() <= WINDOWS_DRIVE_LETTER_SIZE) {
|
||||
|
@ -141,6 +156,7 @@ ScriptEngine::ScriptEngine(const QUrl& scriptURL,
|
|||
QTextStream in(&scriptFile);
|
||||
_scriptContents = in.readAll();
|
||||
} else {
|
||||
|
||||
qDebug() << "ERROR Loading file:" << fileName;
|
||||
emit errorMessage("ERROR Loading file:" + fileName);
|
||||
}
|
||||
|
@ -213,10 +229,6 @@ void ScriptEngine::init() {
|
|||
if (_isInitialized) {
|
||||
return; // only initialize once
|
||||
}
|
||||
|
||||
new ArrayBufferClass(&_engine);
|
||||
new ArrayBufferViewClass(&_engine);
|
||||
new DataViewClass(&_engine);
|
||||
|
||||
_isInitialized = true;
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <VoxelsScriptingInterface.h>
|
||||
|
||||
#include "AbstractControllerScriptingInterface.h"
|
||||
#include "ArrayBufferClass.h"
|
||||
#include "Quat.h"
|
||||
#include "ScriptUUID.h"
|
||||
#include "Vec3.h"
|
||||
|
@ -56,6 +57,9 @@ public:
|
|||
/// Access the ModelsScriptingInterface in order to initialize it with a custom packet sender and jurisdiction listener
|
||||
static ModelsScriptingInterface* getModelsScriptingInterface() { return &_modelsScriptingInterface; }
|
||||
|
||||
QScriptEngine* getScriptEngine() { return &_engine; }
|
||||
ArrayBufferClass* getArrayBufferClass() { return _arrayBufferClass; }
|
||||
|
||||
/// sets the script contents, will return false if failed, will fail if script is already running
|
||||
bool setScriptContents(const QString& scriptContents, const QString& fileNameString = QString(""));
|
||||
|
||||
|
@ -147,6 +151,8 @@ private:
|
|||
Vec3 _vec3Library;
|
||||
ScriptUUID _uuidLibrary;
|
||||
AnimationCache _animationCache;
|
||||
|
||||
ArrayBufferClass* _arrayBufferClass;
|
||||
|
||||
QHash<QUuid, quint16> _outgoingScriptAudioSequenceNumbers;
|
||||
};
|
||||
|
|
233
libraries/script-engine/src/TypedArrays.cpp
Normal file
233
libraries/script-engine/src/TypedArrays.cpp
Normal file
|
@ -0,0 +1,233 @@
|
|||
//
|
||||
// TypedArrays.cpp
|
||||
//
|
||||
//
|
||||
// Created by Clement on 7/9/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 "ScriptEngine.h"
|
||||
|
||||
#include "TypedArrays.h"
|
||||
|
||||
Q_DECLARE_METATYPE(QByteArray*)
|
||||
|
||||
TypedArray::TypedArray(ScriptEngine* scriptEngine, QString name) : ArrayBufferViewClass(scriptEngine) {
|
||||
_bytesPerElementName = engine()->toStringHandle(BYTES_PER_ELEMENT_PROPERTY_NAME.toLatin1());
|
||||
_lengthName = engine()->toStringHandle(LENGTH_PROPERTY_NAME.toLatin1());
|
||||
_name = engine()->toStringHandle(name.toLatin1());
|
||||
}
|
||||
|
||||
QScriptValue TypedArray::construct(QScriptContext *context, QScriptEngine *engine) {
|
||||
TypedArray* cls = qscriptvalue_cast<TypedArray*>(context->callee().data());
|
||||
if (!cls || context->argumentCount() < 1) {
|
||||
return QScriptValue();
|
||||
}
|
||||
|
||||
QScriptValue newObject;
|
||||
QScriptValue bufferArg = context->argument(0);
|
||||
QByteArray* arrayBuffer = qscriptvalue_cast<QByteArray*>(bufferArg.data());
|
||||
TypedArray* typedArray = qscriptvalue_cast<TypedArray*>(bufferArg);
|
||||
|
||||
if (arrayBuffer) {
|
||||
if (context->argumentCount() == 1) {
|
||||
// Case for entire ArrayBuffer
|
||||
newObject = cls->newInstance(bufferArg, 0, arrayBuffer->size());
|
||||
} else {
|
||||
QScriptValue byteOffsetArg = context->argument(1);
|
||||
if (!byteOffsetArg.isNumber()) {
|
||||
engine->evaluate("throw \"ArgumentError: 2nd arg is not a number\"");
|
||||
return QScriptValue();
|
||||
}
|
||||
if (byteOffsetArg.toInt32() < 0 || byteOffsetArg.toInt32() >= arrayBuffer->size()) {
|
||||
engine->evaluate("throw \"RangeError: byteOffset out of range\"");
|
||||
return QScriptValue();
|
||||
}
|
||||
quint32 byteOffset = byteOffsetArg.toInt32();
|
||||
|
||||
if (context->argumentCount() == 2) {
|
||||
// case for end of ArrayBuffer
|
||||
newObject = cls->newInstance(bufferArg, byteOffset, arrayBuffer->size() - byteOffset);
|
||||
} else {
|
||||
|
||||
QScriptValue lengthArg = (context->argumentCount() > 2) ? context->argument(2) : QScriptValue();
|
||||
if (!lengthArg.isNumber()) {
|
||||
engine->evaluate("throw \"ArgumentError: 3nd arg is not a number\"");
|
||||
return QScriptValue();
|
||||
}
|
||||
if (lengthArg.toInt32() < 0 ||
|
||||
byteOffsetArg.toInt32() + lengthArg.toInt32() * cls->_bytesPerElement > arrayBuffer->size()) {
|
||||
engine->evaluate("throw \"RangeError: byteLength out of range\"");
|
||||
return QScriptValue();
|
||||
}
|
||||
quint32 length = lengthArg.toInt32() * cls->_bytesPerElement;
|
||||
|
||||
// case for well-defined range
|
||||
newObject = cls->newInstance(bufferArg, byteOffset, length);
|
||||
}
|
||||
}
|
||||
} else if (typedArray) {
|
||||
// case for another reference to another TypedArray
|
||||
newObject = cls->newInstance(bufferArg, true);
|
||||
} else if (context->argument(0).isNumber()) {
|
||||
// case for new ArrayBuffer
|
||||
newObject = cls->newInstance(context->argument(0).toInt32());
|
||||
} else {
|
||||
// TODO: Standard array case
|
||||
}
|
||||
|
||||
if (context->isCalledAsConstructor()) {
|
||||
context->setThisObject(newObject);
|
||||
return engine->undefinedValue();
|
||||
}
|
||||
|
||||
return newObject;
|
||||
}
|
||||
|
||||
QScriptClass::QueryFlags TypedArray::queryProperty(const QScriptValue& object,
|
||||
const QScriptString& name,
|
||||
QueryFlags flags, uint* id) {
|
||||
if (name == _bytesPerElementName || name == _lengthName) {
|
||||
return flags &= HandlesReadAccess; // Only keep read access flags
|
||||
}
|
||||
return ArrayBufferViewClass::queryProperty(object, name, flags, id);
|
||||
}
|
||||
|
||||
QScriptValue TypedArray::property(const QScriptValue &object,
|
||||
const QScriptString &name, uint id) {
|
||||
if (name == _bytesPerElementName) {
|
||||
return QScriptValue(_bytesPerElement);
|
||||
}
|
||||
if (name == _lengthName) {
|
||||
return object.data().property(_lengthName);
|
||||
}
|
||||
return ArrayBufferViewClass::property(object, name, id);
|
||||
}
|
||||
|
||||
QScriptValue::PropertyFlags TypedArray::propertyFlags(const QScriptValue& object,
|
||||
const QScriptString& name, uint id) {
|
||||
return QScriptValue::Undeletable;
|
||||
}
|
||||
|
||||
QString TypedArray::name() const {
|
||||
return _name.toString();
|
||||
}
|
||||
|
||||
QScriptValue TypedArray::prototype() const {
|
||||
return _proto;
|
||||
}
|
||||
|
||||
Int8ArrayClass::Int8ArrayClass(ScriptEngine* scriptEngine) : TypedArray(scriptEngine, INT_8_ARRAY_CLASS_NAME) {
|
||||
QScriptValue global = engine()->globalObject();
|
||||
|
||||
_bytesPerElement = sizeof(qint8);
|
||||
|
||||
// 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 Int8ArrayClass::newInstance(quint32 length) {
|
||||
ArrayBufferClass* array = getScriptEngine()->getArrayBufferClass();
|
||||
QScriptValue buffer = array->newInstance(length * _bytesPerElement);
|
||||
return newInstance(buffer, 0, length);
|
||||
}
|
||||
|
||||
QScriptValue Int8ArrayClass::newInstance(QScriptValue array, bool isTypedArray) {
|
||||
// TODO
|
||||
assert(false);
|
||||
if (isTypedArray) {
|
||||
QByteArray* originalArray = qscriptvalue_cast<QByteArray*>(array.data().property(_bufferName).data());
|
||||
ArrayBufferClass* arrayBufferClass = reinterpret_cast<ScriptEngine*>(engine())->getArrayBufferClass();
|
||||
quint32 byteOffset = array.data().property(_byteOffsetName).toInt32();
|
||||
quint32 byteLength = array.data().property(_byteLengthName).toInt32();
|
||||
quint32 length = byteLength / _bytesPerElement;
|
||||
QByteArray newArray = originalArray->mid(byteOffset, byteLength);
|
||||
|
||||
if (byteLength % _bytesPerElement != 0) {
|
||||
length += 1;
|
||||
byteLength = length * _bytesPerElement;
|
||||
}
|
||||
|
||||
|
||||
return newInstance(arrayBufferClass->newInstance(newArray),
|
||||
array.data().property(_byteOffsetName).toInt32(),
|
||||
array.data().property(_lengthName).toInt32());
|
||||
}
|
||||
return QScriptValue();
|
||||
}
|
||||
|
||||
QScriptValue Int8ArrayClass::newInstance(QScriptValue buffer, quint32 byteOffset, quint32 length) {
|
||||
QScriptValue data = engine()->newObject();
|
||||
data.setProperty(_bufferName, buffer);
|
||||
data.setProperty(_byteOffsetName, byteOffset);
|
||||
data.setProperty(_byteLengthName, length * _bytesPerElement);
|
||||
data.setProperty(_lengthName, length);
|
||||
|
||||
return engine()->newObject(this, data);
|
||||
}
|
||||
|
||||
QScriptClass::QueryFlags Int8ArrayClass::queryProperty(const QScriptValue& object,
|
||||
const QScriptString& name,
|
||||
QueryFlags flags, uint* id) {
|
||||
quint32 byteOffset = object.data().property(_byteOffsetName).toInt32();
|
||||
quint32 length = object.data().property(_lengthName).toInt32();
|
||||
bool ok = false;
|
||||
int pos = name.toArrayIndex(&ok);
|
||||
|
||||
// Check that name is a valid index and arrayBuffer exists
|
||||
if (ok && pos >= 0 && pos < length) {
|
||||
*id = byteOffset + pos * _bytesPerElement; // save pos to avoid recomputation
|
||||
return HandlesReadAccess | HandlesWriteAccess; // Read/Write access
|
||||
}
|
||||
|
||||
return TypedArray::queryProperty(object, name, flags, id);
|
||||
}
|
||||
|
||||
QScriptValue Int8ArrayClass::property(const QScriptValue &object,
|
||||
const QScriptString &name, uint id) {
|
||||
QByteArray* arrayBuffer = qscriptvalue_cast<QByteArray*>(object.data().property(_bufferName).data());
|
||||
bool ok = false;
|
||||
name.toArrayIndex(&ok);
|
||||
|
||||
if (ok && arrayBuffer) {
|
||||
QDataStream stream(*arrayBuffer);
|
||||
stream.skipRawData(id);
|
||||
|
||||
qint8 result;
|
||||
stream >> result;
|
||||
return result;
|
||||
}
|
||||
|
||||
return TypedArray::property(object, name, id);
|
||||
}
|
||||
|
||||
void Int8ArrayClass::setProperty(QScriptValue &object,
|
||||
const QScriptString &name,
|
||||
uint id, const QScriptValue &value) {
|
||||
qDebug() << "ID: " << id << ", Value: " << value.toInt32();
|
||||
QByteArray *ba = qscriptvalue_cast<QByteArray*>(object.data().property(_bufferName).data());
|
||||
if (ba && value.isNumber()) {
|
||||
QDataStream stream(ba, QIODevice::ReadWrite);
|
||||
stream.skipRawData(id);
|
||||
|
||||
qDebug() << "Adding: " << (qint8)value.toInt32();
|
||||
stream << (qint8)value.toInt32();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
104
libraries/script-engine/src/TypedArrays.h
Normal file
104
libraries/script-engine/src/TypedArrays.h
Normal file
|
@ -0,0 +1,104 @@
|
|||
//
|
||||
// TypedArrays.h
|
||||
//
|
||||
//
|
||||
// Created by Clement on 7/9/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_TypedArrays_h
|
||||
#define hifi_TypedArrays_h
|
||||
|
||||
#include "ArrayBufferViewClass.h"
|
||||
|
||||
static const QString BYTES_PER_ELEMENT_PROPERTY_NAME = "BYTES_PER_ELEMENT";
|
||||
static const QString LENGTH_PROPERTY_NAME = "length";
|
||||
|
||||
static const QString INT_8_ARRAY_CLASS_NAME = "Int8Array";
|
||||
|
||||
class TypedArray : public ArrayBufferViewClass {
|
||||
Q_OBJECT
|
||||
public:
|
||||
TypedArray(ScriptEngine* scriptEngine, QString name);
|
||||
virtual QScriptValue newInstance(quint32 length) = 0;
|
||||
virtual QScriptValue newInstance(QScriptValue array, bool isTypedArray) = 0;
|
||||
virtual QScriptValue newInstance(QScriptValue buffer, quint32 byteOffset, quint32 length) = 0;
|
||||
|
||||
virtual QueryFlags queryProperty(const QScriptValue& object,
|
||||
const QScriptString& name,
|
||||
QueryFlags flags, uint* id);
|
||||
virtual QScriptValue property(const QScriptValue &object,
|
||||
const QScriptString &name, uint id);
|
||||
virtual QScriptValue::PropertyFlags propertyFlags(const QScriptValue& object,
|
||||
const QScriptString& name, uint id);
|
||||
|
||||
QString name() const;
|
||||
QScriptValue prototype() const;
|
||||
|
||||
protected:
|
||||
static QScriptValue construct(QScriptContext* context, QScriptEngine* engine);
|
||||
|
||||
QScriptValue _proto;
|
||||
QScriptValue _ctor;
|
||||
|
||||
QScriptString _name;
|
||||
QScriptString _bytesPerElementName;
|
||||
QScriptString _lengthName;
|
||||
|
||||
quint32 _bytesPerElement;
|
||||
};
|
||||
|
||||
class Int8ArrayClass : public TypedArray {
|
||||
Q_OBJECT
|
||||
public:
|
||||
Int8ArrayClass(ScriptEngine* scriptEngine);
|
||||
QScriptValue newInstance(quint32 length);
|
||||
QScriptValue newInstance(QScriptValue array, bool isTypedArray);
|
||||
QScriptValue newInstance(QScriptValue buffer, quint32 byteOffset, quint32 length);
|
||||
|
||||
QueryFlags queryProperty(const QScriptValue& object,
|
||||
const QScriptString& name,
|
||||
QueryFlags flags, uint* id);
|
||||
QScriptValue property(const QScriptValue &object,
|
||||
const QScriptString &name, uint id);
|
||||
void setProperty(QScriptValue &object,
|
||||
const QScriptString &name,
|
||||
uint id, const QScriptValue &value);
|
||||
};
|
||||
|
||||
class Uint8ArrayClass : public TypedArray {
|
||||
|
||||
};
|
||||
|
||||
class Uint8ClampedArrayClass : public TypedArray {
|
||||
|
||||
};
|
||||
|
||||
class Int16ArrayClass : public TypedArray {
|
||||
|
||||
};
|
||||
|
||||
class Uint16ArrayClass : public TypedArray {
|
||||
|
||||
};
|
||||
|
||||
class Int32ArrayClass : public TypedArray {
|
||||
|
||||
};
|
||||
|
||||
class Uint32ArrayClass : public TypedArray {
|
||||
|
||||
};
|
||||
|
||||
class Float32ArrayClass : public TypedArray {
|
||||
|
||||
};
|
||||
|
||||
class Float64ArrayClass : public TypedArray {
|
||||
|
||||
};
|
||||
|
||||
#endif // hifi_TypedArrays_h
|
Loading…
Reference in a new issue