Showing the changes to libraries/script-engine/src/qtscript/ScriptEngineQtScript_cast.cpp (1 of 11 files). Show all
Unified · Split
| @@ -16,64 +16,16 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <QtCore/QJsonValue> |
| 17 | 17 | #include <QtScript/QScriptEngine> |
| 18 | 18 | |
| 19 | +#include "../ScriptEngineCast.h" | |
| 19 | 20 | #include "../ScriptValueIterator.h" |
| 20 | 21 | |
| 21 | 22 | #include "ScriptObjectQtProxy.h" |
| 22 | 23 | #include "ScriptValueQtWrapper.h" |
| 23 | 24 | |
| 24 | −template <int i> | |
| 25 | −class CustomTypeInstance { | |
| 26 | −public: | |
| 27 | − static ScriptEngine::MarshalFunction marshalFunc; | |
| 28 | − static ScriptEngine::DemarshalFunction demarshalFunc; | |
| 29 | − | |
| 30 | − static QScriptValue internalMarshalFunc(QScriptEngine* engine, const void* src) { | |
| 31 | − ScriptEngineQtScript* unwrappedEngine = static_cast<ScriptEngineQtScript*>(engine); | |
| 32 | − ScriptValue dest = marshalFunc(unwrappedEngine, src); | |
| 33 | − return ScriptValueQtWrapper::fullUnwrap(unwrappedEngine, dest); | |
| 34 | − } | |
| 35 | − | |
| 36 | − static void internalDemarshalFunc(const QScriptValue& src, void* dest) { | |
| 37 | − ScriptEngineQtScript* unwrappedEngine = static_cast<ScriptEngineQtScript*>(src.engine()); | |
| 38 | − ScriptValue wrappedSrc(new ScriptValueQtWrapper(unwrappedEngine, src)); | |
| 39 | − demarshalFunc(wrappedSrc, dest); | |
| 40 | − } | |
| 41 | −}; | |
| 42 | −template <int i> | |
| 43 | −ScriptEngine::MarshalFunction CustomTypeInstance<i>::marshalFunc; | |
| 44 | −template <int i> | |
| 45 | −ScriptEngine::DemarshalFunction CustomTypeInstance<i>::demarshalFunc; | |
| 46 | − | |
| 47 | −// I would *LOVE* it if there was a different way to do this, jeez! | |
| 48 | −// Qt requires two functions that have no parameters that give any context, | |
| 49 | −// one of the must return a QScriptValue (so we can't void* them into generics and stick them in the templates). | |
| 50 | −// This *has* to be done via templates but the whole point of this is to avoid leaking types into the rest of | |
| 51 | −// the system that would require anyone other than us to have a dependency on QtScript | |
| 52 | −#define CUSTOM_TYPE_ENTRY(idx) \ | |
| 53 | − case idx: \ | |
| 54 | − CustomTypeInstance<idx>::marshalFunc = marshalFunc; \ | |
| 55 | − CustomTypeInstance<idx>::demarshalFunc = demarshalFunc; \ | |
| 56 | − internalMarshalFunc = CustomTypeInstance<idx>::internalMarshalFunc; \ | |
| 57 | − internalDemarshalFunc = CustomTypeInstance<idx>::internalDemarshalFunc; \ | |
| 58 | − break; | |
| 59 | −#define CUSTOM_TYPE_ENTRY_10(idx) \ | |
| 60 | − CUSTOM_TYPE_ENTRY((idx * 10)); \ | |
| 61 | − CUSTOM_TYPE_ENTRY((idx * 10) + 1); \ | |
| 62 | − CUSTOM_TYPE_ENTRY((idx * 10) + 2); \ | |
| 63 | − CUSTOM_TYPE_ENTRY((idx * 10) + 3); \ | |
| 64 | − CUSTOM_TYPE_ENTRY((idx * 10) + 4); \ | |
| 65 | − CUSTOM_TYPE_ENTRY((idx * 10) + 5); \ | |
| 66 | − CUSTOM_TYPE_ENTRY((idx * 10) + 6); \ | |
| 67 | − CUSTOM_TYPE_ENTRY((idx * 10) + 7); \ | |
| 68 | − CUSTOM_TYPE_ENTRY((idx * 10) + 8); \ | |
| 69 | − CUSTOM_TYPE_ENTRY((idx * 10) + 9); | |
| 70 | − | |
| 71 | 25 | void ScriptEngineQtScript::setDefaultPrototype(int metaTypeId, const ScriptValue& prototype) { |
| 72 | 26 | ScriptValueQtWrapper* unwrappedPrototype = ScriptValueQtWrapper::unwrap(prototype); |
| 73 | 27 | if (unwrappedPrototype) { |
| 74 | 28 | const QScriptValue& scriptPrototype = unwrappedPrototype->toQtValue(); |
| 75 | − QScriptEngine::setDefaultPrototype(metaTypeId, scriptPrototype); | |
| 76 | − | |
| 77 | 29 | QMutexLocker guard(&_customTypeProtect); |
| 78 | 30 | _customPrototypes.insert(metaTypeId, scriptPrototype); |
| 79 | 31 | } |
| @@ -83,59 +35,12 @@ void ScriptEngineQtScript::registerCustomType(int type, · 3 unmodified lines | ||
| 83 | 35 | ScriptEngine::MarshalFunction marshalFunc, |
| 84 | 36 | ScriptEngine::DemarshalFunction demarshalFunc) |
| 85 | 37 | { |
| 86 | − QScriptEngine::MarshalFunction internalMarshalFunc; | |
| 87 | − QScriptEngine::DemarshalFunction internalDemarshalFunc; | |
| 88 | − | |
| 89 | − { | |
| 90 | − QMutexLocker guard(&_customTypeProtect); | |
| 91 | − | |
| 92 | − // storing it in a map for our own benefit | |
| 93 | − CustomMarshal& customType = _customTypes.insert(type, CustomMarshal()).value(); | |
| 94 | − customType.demarshalFunc = demarshalFunc; | |
| 95 | − customType.marshalFunc = marshalFunc; | |
| 96 | − | |
| 97 | − // creating a conversion for QtScript's benefit | |
| 98 | − if (_nextCustomType >= 300) { // have we ran out of translators? | |
| 99 | − Q_ASSERT(false); | |
| 100 | − return; | |
| 101 | − } | |
| 102 | − | |
| 103 | − switch (_nextCustomType++) { | |
| 104 | − CUSTOM_TYPE_ENTRY_10(0); | |
| 105 | − CUSTOM_TYPE_ENTRY_10(1); | |
| 106 | − CUSTOM_TYPE_ENTRY_10(2); | |
| 107 | − CUSTOM_TYPE_ENTRY_10(3); | |
| 108 | − CUSTOM_TYPE_ENTRY_10(4); | |
| 109 | − CUSTOM_TYPE_ENTRY_10(5); | |
| 110 | − CUSTOM_TYPE_ENTRY_10(6); | |
| 111 | − CUSTOM_TYPE_ENTRY_10(7); | |
| 112 | − CUSTOM_TYPE_ENTRY_10(8); | |
| 113 | − CUSTOM_TYPE_ENTRY_10(9); | |
| 114 | − CUSTOM_TYPE_ENTRY_10(10); | |
| 115 | − CUSTOM_TYPE_ENTRY_10(11); | |
| 116 | − CUSTOM_TYPE_ENTRY_10(12); | |
| 117 | − CUSTOM_TYPE_ENTRY_10(13); | |
| 118 | − CUSTOM_TYPE_ENTRY_10(14); | |
| 119 | − CUSTOM_TYPE_ENTRY_10(15); | |
| 120 | − CUSTOM_TYPE_ENTRY_10(16); | |
| 121 | − CUSTOM_TYPE_ENTRY_10(17); | |
| 122 | − CUSTOM_TYPE_ENTRY_10(18); | |
| 123 | − CUSTOM_TYPE_ENTRY_10(19); | |
| 124 | − CUSTOM_TYPE_ENTRY_10(20); | |
| 125 | − CUSTOM_TYPE_ENTRY_10(21); | |
| 126 | − CUSTOM_TYPE_ENTRY_10(22); | |
| 127 | − CUSTOM_TYPE_ENTRY_10(23); | |
| 128 | − CUSTOM_TYPE_ENTRY_10(24); | |
| 129 | − CUSTOM_TYPE_ENTRY_10(25); | |
| 130 | − CUSTOM_TYPE_ENTRY_10(26); | |
| 131 | − CUSTOM_TYPE_ENTRY_10(27); | |
| 132 | − CUSTOM_TYPE_ENTRY_10(28); | |
| 133 | − CUSTOM_TYPE_ENTRY_10(29); | |
| 134 | − CUSTOM_TYPE_ENTRY_10(30); | |
| 135 | − } | |
| 136 | − } | |
| 38 | + QMutexLocker guard(&_customTypeProtect); | |
| 137 | 39 | |
| 138 | − qScriptRegisterMetaType_helper(this, type, internalMarshalFunc, internalDemarshalFunc, QScriptValue()); | |
| 40 | + // storing it in a map for our own benefit | |
| 41 | + CustomMarshal& customType = _customTypes.insert(type, CustomMarshal()).value(); | |
| 42 | + customType.demarshalFunc = demarshalFunc; | |
| 43 | + customType.marshalFunc = marshalFunc; | |
| 139 | 44 | } |
| 140 | 45 | |
| 141 | 46 | Q_DECLARE_METATYPE(ScriptValue); |
| @@ -149,8 +54,7 @@ static void ScriptValueFromQScriptValue(const QScriptValue& src, ScriptValue& de · 7 unmodified lines | ||
| 149 | 54 | dest = ScriptValue(new ScriptValueQtWrapper(engine, src)); |
| 150 | 55 | } |
| 151 | 56 | |
| 152 | −static ScriptValue StringListToScriptValue(ScriptEngine* engine, const void* pSrc) { | |
| 153 | − const QStringList& src = *reinterpret_cast<const QStringList*>(pSrc); | |
| 57 | +static ScriptValue StringListToScriptValue(ScriptEngine* engine, const QStringList& src) { | |
| 154 | 58 | int len = src.length(); |
| 155 | 59 | ScriptValue dest = engine->newArray(len); |
| 156 | 60 | for (int idx = 0; idx < len; ++idx) { |
| @@ -159,9 +63,8 @@ static ScriptValue StringListToScriptValue(ScriptEngine* engine, const void* pSr · 2 unmodified lines | ||
| 159 | 63 | return dest; |
| 160 | 64 | } |
| 161 | 65 | |
| 162 | −static bool StringListFromScriptValue(const ScriptValue& src, void* pDest) { | |
| 66 | +static bool StringListFromScriptValue(const ScriptValue& src, QStringList& dest) { | |
| 163 | 67 | if(!src.isArray()) return false; |
| 164 | − QStringList& dest = *reinterpret_cast<QStringList*>(pDest); | |
| 165 | 68 | int len = src.property("length").toInteger(); |
| 166 | 69 | dest.clear(); |
| 167 | 70 | for (int idx = 0; idx < len; ++idx) { |
| @@ -170,8 +73,7 @@ static bool StringListFromScriptValue(const ScriptValue& src, void* pDest) { · 2 unmodified lines | ||
| 170 | 73 | return true; |
| 171 | 74 | } |
| 172 | 75 | |
| 173 | −static ScriptValue VariantListToScriptValue(ScriptEngine* engine, const void* pSrc) { | |
| 174 | − const QVariantList& src = *reinterpret_cast<const QVariantList*>(pSrc); | |
| 76 | +static ScriptValue VariantListToScriptValue(ScriptEngine* engine, const QVariantList& src) { | |
| 175 | 77 | int len = src.length(); |
| 176 | 78 | ScriptValue dest = engine->newArray(len); |
| 177 | 79 | for (int idx = 0; idx < len; ++idx) { |
| @@ -180,9 +82,8 @@ static ScriptValue VariantListToScriptValue(ScriptEngine* engine, const void* pS · 2 unmodified lines | ||
| 180 | 82 | return dest; |
| 181 | 83 | } |
| 182 | 84 | |
| 183 | −static bool VariantListFromScriptValue(const ScriptValue& src, void* pDest) { | |
| 85 | +static bool VariantListFromScriptValue(const ScriptValue& src, QVariantList& dest) { | |
| 184 | 86 | if(!src.isArray()) return false; |
| 185 | − QVariantList& dest = *reinterpret_cast<QVariantList*>(pDest); | |
| 186 | 87 | int len = src.property("length").toInteger(); |
| 187 | 88 | dest.clear(); |
| 188 | 89 | for (int idx = 0; idx < len; ++idx) { |
| @@ -191,8 +92,7 @@ static bool VariantListFromScriptValue(const ScriptValue& src, void* pDest) { · 2 unmodified lines | ||
| 191 | 92 | return true; |
| 192 | 93 | } |
| 193 | 94 | |
| 194 | −static ScriptValue VariantMapToScriptValue(ScriptEngine* engine, const void* pSrc) { | |
| 195 | − const QVariantMap& src = *reinterpret_cast<const QVariantMap*>(pSrc); | |
| 95 | +static ScriptValue VariantMapToScriptValue(ScriptEngine* engine, const QVariantMap& src) { | |
| 196 | 96 | ScriptValue dest = engine->newObject(); |
| 197 | 97 | for (QVariantMap::const_iterator iter = src.cbegin(); iter != src.cend(); ++iter) { |
| 198 | 98 | dest.setProperty(iter.key(), engine->newVariant(iter.value())); |
| @@ -200,8 +100,7 @@ static ScriptValue VariantMapToScriptValue(ScriptEngine* engine, const void* pSr · 1 unmodified line | ||
| 200 | 100 | return dest; |
| 201 | 101 | } |
| 202 | 102 | |
| 203 | −static bool VariantMapFromScriptValue(const ScriptValue& src, void* pDest) { | |
| 204 | − QVariantMap& dest = *reinterpret_cast<QVariantMap*>(pDest); | |
| 103 | +static bool VariantMapFromScriptValue(const ScriptValue& src, QVariantMap& dest) { | |
| 205 | 104 | dest.clear(); |
| 206 | 105 | ScriptValueIteratorPointer iter = src.newIterator(); |
| 207 | 106 | while (iter->hasNext()) { |
| @@ -211,8 +110,7 @@ static bool VariantMapFromScriptValue(const ScriptValue& src, void* pDest) { · 3 unmodified lines | ||
| 211 | 110 | return true; |
| 212 | 111 | } |
| 213 | 112 | |
| 214 | −static ScriptValue VariantHashToScriptValue(ScriptEngine* engine, const void* pSrc) { | |
| 215 | − const QVariantHash& src = *reinterpret_cast<const QVariantHash*>(pSrc); | |
| 113 | +static ScriptValue VariantHashToScriptValue(ScriptEngine* engine, const QVariantHash& src) { | |
| 216 | 114 | ScriptValue dest = engine->newObject(); |
| 217 | 115 | for (QVariantHash::const_iterator iter = src.cbegin(); iter != src.cend(); ++iter) { |
| 218 | 116 | dest.setProperty(iter.key(), engine->newVariant(iter.value())); |
| @@ -220,8 +118,7 @@ static ScriptValue VariantHashToScriptValue(ScriptEngine* engine, const void* pS · 1 unmodified line | ||
| 220 | 118 | return dest; |
| 221 | 119 | } |
| 222 | 120 | |
| 223 | −static bool VariantHashFromScriptValue(const ScriptValue& src, void* pDest) { | |
| 224 | − QVariantHash& dest = *reinterpret_cast<QVariantHash*>(pDest); | |
| 121 | +static bool VariantHashFromScriptValue(const ScriptValue& src, QVariantHash& dest) { | |
| 225 | 122 | dest.clear(); |
| 226 | 123 | ScriptValueIteratorPointer iter = src.newIterator(); |
| 227 | 124 | while (iter->hasNext()) { |
| @@ -231,19 +128,16 @@ static bool VariantHashFromScriptValue(const ScriptValue& src, void* pDest) { · 3 unmodified lines | ||
| 231 | 128 | return true; |
| 232 | 129 | } |
| 233 | 130 | |
| 234 | −static ScriptValue JsonValueToScriptValue(ScriptEngine* engine, const void* pSrc) { | |
| 235 | − const QJsonValue& src = *reinterpret_cast<const QJsonValue*>(pSrc); | |
| 131 | +static ScriptValue JsonValueToScriptValue(ScriptEngine* engine, const QJsonValue& src) { | |
| 236 | 132 | return engine->newVariant(src.toVariant()); |
| 237 | 133 | } |
| 238 | 134 | |
| 239 | −static bool JsonValueFromScriptValue(const ScriptValue& src, void* pDest) { | |
| 240 | − QJsonValue& dest = *reinterpret_cast<QJsonValue*>(pDest); | |
| 135 | +static bool JsonValueFromScriptValue(const ScriptValue& src, QJsonValue& dest) { | |
| 241 | 136 | dest = QJsonValue::fromVariant(src.toVariant()); |
| 242 | 137 | return true; |
| 243 | 138 | } |
| 244 | 139 | |
| 245 | −static ScriptValue JsonObjectToScriptValue(ScriptEngine* engine, const void* pSrc) { | |
| 246 | − const QJsonObject& src = *reinterpret_cast<const QJsonObject*>(pSrc); | |
| 140 | +static ScriptValue JsonObjectToScriptValue(ScriptEngine* engine, const QJsonObject& src) { | |
| 247 | 141 | QVariantMap map = src.toVariantMap(); |
| 248 | 142 | ScriptValue dest = engine->newObject(); |
| 249 | 143 | for (QVariantMap::const_iterator iter = map.cbegin(); iter != map.cend(); ++iter) { |
| @@ -252,8 +146,7 @@ static ScriptValue JsonObjectToScriptValue(ScriptEngine* engine, const void* pSr · 2 unmodified lines | ||
| 252 | 146 | return dest; |
| 253 | 147 | } |
| 254 | 148 | |
| 255 | −static bool JsonObjectFromScriptValue(const ScriptValue& src, void* pDest) { | |
| 256 | − QJsonObject& dest = *reinterpret_cast<QJsonObject*>(pDest); | |
| 149 | +static bool JsonObjectFromScriptValue(const ScriptValue& src, QJsonObject& dest) { | |
| 257 | 150 | QVariantMap map; |
| 258 | 151 | ScriptValueIteratorPointer iter = src.newIterator(); |
| 259 | 152 | while (iter->hasNext()) { |
| @@ -264,8 +157,7 @@ static bool JsonObjectFromScriptValue(const ScriptValue& src, void* pDest) { · 4 unmodified lines | ||
| 264 | 157 | return true; |
| 265 | 158 | } |
| 266 | 159 | |
| 267 | −static ScriptValue JsonArrayToScriptValue(ScriptEngine* engine, const void* pSrc) { | |
| 268 | − const QJsonArray& src = *reinterpret_cast<const QJsonArray*>(pSrc); | |
| 160 | +static ScriptValue JsonArrayToScriptValue(ScriptEngine* engine, const QJsonArray& src) { | |
| 269 | 161 | QVariantList list = src.toVariantList(); |
| 270 | 162 | int len = list.length(); |
| 271 | 163 | ScriptValue dest = engine->newArray(len); |
| @@ -275,9 +167,8 @@ static ScriptValue JsonArrayToScriptValue(ScriptEngine* engine, const void* pSrc · 3 unmodified lines | ||
| 275 | 167 | return dest; |
| 276 | 168 | } |
| 277 | 169 | |
| 278 | −static bool JsonArrayFromScriptValue(const ScriptValue& src, void* pDest) { | |
| 170 | +static bool JsonArrayFromScriptValue(const ScriptValue& src, QJsonArray& dest) { | |
| 279 | 171 | if(!src.isArray()) return false; |
| 280 | − QJsonArray& dest = *reinterpret_cast<QJsonArray*>(pDest); | |
| 281 | 172 | QVariantList list; |
| 282 | 173 | int len = src.property("length").toInteger(); |
| 283 | 174 | for (int idx = 0; idx < len; ++idx) { |
| @@ -292,63 +183,33 @@ static bool JsonArrayFromScriptValue(const ScriptValue& src, void* pDest) { · 8 unmodified lines | ||
| 292 | 183 | void ScriptEngineQtScript::registerSystemTypes() { |
| 293 | 184 | qScriptRegisterMetaType(this, ScriptValueToQScriptValue, ScriptValueFromQScriptValue); |
| 294 | 185 | |
| 295 | − QMutexLocker guard(&_customTypeProtect); | |
| 296 | − | |
| 297 | − { | |
| 298 | − CustomMarshal& customType = _customTypes.insert(QMetaType::QStringList, CustomMarshal()).value(); | |
| 299 | − customType.demarshalFunc = StringListFromScriptValue; | |
| 300 | − customType.marshalFunc = StringListToScriptValue; | |
| 301 | − } | |
| 302 | − { | |
| 303 | − CustomMarshal& customType = _customTypes.insert(QMetaType::QVariantList, CustomMarshal()).value(); | |
| 304 | − customType.demarshalFunc = VariantListFromScriptValue; | |
| 305 | − customType.marshalFunc = VariantListToScriptValue; | |
| 306 | − } | |
| 307 | − { | |
| 308 | − CustomMarshal& customType = _customTypes.insert(QMetaType::QVariantMap, CustomMarshal()).value(); | |
| 309 | − customType.demarshalFunc = VariantMapFromScriptValue; | |
| 310 | − customType.marshalFunc = VariantMapToScriptValue; | |
| 311 | − } | |
| 312 | − { | |
| 313 | − CustomMarshal& customType = _customTypes.insert(QMetaType::QVariantHash, CustomMarshal()).value(); | |
| 314 | − customType.demarshalFunc = VariantHashFromScriptValue; | |
| 315 | − customType.marshalFunc = VariantHashToScriptValue; | |
| 316 | − } | |
| 317 | − { | |
| 318 | − CustomMarshal& customType = _customTypes.insert(QMetaType::QJsonValue, CustomMarshal()).value(); | |
| 319 | − customType.demarshalFunc = JsonValueFromScriptValue; | |
| 320 | − customType.marshalFunc = JsonValueToScriptValue; | |
| 321 | − } | |
| 322 | − { | |
| 323 | − CustomMarshal& customType = _customTypes.insert(QMetaType::QJsonObject, CustomMarshal()).value(); | |
| 324 | − customType.demarshalFunc = JsonObjectFromScriptValue; | |
| 325 | − customType.marshalFunc = JsonObjectToScriptValue; | |
| 326 | − } | |
| 327 | − { | |
| 328 | − CustomMarshal& customType = _customTypes.insert(QMetaType::QJsonArray, CustomMarshal()).value(); | |
| 329 | − customType.demarshalFunc = JsonArrayFromScriptValue; | |
| 330 | − customType.marshalFunc = JsonArrayToScriptValue; | |
| 331 | − } | |
| 186 | + scriptRegisterMetaType(this, StringListToScriptValue, StringListFromScriptValue); | |
| 187 | + scriptRegisterMetaType(this, VariantListToScriptValue, VariantListFromScriptValue); | |
| 188 | + scriptRegisterMetaType(this, VariantMapToScriptValue, VariantMapFromScriptValue); | |
| 189 | + scriptRegisterMetaType(this, VariantHashToScriptValue, VariantHashFromScriptValue); | |
| 190 | + scriptRegisterMetaType(this, JsonValueToScriptValue, JsonValueFromScriptValue); | |
| 191 | + scriptRegisterMetaType(this, JsonObjectToScriptValue, JsonObjectFromScriptValue); | |
| 192 | + scriptRegisterMetaType(this, JsonArrayToScriptValue, JsonArrayFromScriptValue); | |
| 332 | 193 | } |
| 333 | 194 | |
| 334 | −bool ScriptEngineQtScript::castValueToVariant(const QScriptValue& val, QVariant& dest, int destType) { | |
| 195 | +bool ScriptEngineQtScript::castValueToVariant(const QScriptValue& val, QVariant& dest, int destTypeId) { | |
| 335 | 196 | |
| 336 | 197 | // if we're not particularly interested in a specific type, try to detect if we're dealing with a registered type |
| 337 | − if (destType == QMetaType::UnknownType) { | |
| 198 | + if (destTypeId == QMetaType::UnknownType) { | |
| 338 | 199 | QObject* obj = ScriptObjectQtProxy::unwrap(val); |
| 339 | 200 | if (obj) { |
| 340 | 201 | for (const QMetaObject* metaObject = obj->metaObject(); metaObject; metaObject = metaObject->superClass()) { |
| 341 | 202 | QByteArray typeName = QByteArray(metaObject->className()) + "*"; |
| 342 | 203 | int typeId = QMetaType::type(typeName.constData()); |
| 343 | 204 | if (typeId != QMetaType::UnknownType) { |
| 344 | − destType = typeId; | |
| 205 | + destTypeId = typeId; | |
| 345 | 206 | break; |
| 346 | 207 | } |
| 347 | 208 | } |
| 348 | 209 | } |
| 349 | 210 | } |
| 350 | 211 | |
| 351 | − if (destType == qMetaTypeId<ScriptValue>()) { | |
| 212 | + if (destTypeId == qMetaTypeId<ScriptValue>()) { | |
| 352 | 213 | dest = QVariant::fromValue(ScriptValue(new ScriptValueQtWrapper(this, val))); |
| 353 | 214 | return true; |
| 354 | 215 | } |
| @@ -357,20 +218,19 @@ bool ScriptEngineQtScript::castValueToVariant(const QScriptValue& val, QVariant& · 2 unmodified lines | ||
| 357 | 218 | ScriptEngine::DemarshalFunction demarshalFunc = nullptr; |
| 358 | 219 | { |
| 359 | 220 | QMutexLocker guard(&_customTypeProtect); |
| 360 | − CustomMarshalMap::const_iterator lookup = _customTypes.find(destType); | |
| 221 | + CustomMarshalMap::const_iterator lookup = _customTypes.find(destTypeId); | |
| 361 | 222 | if (lookup != _customTypes.cend()) { |
| 362 | 223 | demarshalFunc = lookup.value().demarshalFunc; |
| 363 | 224 | } |
| 364 | 225 | } |
| 365 | 226 | if (demarshalFunc) { |
| 366 | − void* destStorage = QMetaType::create(destType); | |
| 227 | + dest = QVariant(destTypeId, static_cast<void*>(NULL)); | |
| 367 | 228 | ScriptValue wrappedVal(new ScriptValueQtWrapper(this, val)); |
| 368 | − bool success = demarshalFunc(wrappedVal, destStorage); | |
| 369 | − dest = success ? QVariant(destType, destStorage) : QVariant(); | |
| 370 | − QMetaType::destroy(destType, destStorage); | |
| 229 | + bool success = demarshalFunc(wrappedVal, const_cast<void*>(dest.constData())); | |
| 230 | + if(!success) dest = QVariant(); | |
| 371 | 231 | return success; |
| 372 | 232 | } else { |
| 373 | − switch (destType) { | |
| 233 | + switch (destTypeId) { | |
| 374 | 234 | case QMetaType::UnknownType: |
| 375 | 235 | if (val.isUndefined()) { |
| 376 | 236 | dest = QVariant(); |
| @@ -443,8 +303,19 @@ bool ScriptEngineQtScript::castValueToVariant(const QScriptValue& val, QVariant& · 66 unmodified lines | ||
| 443 | 303 | break; |
| 444 | 304 | default: |
| 445 | 305 | // check to see if this is a pointer to a QObject-derived object |
| 446 | − if (QMetaType::typeFlags(destType) & QMetaType::PointerToQObject) { | |
| 447 | − dest = QVariant::fromValue(ScriptObjectQtProxy::unwrap(val)); | |
| 306 | + if (QMetaType::typeFlags(destTypeId) & (QMetaType::PointerToQObject | QMetaType::TrackingPointerToQObject)) { | |
| 307 | + /* Do we really want to permit regular passing of nullptr to native functions? | |
| 308 | + if (!val.isValid() || val.isUndefined() || val.isNull()) { | |
| 309 | + dest = QVariant::fromValue(nullptr); | |
| 310 | + break; | |
| 311 | + }*/ | |
| 312 | + QObject* obj = ScriptObjectQtProxy::unwrap(val); | |
| 313 | + if (!obj) return false; | |
| 314 | + const QMetaObject* destMeta = QMetaType::metaObjectForType(destTypeId); | |
| 315 | + Q_ASSERT(destMeta); | |
| 316 | + obj = destMeta->cast(obj); | |
| 317 | + if (!obj) return false; | |
| 318 | + dest = QVariant::fromValue(obj); | |
| 448 | 319 | break; |
| 449 | 320 | } |
| 450 | 321 | // check to see if we have a registered prototype |
| @@ -461,7 +332,40 @@ bool ScriptEngineQtScript::castValueToVariant(const QScriptValue& val, QVariant& · 10 unmodified lines | ||
| 461 | 332 | } |
| 462 | 333 | } |
| 463 | 334 | |
| 464 | − return destType == QMetaType::UnknownType || dest.userType() == destType || dest.convert(destType); | |
| 335 | + return destTypeId == QMetaType::UnknownType || dest.userType() == destTypeId || dest.convert(destTypeId); | |
| 336 | +} | |
| 337 | + | |
| 338 | +QString ScriptEngineQtScript::valueType(const QScriptValue& val) { | |
| 339 | + if (val.isUndefined()) { | |
| 340 | + return "undefined"; | |
| 341 | + } | |
| 342 | + if (val.isNull()) { | |
| 343 | + return "null"; | |
| 344 | + } | |
| 345 | + if (val.isBool()) { | |
| 346 | + return "boolean"; | |
| 347 | + } | |
| 348 | + if (val.isString()) { | |
| 349 | + return "string"; | |
| 350 | + } | |
| 351 | + if (val.isNumber()) { | |
| 352 | + return "number"; | |
| 353 | + } | |
| 354 | + { | |
| 355 | + QObject* obj = ScriptObjectQtProxy::unwrap(val); | |
| 356 | + if (obj) { | |
| 357 | + QString objectName = obj->objectName(); | |
| 358 | + if (!objectName.isEmpty()) return objectName; | |
| 359 | + return obj->metaObject()->className(); | |
| 360 | + } | |
| 361 | + } | |
| 362 | + { | |
| 363 | + QVariant var = ScriptVariantQtProxy::unwrap(val); | |
| 364 | + if (var.isValid()) { | |
| 365 | + return var.typeName(); | |
| 366 | + } | |
| 367 | + } | |
| 368 | + return val.toVariant().typeName(); | |
| 465 | 369 | } |
| 466 | 370 | |
| 467 | 371 | QScriptValue ScriptEngineQtScript::castVariantToValue(const QVariant& val) { |
| @@ -513,16 +417,21 @@ QScriptValue ScriptEngineQtScript::castVariantToValue(const QVariant& val) { · 45 unmodified lines | ||
| 513 | 417 | return QScriptValue(this, val.toString()); |
| 514 | 418 | case QMetaType::QVariant: |
| 515 | 419 | return castVariantToValue(val.value<QVariant>()); |
| 516 | − case QMetaType::QObjectStar: | |
| 517 | − return ScriptObjectQtProxy::newQObject(this, val.value<QObject*>(), ScriptEngine::QtOwnership); | |
| 420 | + case QMetaType::QObjectStar: { | |
| 421 | + QObject* obj = val.value<QObject*>(); | |
| 422 | + if (obj == nullptr) return QScriptValue(this, QScriptValue::NullValue); | |
| 423 | + return ScriptObjectQtProxy::newQObject(this, obj); | |
| 424 | + } | |
| 518 | 425 | case QMetaType::QDateTime: |
| 519 | 426 | return static_cast<QScriptEngine*>(this)->newDate(val.value<QDateTime>()); |
| 520 | 427 | case QMetaType::QDate: |
| 521 | 428 | return static_cast<QScriptEngine*>(this)->newDate(val.value<QDate>().startOfDay()); |
| 522 | 429 | default: |
| 523 | 430 | // check to see if this is a pointer to a QObject-derived object |
| 524 | − if (QMetaType::typeFlags(valTypeId) & QMetaType::PointerToQObject) { | |
| 525 | − return ScriptObjectQtProxy::newQObject(this, val.value<QObject*>(), ScriptEngine::QtOwnership); | |
| 431 | + if (QMetaType::typeFlags(valTypeId) & (QMetaType::PointerToQObject | QMetaType::TrackingPointerToQObject)) { | |
| 432 | + QObject* obj = val.value<QObject*>(); | |
| 433 | + if (obj == nullptr) return QScriptValue(this, QScriptValue::NullValue); | |
| 434 | + return ScriptObjectQtProxy::newQObject(this, obj); | |
| 526 | 435 | } |
| 527 | 436 | // have we set a prototype'd variant? |
| 528 | 437 | { |