mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-04 07:33:10 +02:00
More work on typed arrays
This commit is contained in:
parent
b4eb6a2eb7
commit
0e5af5afea
2 changed files with 351 additions and 79 deletions
|
@ -9,6 +9,8 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "ScriptEngine.h"
|
||||
|
||||
#include "TypedArrays.h"
|
||||
|
@ -22,12 +24,12 @@ TypedArray::TypedArray(ScriptEngine* scriptEngine, QString name) : ArrayBufferVi
|
|||
|
||||
QScriptValue global = engine()->globalObject();
|
||||
|
||||
// build prototype TODO
|
||||
// _proto = engine->newQObject(new DataViewPrototype(this),
|
||||
// QScriptEngine::QtOwnership,
|
||||
// QScriptEngine::SkipMethodsInEnumeration |
|
||||
// QScriptEngine::ExcludeSuperClassMethods |
|
||||
// QScriptEngine::ExcludeSuperClassProperties);
|
||||
// build prototype
|
||||
_proto = engine()->newQObject(new TypedArrayPrototype(this),
|
||||
QScriptEngine::QtOwnership,
|
||||
QScriptEngine::SkipMethodsInEnumeration |
|
||||
QScriptEngine::ExcludeSuperClassMethods |
|
||||
QScriptEngine::ExcludeSuperClassProperties);
|
||||
|
||||
_proto.setPrototype(global.property("Object").property("prototype"));
|
||||
|
||||
|
@ -37,16 +39,49 @@ TypedArray::TypedArray(ScriptEngine* scriptEngine, QString name) : ArrayBufferVi
|
|||
engine()->globalObject().setProperty(_name, _ctor);
|
||||
}
|
||||
|
||||
QScriptValue TypedArray::newInstance(quint32 length) {
|
||||
ArrayBufferClass* array = getScriptEngine()->getArrayBufferClass();
|
||||
QScriptValue buffer = array->newInstance(length * _bytesPerElement);
|
||||
return newInstance(buffer, 0, length);
|
||||
}
|
||||
|
||||
QScriptValue TypedArray::newInstance(QScriptValue array) {
|
||||
if (array.property("length").isValid()) {
|
||||
quint32 length = array.property("length").toInt32();
|
||||
QScriptValue newArray = newInstance(length);
|
||||
for (int i = 0; i < length; ++i) {
|
||||
QScriptValue value = array.property(QString::number(i));
|
||||
setProperty(newArray, engine()->toStringHandle(QString::number(i)),
|
||||
i * _bytesPerElement, (value.isNumber()) ? value : QScriptValue(0));
|
||||
}
|
||||
return newArray;
|
||||
}
|
||||
return QScriptValue();
|
||||
}
|
||||
|
||||
QScriptValue TypedArray::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);
|
||||
}
|
||||
|
||||
QScriptValue TypedArray::construct(QScriptContext *context, QScriptEngine *engine) {
|
||||
TypedArray* cls = qscriptvalue_cast<TypedArray*>(context->callee().data());
|
||||
if (!cls || context->argumentCount() < 1) {
|
||||
if (!cls) {
|
||||
return QScriptValue();
|
||||
}
|
||||
|
||||
if (context->argumentCount() == 0) {
|
||||
return cls->newInstance(0);
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -58,15 +93,22 @@ QScriptValue TypedArray::construct(QScriptContext *context, QScriptEngine *engin
|
|||
engine->evaluate("throw \"ArgumentError: 2nd arg is not a number\"");
|
||||
return QScriptValue();
|
||||
}
|
||||
if (byteOffsetArg.toInt32() < 0 || byteOffsetArg.toInt32() >= arrayBuffer->size()) {
|
||||
if (byteOffsetArg.toInt32() < 0 || byteOffsetArg.toInt32() > arrayBuffer->size()) {
|
||||
engine->evaluate("throw \"RangeError: byteOffset out of range\"");
|
||||
return QScriptValue();
|
||||
}
|
||||
if (byteOffsetArg.toInt32() % cls->_bytesPerElement != 0) {
|
||||
engine->evaluate("throw \"RangeError: byteOffset not a multiple of BYTES_PER_ELEMENT\"");
|
||||
}
|
||||
quint32 byteOffset = byteOffsetArg.toInt32();
|
||||
|
||||
if (context->argumentCount() == 2) {
|
||||
// case for end of ArrayBuffer
|
||||
newObject = cls->newInstance(bufferArg, byteOffset, arrayBuffer->size() - byteOffset);
|
||||
if ((arrayBuffer->size() - byteOffset) % cls->_bytesPerElement != 0) {
|
||||
engine->evaluate("throw \"RangeError: byteLength - byteOffset not a multiple of BYTES_PER_ELEMENT\"");
|
||||
}
|
||||
quint32 length = (arrayBuffer->size() - byteOffset) / cls->_bytesPerElement;
|
||||
newObject = cls->newInstance(bufferArg, byteOffset, length);
|
||||
} else {
|
||||
|
||||
QScriptValue lengthArg = (context->argumentCount() > 2) ? context->argument(2) : QScriptValue();
|
||||
|
@ -79,20 +121,17 @@ QScriptValue TypedArray::construct(QScriptContext *context, QScriptEngine *engin
|
|||
engine->evaluate("throw \"RangeError: byteLength out of range\"");
|
||||
return QScriptValue();
|
||||
}
|
||||
quint32 length = lengthArg.toInt32() * cls->_bytesPerElement;
|
||||
quint32 length = lengthArg.toInt32();
|
||||
|
||||
// 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
|
||||
newObject = cls->newInstance(bufferArg);
|
||||
}
|
||||
|
||||
if (context->isCalledAsConstructor()) {
|
||||
|
@ -148,79 +187,257 @@ QScriptValue TypedArray::prototype() const {
|
|||
return _proto;
|
||||
}
|
||||
|
||||
Int8ArrayClass::Int8ArrayClass(ScriptEngine* scriptEngine) : TypedArray(scriptEngine, INT_8_ARRAY_CLASS_NAME) {
|
||||
_bytesPerElement = sizeof(qint8);
|
||||
void TypedArray::setBytesPerElement(quint32 bytesPerElement) {
|
||||
_bytesPerElement = bytesPerElement;
|
||||
_ctor.setProperty(_bytesPerElementName, _bytesPerElement);
|
||||
}
|
||||
|
||||
QScriptValue Int8ArrayClass::newInstance(quint32 length) {
|
||||
ArrayBufferClass* array = getScriptEngine()->getArrayBufferClass();
|
||||
QScriptValue buffer = array->newInstance(length * _bytesPerElement);
|
||||
return newInstance(buffer, 0, length);
|
||||
TypedArrayPrototype::TypedArrayPrototype(QObject* parent) : QObject(parent) {
|
||||
}
|
||||
|
||||
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;
|
||||
QByteArray* TypedArrayPrototype::thisArrayBuffer() const {
|
||||
QScriptValue bufferObject = thisObject().data().property(BUFFER_PROPERTY_NAME);
|
||||
return qscriptvalue_cast<QByteArray*>(bufferObject.data());
|
||||
}
|
||||
|
||||
void TypedArrayPrototype::set(QScriptValue array, quint32 offset) {
|
||||
TypedArray* typedArray = static_cast<TypedArray*>(parent());
|
||||
if (array.isArray()) {
|
||||
quint32 length = array.property("length").toInt32();
|
||||
if (offset + length > thisObject().data().property(typedArray->_lengthName).toInt32()) {
|
||||
// TODO throw an error maybe?
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
return newInstance(arrayBufferClass->newInstance(newArray),
|
||||
array.data().property(_byteOffsetName).toInt32(),
|
||||
array.data().property(_lengthName).toInt32());
|
||||
for (int i = 0; i < length; ++i) {
|
||||
thisObject().setProperty(QString::number(offset + i), array.property(QString::number(i)));
|
||||
}
|
||||
}
|
||||
// TODO handle typed arrays
|
||||
}
|
||||
|
||||
QScriptValue TypedArrayPrototype::subarray(qint32 begin) {
|
||||
TypedArray* typedArray = static_cast<TypedArray*>(parent());
|
||||
QScriptValue arrayBuffer = thisObject().data().property(typedArray->_bufferName);
|
||||
qint32 byteOffset = thisObject().data().property(typedArray->_byteOffsetName).toInt32();
|
||||
qint32 length = thisObject().data().property(typedArray->_lengthName).toInt32();
|
||||
qint32 bytesPerElement = typedArray->_bytesPerElement;
|
||||
|
||||
// if indices < 0 then they start from the end of the array
|
||||
begin = (begin < 0) ? length + begin : begin;
|
||||
|
||||
// here we clamp the indices to fit the array
|
||||
begin = glm::clamp(begin, 0, (length - 1));
|
||||
|
||||
byteOffset += begin * bytesPerElement;
|
||||
return typedArray->newInstance(arrayBuffer, byteOffset, length - begin);
|
||||
}
|
||||
|
||||
QScriptValue TypedArrayPrototype::subarray(qint32 begin, qint32 end) {
|
||||
TypedArray* typedArray = static_cast<TypedArray*>(parent());
|
||||
QScriptValue arrayBuffer = thisObject().data().property(typedArray->_bufferName);
|
||||
qint32 byteOffset = thisObject().data().property(typedArray->_byteOffsetName).toInt32();
|
||||
qint32 length = thisObject().data().property(typedArray->_lengthName).toInt32();
|
||||
qint32 bytesPerElement = typedArray->_bytesPerElement;
|
||||
|
||||
// if indices < 0 then they start from the end of the array
|
||||
begin = (begin < 0) ? length + begin : begin;
|
||||
end = (end < 0) ? length + end : end;
|
||||
|
||||
// here we clamp the indices to fit the array
|
||||
begin = glm::clamp(begin, 0, (length - 1));
|
||||
end = glm::clamp(end, 0, (length - 1));
|
||||
|
||||
byteOffset += begin * bytesPerElement;
|
||||
length = (end - begin > 0) ? end - begin : 0;
|
||||
return typedArray->newInstance(arrayBuffer, byteOffset, length);
|
||||
}
|
||||
|
||||
QScriptValue TypedArrayPrototype::get(quint32 index) {
|
||||
TypedArray* typedArray = static_cast<TypedArray*>(parent());
|
||||
QScriptString name = engine()->toStringHandle(QString::number(index));
|
||||
uint id;
|
||||
QScriptClass::QueryFlags flags = typedArray->queryProperty(thisObject(),
|
||||
name,
|
||||
QScriptClass::HandlesReadAccess, &id);
|
||||
if (QScriptClass::HandlesReadAccess & flags) {
|
||||
return typedArray->property(thisObject(), name, id);
|
||||
}
|
||||
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);
|
||||
void TypedArrayPrototype::set(quint32 index, QScriptValue& value) {
|
||||
TypedArray* typedArray = static_cast<TypedArray*>(parent());
|
||||
QScriptValue object = thisObject();
|
||||
QScriptString name = engine()->toStringHandle(QString::number(index));
|
||||
uint id;
|
||||
QScriptClass::QueryFlags flags = typedArray->queryProperty(object,
|
||||
name,
|
||||
QScriptClass::HandlesWriteAccess, &id);
|
||||
if (QScriptClass::HandlesWriteAccess & flags) {
|
||||
typedArray->setProperty(object, name, id, value);
|
||||
}
|
||||
}
|
||||
|
||||
QScriptValue Int8ArrayClass::property(const QScriptValue &object,
|
||||
const QScriptString &name, uint id) {
|
||||
QByteArray* arrayBuffer = qscriptvalue_cast<QByteArray*>(object.data().property(_bufferName).data());
|
||||
template<class T>
|
||||
QScriptValue propertyHelper(const QByteArray* arrayBuffer, const QScriptString &name, uint id) {
|
||||
bool ok = false;
|
||||
name.toArrayIndex(&ok);
|
||||
|
||||
|
||||
if (ok && arrayBuffer) {
|
||||
QDataStream stream(*arrayBuffer);
|
||||
stream.skipRawData(id);
|
||||
|
||||
qint8 result;
|
||||
T result;
|
||||
stream >> result;
|
||||
return result;
|
||||
}
|
||||
|
||||
return TypedArray::property(object, name, id);
|
||||
return QScriptValue();
|
||||
}
|
||||
|
||||
void Int8ArrayClass::setProperty(QScriptValue &object,
|
||||
const QScriptString &name,
|
||||
uint id, const QScriptValue &value) {
|
||||
QByteArray *ba = qscriptvalue_cast<QByteArray*>(object.data().property(_bufferName).data());
|
||||
if (ba && value.isNumber()) {
|
||||
QDataStream stream(ba, QIODevice::ReadWrite);
|
||||
template<class T>
|
||||
void setPropertyHelper(QByteArray* arrayBuffer, const QScriptString &name, uint id, const QScriptValue &value) {
|
||||
if (arrayBuffer && value.isNumber()) {
|
||||
QDataStream stream(arrayBuffer, QIODevice::ReadWrite);
|
||||
stream.skipRawData(id);
|
||||
|
||||
stream << (qint8)value.toInt32();
|
||||
stream << (T)value.toNumber();
|
||||
}
|
||||
}
|
||||
|
||||
Int8ArrayClass::Int8ArrayClass(ScriptEngine* scriptEngine) : TypedArray(scriptEngine, INT_8_ARRAY_CLASS_NAME) {
|
||||
setBytesPerElement(sizeof(qint8));
|
||||
}
|
||||
|
||||
QScriptValue Int8ArrayClass::property(const QScriptValue &object, const QScriptString &name, uint id) {
|
||||
QByteArray* arrayBuffer = qscriptvalue_cast<QByteArray*>(object.data().property(_bufferName).data());
|
||||
QScriptValue result = propertyHelper<qint8>(arrayBuffer, name, id);
|
||||
return (result.isValid()) ? result : TypedArray::property(object, name, id);
|
||||
}
|
||||
|
||||
void Int8ArrayClass::setProperty(QScriptValue &object, const QScriptString &name,
|
||||
uint id, const QScriptValue &value) {
|
||||
QByteArray *ba = qscriptvalue_cast<QByteArray*>(object.data().property(_bufferName).data());
|
||||
setPropertyHelper<qint8>(ba, name, id, value);
|
||||
}
|
||||
|
||||
Uint8ArrayClass::Uint8ArrayClass(ScriptEngine* scriptEngine) : TypedArray(scriptEngine, UINT_8_ARRAY_CLASS_NAME) {
|
||||
setBytesPerElement(sizeof(quint8));
|
||||
}
|
||||
|
||||
QScriptValue Uint8ArrayClass::property(const QScriptValue &object, const QScriptString &name, uint id) {
|
||||
|
||||
QByteArray* arrayBuffer = qscriptvalue_cast<QByteArray*>(object.data().property(_bufferName).data());
|
||||
QScriptValue result = propertyHelper<quint8>(arrayBuffer, name, id);
|
||||
return (result.isValid()) ? result : TypedArray::property(object, name, id);
|
||||
}
|
||||
|
||||
void Uint8ArrayClass::setProperty(QScriptValue &object, const QScriptString &name,
|
||||
uint id, const QScriptValue &value) {
|
||||
QByteArray *ba = qscriptvalue_cast<QByteArray*>(object.data().property(_bufferName).data());
|
||||
setPropertyHelper<quint8>(ba, name, id, value);
|
||||
}
|
||||
|
||||
Int16ArrayClass::Int16ArrayClass(ScriptEngine* scriptEngine) : TypedArray(scriptEngine, INT_16_ARRAY_CLASS_NAME) {
|
||||
setBytesPerElement(sizeof(qint16));
|
||||
}
|
||||
|
||||
QScriptValue Int16ArrayClass::property(const QScriptValue &object, const QScriptString &name, uint id) {
|
||||
|
||||
QByteArray* arrayBuffer = qscriptvalue_cast<QByteArray*>(object.data().property(_bufferName).data());
|
||||
QScriptValue result = propertyHelper<qint16>(arrayBuffer, name, id);
|
||||
return (result.isValid()) ? result : TypedArray::property(object, name, id);
|
||||
}
|
||||
|
||||
void Int16ArrayClass::setProperty(QScriptValue &object, const QScriptString &name,
|
||||
uint id, const QScriptValue &value) {
|
||||
QByteArray *ba = qscriptvalue_cast<QByteArray*>(object.data().property(_bufferName).data());
|
||||
setPropertyHelper<qint16>(ba, name, id, value);
|
||||
}
|
||||
|
||||
Uint16ArrayClass::Uint16ArrayClass(ScriptEngine* scriptEngine) : TypedArray(scriptEngine, UINT_16_ARRAY_CLASS_NAME) {
|
||||
setBytesPerElement(sizeof(quint16));
|
||||
}
|
||||
|
||||
QScriptValue Uint16ArrayClass::property(const QScriptValue &object, const QScriptString &name, uint id) {
|
||||
|
||||
QByteArray* arrayBuffer = qscriptvalue_cast<QByteArray*>(object.data().property(_bufferName).data());
|
||||
QScriptValue result = propertyHelper<quint16>(arrayBuffer, name, id);
|
||||
return (result.isValid()) ? result : TypedArray::property(object, name, id);
|
||||
}
|
||||
|
||||
void Uint16ArrayClass::setProperty(QScriptValue &object, const QScriptString &name,
|
||||
uint id, const QScriptValue &value) {
|
||||
QByteArray *ba = qscriptvalue_cast<QByteArray*>(object.data().property(_bufferName).data());
|
||||
setPropertyHelper<quint16>(ba, name, id, value);
|
||||
}
|
||||
|
||||
Int32ArrayClass::Int32ArrayClass(ScriptEngine* scriptEngine) : TypedArray(scriptEngine, INT_32_ARRAY_CLASS_NAME) {
|
||||
setBytesPerElement(sizeof(qint32));
|
||||
}
|
||||
|
||||
QScriptValue Int32ArrayClass::property(const QScriptValue &object, const QScriptString &name, uint id) {
|
||||
|
||||
QByteArray* arrayBuffer = qscriptvalue_cast<QByteArray*>(object.data().property(_bufferName).data());
|
||||
QScriptValue result = propertyHelper<qint32>(arrayBuffer, name, id);
|
||||
return (result.isValid()) ? result : TypedArray::property(object, name, id);
|
||||
}
|
||||
|
||||
void Int32ArrayClass::setProperty(QScriptValue &object, const QScriptString &name,
|
||||
uint id, const QScriptValue &value) {
|
||||
QByteArray *ba = qscriptvalue_cast<QByteArray*>(object.data().property(_bufferName).data());
|
||||
setPropertyHelper<qint32>(ba, name, id, value);
|
||||
}
|
||||
|
||||
Uint32ArrayClass::Uint32ArrayClass(ScriptEngine* scriptEngine) : TypedArray(scriptEngine, UINT_32_ARRAY_CLASS_NAME) {
|
||||
setBytesPerElement(sizeof(quint32));
|
||||
}
|
||||
|
||||
QScriptValue Uint32ArrayClass::property(const QScriptValue &object, const QScriptString &name, uint id) {
|
||||
|
||||
QByteArray* arrayBuffer = qscriptvalue_cast<QByteArray*>(object.data().property(_bufferName).data());
|
||||
QScriptValue result = propertyHelper<quint32>(arrayBuffer, name, id);
|
||||
return (result.isValid()) ? result : TypedArray::property(object, name, id);
|
||||
}
|
||||
|
||||
void Uint32ArrayClass::setProperty(QScriptValue &object, const QScriptString &name,
|
||||
uint id, const QScriptValue &value) {
|
||||
QByteArray *ba = qscriptvalue_cast<QByteArray*>(object.data().property(_bufferName).data());
|
||||
setPropertyHelper<quint32>(ba, name, id, value);
|
||||
}
|
||||
|
||||
Float32ArrayClass::Float32ArrayClass(ScriptEngine* scriptEngine) : TypedArray(scriptEngine, FLOAT_32_ARRAY_CLASS_NAME) {
|
||||
setBytesPerElement(sizeof(float));
|
||||
}
|
||||
|
||||
QScriptValue Float32ArrayClass::property(const QScriptValue &object, const QScriptString &name, uint id) {
|
||||
|
||||
QByteArray* arrayBuffer = qscriptvalue_cast<QByteArray*>(object.data().property(_bufferName).data());
|
||||
QScriptValue result = propertyHelper<float>(arrayBuffer, name, id);
|
||||
return (result.isValid()) ? result : TypedArray::property(object, name, id);
|
||||
}
|
||||
|
||||
void Float32ArrayClass::setProperty(QScriptValue &object, const QScriptString &name,
|
||||
uint id, const QScriptValue &value) {
|
||||
QByteArray *ba = qscriptvalue_cast<QByteArray*>(object.data().property(_bufferName).data());
|
||||
setPropertyHelper<float>(ba, name, id, value);
|
||||
}
|
||||
|
||||
Float64ArrayClass::Float64ArrayClass(ScriptEngine* scriptEngine) : TypedArray(scriptEngine, FLOAT_64_ARRAY_CLASS_NAME) {
|
||||
setBytesPerElement(sizeof(double));
|
||||
}
|
||||
|
||||
QScriptValue Float64ArrayClass::property(const QScriptValue &object, const QScriptString &name, uint id) {
|
||||
|
||||
QByteArray* arrayBuffer = qscriptvalue_cast<QByteArray*>(object.data().property(_bufferName).data());
|
||||
QScriptValue result = propertyHelper<double>(arrayBuffer, name, id);
|
||||
return (result.isValid()) ? result : TypedArray::property(object, name, id);
|
||||
}
|
||||
|
||||
void Float64ArrayClass::setProperty(QScriptValue &object, const QScriptString &name,
|
||||
uint id, const QScriptValue &value) {
|
||||
QByteArray *ba = qscriptvalue_cast<QByteArray*>(object.data().property(_bufferName).data());
|
||||
setPropertyHelper<double>(ba, name, id, value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -18,20 +18,28 @@ 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";
|
||||
static const QString UINT_8_ARRAY_CLASS_NAME = "Uint8Array";
|
||||
static const QString INT_16_ARRAY_CLASS_NAME = "Int16Array";
|
||||
static const QString UINT_16_ARRAY_CLASS_NAME = "Uint16Array";
|
||||
static const QString INT_32_ARRAY_CLASS_NAME = "Int32Array";
|
||||
static const QString UINT_32_ARRAY_CLASS_NAME = "Uint32Array";
|
||||
static const QString FLOAT_32_ARRAY_CLASS_NAME = "Float32Array";
|
||||
static const QString FLOAT_64_ARRAY_CLASS_NAME = "Float64Array";
|
||||
|
||||
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 QScriptValue newInstance(quint32 length);
|
||||
virtual QScriptValue newInstance(QScriptValue array);
|
||||
virtual QScriptValue newInstance(QScriptValue buffer, quint32 byteOffset, quint32 length);
|
||||
|
||||
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 property(const QScriptValue& object,
|
||||
const QScriptString& name, uint id);
|
||||
virtual void setProperty(QScriptValue& object, const QScriptString& name, uint id, const QScriptValue& value) = 0;
|
||||
virtual QScriptValue::PropertyFlags propertyFlags(const QScriptValue& object,
|
||||
const QScriptString& name, uint id);
|
||||
|
||||
|
@ -41,6 +49,8 @@ public:
|
|||
protected:
|
||||
static QScriptValue construct(QScriptContext* context, QScriptEngine* engine);
|
||||
|
||||
void setBytesPerElement(quint32 bytesPerElement);
|
||||
|
||||
QScriptValue _proto;
|
||||
QScriptValue _ctor;
|
||||
|
||||
|
@ -49,53 +59,98 @@ protected:
|
|||
QScriptString _lengthName;
|
||||
|
||||
quint32 _bytesPerElement;
|
||||
|
||||
friend class TypedArrayPrototype;
|
||||
};
|
||||
|
||||
class TypedArrayPrototype : public QObject, public QScriptable {
|
||||
Q_OBJECT
|
||||
public:
|
||||
TypedArrayPrototype(QObject* parent = NULL);
|
||||
|
||||
public slots:
|
||||
void set(QScriptValue array, quint32 offset = 0);
|
||||
QScriptValue subarray(qint32 begin);
|
||||
QScriptValue subarray(qint32 begin, qint32 end);
|
||||
|
||||
QScriptValue get(quint32 index);
|
||||
void set(quint32 index, QScriptValue& value);
|
||||
private:
|
||||
QByteArray* thisArrayBuffer() const;
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
QScriptValue property(const QScriptValue &object,
|
||||
const QScriptString &name, uint id);
|
||||
void setProperty(QScriptValue &object,
|
||||
const QScriptString &name,
|
||||
uint id, const QScriptValue &value);
|
||||
|
||||
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 {
|
||||
Q_OBJECT
|
||||
public:
|
||||
Uint8ArrayClass(ScriptEngine* scriptEngine);
|
||||
|
||||
QScriptValue property(const QScriptValue &object, const QScriptString &name, uint id);
|
||||
void setProperty(QScriptValue &object, const QScriptString &name, uint id, const QScriptValue &value);
|
||||
};
|
||||
|
||||
class Uint8ClampedArrayClass : public TypedArray {
|
||||
|
||||
// TODO
|
||||
};
|
||||
|
||||
class Int16ArrayClass : public TypedArray {
|
||||
Q_OBJECT
|
||||
public:
|
||||
Int16ArrayClass(ScriptEngine* scriptEngine);
|
||||
|
||||
QScriptValue property(const QScriptValue &object, const QScriptString &name, uint id);
|
||||
void setProperty(QScriptValue &object, const QScriptString &name, uint id, const QScriptValue &value);
|
||||
};
|
||||
|
||||
class Uint16ArrayClass : public TypedArray {
|
||||
Q_OBJECT
|
||||
public:
|
||||
Uint16ArrayClass(ScriptEngine* scriptEngine);
|
||||
|
||||
};
|
||||
QScriptValue property(const QScriptValue &object, const QScriptString &name, uint id);
|
||||
void setProperty(QScriptValue &object, const QScriptString &name, uint id, const QScriptValue &value);};
|
||||
|
||||
class Int32ArrayClass : public TypedArray {
|
||||
Q_OBJECT
|
||||
public:
|
||||
Int32ArrayClass(ScriptEngine* scriptEngine);
|
||||
|
||||
QScriptValue property(const QScriptValue &object, const QScriptString &name, uint id);
|
||||
void setProperty(QScriptValue &object, const QScriptString &name, uint id, const QScriptValue &value);
|
||||
};
|
||||
|
||||
class Uint32ArrayClass : public TypedArray {
|
||||
Q_OBJECT
|
||||
public:
|
||||
Uint32ArrayClass(ScriptEngine* scriptEngine);
|
||||
|
||||
QScriptValue property(const QScriptValue &object, const QScriptString &name, uint id);
|
||||
void setProperty(QScriptValue &object, const QScriptString &name, uint id, const QScriptValue &value);
|
||||
};
|
||||
|
||||
class Float32ArrayClass : public TypedArray {
|
||||
Q_OBJECT
|
||||
public:
|
||||
Float32ArrayClass(ScriptEngine* scriptEngine);
|
||||
|
||||
};
|
||||
QScriptValue property(const QScriptValue &object, const QScriptString &name, uint id);
|
||||
void setProperty(QScriptValue &object, const QScriptString &name, uint id, const QScriptValue &value);};
|
||||
|
||||
class Float64ArrayClass : public TypedArray {
|
||||
Q_OBJECT
|
||||
public:
|
||||
Float64ArrayClass(ScriptEngine* scriptEngine);
|
||||
|
||||
QScriptValue property(const QScriptValue &object, const QScriptString &name, uint id);
|
||||
void setProperty(QScriptValue &object, const QScriptString &name, uint id, const QScriptValue &value);
|
||||
};
|
||||
|
||||
#endif // hifi_TypedArrays_h
|
Loading…
Reference in a new issue