5#ifndef QV4REFERENCEOBJECT_P_H
6#define QV4REFERENCEOBJECT_P_H
19#include <private/qv4object_p.h>
20#include <private/qv4stackframe_p.h>
21#include <private/qqmlnotifier_p.h>
22#include <private/qv4qobjectwrapper_p.h>
29struct ReferenceObject;
39#define ReferenceObjectMembers(class, Member)
40 Member(class, Pointer, Object *, m_object)
42DECLARE_HEAP_OBJECT(ReferenceObject, Object) {
43 DECLARE_MARKOBJECTS(ReferenceObject);
47 CanWriteBack = 1 << 0,
49 EnforcesLocation = 1 << 2,
52 Q_DECLARE_FLAGS(Flags, Flag);
54 void init(Object *object,
int property, Flags flags)
56 auto connectToNotifySignal = [
this](QObject* obj,
int property, QQmlEngine* engine) {
60 Q_ASSERT(!referenceEndpoint);
61 Q_ASSERT(!bindableNotifier);
63 referenceEndpoint =
new ReferenceObjectEndpoint(
this);
64 referenceEndpoint->connect(
88 QMetaObjectPrivate::signalIndex(obj->metaObject()->property(property).notifySignal()),
106 new(onDelete) QMetaObject::Connection(QObject::connect(obj, &QObject::destroyed, [
this](){ setDirty(
true); }));
109 auto connectToBindable = [
this](QObject* obj,
int property, QQmlEngine* engine) {
113 Q_ASSERT(!referenceEndpoint);
114 Q_ASSERT(!bindableNotifier);
116 bindableNotifier =
new QPropertyNotifier(obj->metaObject()->property(property).bindable(obj).addNotifier([
this](){ setDirty(
true); }));
117 new(onDelete) QMetaObject::Connection(QObject::connect(obj, &QObject::destroyed, [
this](){ setDirty(
true); }));
121 m_property = property;
125 object->internalClass->vtable->type != Managed::Type_V4QObjectWrapper &&
126 object->internalClass->vtable->type != Managed::Type_QMLTypeWrapper)
128 if (!(object->internalClass->vtable->type == Managed::Type_V4ReferenceObject) &&
129 !(object->internalClass->vtable->type == Managed::Type_V4Sequence) &&
130 !(object->internalClass->vtable->type == Managed::Type_DateObject) &&
131 !(object->internalClass->vtable->type == Managed::Type_QMLValueTypeWrapper))
136 property =
static_cast<QV4::Heap::ReferenceObject*>(object)->property();
137 object =
static_cast<QV4::Heap::ReferenceObject*>(object)->object();
140 if (object && object->internalClass->vtable->type == Managed::Type_V4QObjectWrapper)
142 auto wrapper =
static_cast<QV4::Heap::QObjectWrapper*>(object);
143 QObject* obj = wrapper->object();
145 if (obj->metaObject()->property(property).isBindable() && internalClass->engine->qmlEngine())
146 connectToBindable(obj, property, internalClass->engine->qmlEngine());
147 else if (obj->metaObject()->property(property).hasNotifySignal() && internalClass->engine->qmlEngine())
148 connectToNotifySignal(obj, property, internalClass->engine->qmlEngine());
151 if (object && object->internalClass->vtable->type == Managed::Type_QMLTypeWrapper) {
152 auto wrapper =
static_cast<QV4::Heap::QQmlTypeWrapper*>(object);
154 Scope scope(internalClass->engine);
155 Scoped<QV4::QQmlTypeWrapper> scopedWrapper(scope, wrapper);
156 QObject* obj = scopedWrapper->object();
158 if (obj->metaObject()->property(property).isBindable() && internalClass->engine->qmlEngine())
159 connectToBindable(obj, property, internalClass->engine->qmlEngine());
160 else if (obj->metaObject()->property(property).hasNotifySignal() && internalClass->engine->qmlEngine())
161 connectToNotifySignal(obj, property, internalClass->engine->qmlEngine());
173 Flags flags()
const {
return Flags(m_flags); }
175 Object *object()
const {
return m_object.get(); }
176 void setObject(Object *object) { m_object.set(internalClass->engine, object); }
178 int property()
const {
return m_property; }
180 bool canWriteBack()
const {
return hasFlag(CanWriteBack); }
181 bool isVariant()
const {
return hasFlag(IsVariant); }
182 bool enforcesLocation()
const {
return hasFlag(EnforcesLocation); }
184 void setLocation(
const Function *function, quint16 statement)
186 m_function = function;
187 m_statementIndex = statement;
190 const Function *function()
const {
return m_function; }
191 quint16 statementIndex()
const {
return m_statementIndex; }
193 bool isAttachedToProperty()
const
195 if (enforcesLocation()) {
196 if (CppStackFrame *frame = internalClass->engine->currentStackFrame) {
197 if (frame->v4Function != function() || frame->statementNumber() != statementIndex())
207 bool isReference()
const {
return m_object; }
209 bool isDirty()
const {
return hasFlag(IsDirty); }
210 void setDirty(
bool dirty) { setFlag(IsDirty, dirty); }
212 return (referenceEndpoint && referenceEndpoint->isConnected()) || bindableNotifier;
218 if (referenceEndpoint || bindableNotifier) {
219 QObject::disconnect(*
reinterpret_cast<QMetaObject::Connection*>(&onDelete));
220 std::destroy_at(
reinterpret_cast<QMetaObject::Connection*>(&onDelete));
223 if (referenceEndpoint)
224 delete referenceEndpoint;
226 if (bindableNotifier)
227 delete bindableNotifier;
232 bool hasFlag(Flag flag)
const
234 return m_flags & quint8(flag);
237 void setFlag(Flag flag,
bool set)
239 m_flags = set ? (m_flags | quint8(flag)) : (m_flags & ~quint8(flag));
242 const Function *m_function;
244 quint16 m_statementIndex;
247 QPropertyNotifier* bindableNotifier;
253 alignas(
alignof(QMetaObject::Connection))
254 std::byte onDelete[
sizeof(QMetaObject::Connection)];
269 static constexpr const int AllProperties = -1;
271 template<
typename HeapObject>
280 QV4::
Scope scope(ref->internalClass->engine);
283 bool wasRead =
false;
284 if (ref->isVariant()) {
286 void *a[] = { &variant };
287 wasRead = object->metacall(QMetaObject::ReadProperty, ref->property(), a)
288 && ref->setVariant(variant);
290 void *a[] = { ref->storagePointer() };
291 wasRead = object->metacall(QMetaObject::ReadProperty, ref->property(), a);
294 ref->setDirty(!ref->isConnected() || !wasRead);
298 template<
typename HeapObject>
299 static bool writeBack(HeapObject *ref,
int internalIndex = AllProperties)
301 if (!ref->object() || !ref->canWriteBack())
304 QV4::
Scope scope(ref->internalClass->engine);
307 int flags = QQmlPropertyData::HasInternalIndex;
309 if (ref->isVariant()) {
310 QVariant variant = ref->toVariant();
311 void *a[] = { &variant,
nullptr, &status, &flags, &internalIndex };
312 return object->metacall(QMetaObject::WriteProperty, ref->property(), a);
315 void *a[] = { ref->storagePointer(),
nullptr, &status, &flags, &internalIndex };
316 return object->metacall(QMetaObject::WriteProperty, ref->property(), a);
319 template<
typename HeapObject>
322 if (ref->object() && !ref->enforcesLocation() && !readReference(ref))
325 return ref->detached();
DECLARE_HEAP_OBJECT(DateObject, ReferenceObject)
bool ReferenceObject::readReference< Heap::DateObject >(Heap::DateObject *ref)
Scoped< Object > ScopedObject
bool ReferenceObject::writeBack< Heap::DateObject >(Heap::DateObject *ref, int internalIndex)
DEFINE_OBJECT_VTABLE(DateObject)
DEFINE_OBJECT_VTABLE(DateCtor)
static bool InLeapYear(double t)
static const double msPerDay
static double DayFromYear(double y)
static QString ToString(double t, double localTZA)
static double UTC(double t, double localTZA)
static const double msPerSecond
static double ParseString(const QString &s, double localTZA)
static QString ToUTCString(double t)
static int msFromTime(double t)
static double DaysInYear(double y)
static QString ToLocaleTimeString(double t)
static const double msPerHour
static double YearFromTime(double t)
static QDateTime ToDateTime(double t, QTimeZone zone)
static QString ToTimeString(double t)
static double getLocalTZA()
static double TimeWithinDay(double t)
static double TimeFromYear(double y)
static QString ToLocaleDateString(double t)
static double DayFromMonth(double month, double leap)
static double WeekDay(double t)
static const double SecondsPerMinute
static double MakeDate(double day, double time)
static double MakeDay(double year, double month, double day)
static double DaylightSavingTA(double t, double localTZA)
static QString ToLocaleString(double t)
static double DayWithinYear(double t)
static const double HoursPerDay
static void addZeroPrefixedInt(QString &str, int num, int nDigits)
static double MonthFromTime(double t)
static int HourFromTime(double t)
static int SecFromTime(double t)
static double Day(double t)
static double TimeClip(double t)
static int MinFromTime(double t)
static QString ToDateString(double t)
static double MakeTime(double hour, double min, double sec, double ms)
static const double msPerMinute
static double DateFromTime(double t)
static double LocalTime(double t, double localTZA)
static const double MinutesPerHour
static double currentTime()
#define Q_MANAGED_TYPE(type)
static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int)
static QDate dateTimeToDate(const QDateTime &dateTime)
static QString dateTimeToString(const QDateTime &dateTime, ExecutionEngine *engine)
static QDateTime timestampToDateTime(double timestamp, QTimeZone zone=QTimeZone::LocalTime)
static QDateTime stringToDateTime(const QString &string, ExecutionEngine *engine)
static double dateTimeToNumber(const QDateTime &dateTime)
static double componentsToTimestamp(double year, double month, double day, double hours, double mins, double secs, double ms, ExecutionEngine *v4)
static ReturnedValue method_setMilliseconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getMonth(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_UTC(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setMinutes(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getUTCMilliseconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toTimeString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getYear(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setUTCHours(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setUTCMonth(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setFullYear(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getUTCSeconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getTimezoneOffset(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toLocaleDateString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setMonth(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setUTCSeconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getDay(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toLocaleTimeString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getUTCDay(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getSeconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setTime(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toISOString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getUTCHours(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setUTCMilliseconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static void timezoneUpdated(ExecutionEngine *e)
static ReturnedValue method_setUTCFullYear(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toDateString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getUTCMinutes(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setHours(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getUTCMonth(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_symbolToPrimitive(const FunctionObject *f, const Value *thisObject, const Value *, int)
static ReturnedValue method_getTime(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_valueOf(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setDate(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_parse(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toJSON(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toUTCString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toLocaleString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getUTCDate(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setUTCDate(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getDate(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setYear(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getUTCFullYear(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getMinutes(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getFullYear(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_now(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getMilliseconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getHours(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setUTCMinutes(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static double getThisDate(ExecutionEngine *v4, const Value *thisObject)
static ReturnedValue method_setSeconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
bool withReadonlyStoragePointer(Function function)
QVariant toVariant() const
bool withWriteonlyStoragePointer(Function function, ExecutionEngine *engine)
void init(QTime time, ExecutionEngine *engine)
static constexpr quint64 MaxDateVal
void init(const QDateTime &dateTime)
Date & operator=(double value)
QDateTime toQDateTime() const
void init(QV4::ExecutionEngine *engine)
ReferenceObject * reference
ReferenceObjectEndpoint(ReferenceObject *reference)
An object that keeps track of the provenance of its owned value, allowing to reflect mutations on the...
static bool writeBack(HeapObject *ref, int internalIndex=AllProperties)
static bool readReference(HeapObject *ref)
static HeapObject * detached(HeapObject *ref)