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 | #include <QtCore/QJsonValue> | 16 | #include <QtCore/QJsonValue> |
| 17 | #include <QtScript/QScriptEngine> | 17 | #include <QtScript/QScriptEngine> |
| 18 | 18 | ||
| 19 | #include "../ScriptEngineCast.h" | ||
| 19 | #include "../ScriptValueIterator.h" | 20 | #include "../ScriptValueIterator.h" |
| 20 | 21 | ||
| 21 | #include "ScriptObjectQtProxy.h" | 22 | #include "ScriptObjectQtProxy.h" |
| 22 | #include "ScriptValueQtWrapper.h" | 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 | void ScriptEngineQtScript::setDefaultPrototype(int metaTypeId, const ScriptValue& prototype) { | 25 | void ScriptEngineQtScript::setDefaultPrototype(int metaTypeId, const ScriptValue& prototype) { |
| 72 | ScriptValueQtWrapper* unwrappedPrototype = ScriptValueQtWrapper::unwrap(prototype); | 26 | ScriptValueQtWrapper* unwrappedPrototype = ScriptValueQtWrapper::unwrap(prototype); |
| 73 | if (unwrappedPrototype) { | 27 | if (unwrappedPrototype) { |
| 74 | const QScriptValue& scriptPrototype = unwrappedPrototype->toQtValue(); | 28 | const QScriptValue& scriptPrototype = unwrappedPrototype->toQtValue(); |
| 75 | QScriptEngine::setDefaultPrototype(metaTypeId, scriptPrototype); | ||
| 76 | |||
| 77 | QMutexLocker guard(&_customTypeProtect); | 29 | QMutexLocker guard(&_customTypeProtect); |
| 78 | _customPrototypes.insert(metaTypeId, scriptPrototype); | 30 | _customPrototypes.insert(metaTypeId, scriptPrototype); |
| 79 | } | 31 | } |
| @@ -83,59 +35,12 @@ void ScriptEngineQtScript::registerCustomType(int type, · 3 unmodified lines | |||
| 83 | ScriptEngine::MarshalFunction marshalFunc, | 35 | ScriptEngine::MarshalFunction marshalFunc, |
| 84 | ScriptEngine::DemarshalFunction demarshalFunc) | 36 | ScriptEngine::DemarshalFunction demarshalFunc) |
| 85 | { | 37 | { |
| 86 | QScriptEngine::MarshalFunction internalMarshalFunc; | 38 | QMutexLocker guard(&_customTypeProtect); |
| 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 | } | ||
| 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 | Q_DECLARE_METATYPE(ScriptValue); | 46 | Q_DECLARE_METATYPE(ScriptValue); |
| @@ -149,8 +54,7 @@ static void ScriptValueFromQScriptValue(const QScriptValue& src, ScriptValue& de · 7 unmodified lines | |||
| 149 | dest = ScriptValue(new ScriptValueQtWrapper(engine, src)); | 54 | dest = ScriptValue(new ScriptValueQtWrapper(engine, src)); |
| 150 | } | 55 | } |
| 151 | 56 | ||
| 152 | static ScriptValue StringListToScriptValue(ScriptEngine* engine, const void* pSrc) { | 57 | static ScriptValue StringListToScriptValue(ScriptEngine* engine, const QStringList& src) { |
| 153 | const QStringList& src = *reinterpret_cast<const QStringList*>(pSrc); | ||
| 154 | int len = src.length(); | 58 | int len = src.length(); |
| 155 | ScriptValue dest = engine->newArray(len); | 59 | ScriptValue dest = engine->newArray(len); |
| 156 | for (int idx = 0; idx < len; ++idx) { | 60 | for (int idx = 0; idx < len; ++idx) { |
| @@ -159,9 +63,8 @@ static ScriptValue StringListToScriptValue(ScriptEngine* engine, const void* pSr · 2 unmodified lines | |||
| 159 | return dest; | 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 | if(!src.isArray()) return false; | 67 | if(!src.isArray()) return false; |
| 164 | QStringList& dest = *reinterpret_cast<QStringList*>(pDest); | ||
| 165 | int len = src.property("length").toInteger(); | 68 | int len = src.property("length").toInteger(); |
| 166 | dest.clear(); | 69 | dest.clear(); |
| 167 | for (int idx = 0; idx < len; ++idx) { | 70 | for (int idx = 0; idx < len; ++idx) { |
| @@ -170,8 +73,7 @@ static bool StringListFromScriptValue(const ScriptValue& src, void* pDest) { · 2 unmodified lines | |||
| 170 | return true; | 73 | return true; |
| 171 | } | 74 | } |
| 172 | 75 | ||
| 173 | static ScriptValue VariantListToScriptValue(ScriptEngine* engine, const void* pSrc) { | 76 | static ScriptValue VariantListToScriptValue(ScriptEngine* engine, const QVariantList& src) { |
| 174 | const QVariantList& src = *reinterpret_cast<const QVariantList*>(pSrc); | ||
| 175 | int len = src.length(); | 77 | int len = src.length(); |
| 176 | ScriptValue dest = engine->newArray(len); | 78 | ScriptValue dest = engine->newArray(len); |
| 177 | for (int idx = 0; idx < len; ++idx) { | 79 | for (int idx = 0; idx < len; ++idx) { |
| @@ -180,9 +82,8 @@ static ScriptValue VariantListToScriptValue(ScriptEngine* engine, const void* pS · 2 unmodified lines | |||
| 180 | return dest; | 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 | if(!src.isArray()) return false; | 86 | if(!src.isArray()) return false; |
| 185 | QVariantList& dest = *reinterpret_cast<QVariantList*>(pDest); | ||
| 186 | int len = src.property("length").toInteger(); | 87 | int len = src.property("length").toInteger(); |
| 187 | dest.clear(); | 88 | dest.clear(); |
| 188 | for (int idx = 0; idx < len; ++idx) { | 89 | for (int idx = 0; idx < len; ++idx) { |
| @@ -191,8 +92,7 @@ static bool VariantListFromScriptValue(const ScriptValue& src, void* pDest) { · 2 unmodified lines | |||
| 191 | return true; | 92 | return true; |
| 192 | } | 93 | } |
| 193 | 94 | ||
| 194 | static ScriptValue VariantMapToScriptValue(ScriptEngine* engine, const void* pSrc) { | 95 | static ScriptValue VariantMapToScriptValue(ScriptEngine* engine, const QVariantMap& src) { |
| 195 | const QVariantMap& src = *reinterpret_cast<const QVariantMap*>(pSrc); | ||
| 196 | ScriptValue dest = engine->newObject(); | 96 | ScriptValue dest = engine->newObject(); |
| 197 | for (QVariantMap::const_iterator iter = src.cbegin(); iter != src.cend(); ++iter) { | 97 | for (QVariantMap::const_iterator iter = src.cbegin(); iter != src.cend(); ++iter) { |
| 198 | dest.setProperty(iter.key(), engine->newVariant(iter.value())); | 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 | return dest; | 100 | return dest; |
| 201 | } | 101 | } |
| 202 | 102 | ||
| 203 | static bool VariantMapFromScriptValue(const ScriptValue& src, void* pDest) { | 103 | static bool VariantMapFromScriptValue(const ScriptValue& src, QVariantMap& dest) { |
| 204 | QVariantMap& dest = *reinterpret_cast<QVariantMap*>(pDest); | ||
| 205 | dest.clear(); | 104 | dest.clear(); |
| 206 | ScriptValueIteratorPointer iter = src.newIterator(); | 105 | ScriptValueIteratorPointer iter = src.newIterator(); |
| 207 | while (iter->hasNext()) { | 106 | while (iter->hasNext()) { |
| @@ -211,8 +110,7 @@ static bool VariantMapFromScriptValue(const ScriptValue& src, void* pDest) { · 3 unmodified lines | |||
| 211 | return true; | 110 | return true; |
| 212 | } | 111 | } |
| 213 | 112 | ||
| 214 | static ScriptValue VariantHashToScriptValue(ScriptEngine* engine, const void* pSrc) { | 113 | static ScriptValue VariantHashToScriptValue(ScriptEngine* engine, const QVariantHash& src) { |
| 215 | const QVariantHash& src = *reinterpret_cast<const QVariantHash*>(pSrc); | ||
| 216 | ScriptValue dest = engine->newObject(); | 114 | ScriptValue dest = engine->newObject(); |
| 217 | for (QVariantHash::const_iterator iter = src.cbegin(); iter != src.cend(); ++iter) { | 115 | for (QVariantHash::const_iterator iter = src.cbegin(); iter != src.cend(); ++iter) { |
| 218 | dest.setProperty(iter.key(), engine->newVariant(iter.value())); | 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 | return dest; | 118 | return dest; |
| 221 | } | 119 | } |
| 222 | 120 | ||
| 223 | static bool VariantHashFromScriptValue(const ScriptValue& src, void* pDest) { | 121 | static bool VariantHashFromScriptValue(const ScriptValue& src, QVariantHash& dest) { |
| 224 | QVariantHash& dest = *reinterpret_cast<QVariantHash*>(pDest); | ||
| 225 | dest.clear(); | 122 | dest.clear(); |
| 226 | ScriptValueIteratorPointer iter = src.newIterator(); | 123 | ScriptValueIteratorPointer iter = src.newIterator(); |
| 227 | while (iter->hasNext()) { | 124 | while (iter->hasNext()) { |
| @@ -231,19 +128,16 @@ static bool VariantHashFromScriptValue(const ScriptValue& src, void* pDest) { · 3 unmodified lines | |||
| 231 | return true; | 128 | return true; |
| 232 | } | 129 | } |
| 233 | 130 | ||
| 234 | static ScriptValue JsonValueToScriptValue(ScriptEngine* engine, const void* pSrc) { | 131 | static ScriptValue JsonValueToScriptValue(ScriptEngine* engine, const QJsonValue& src) { |
| 235 | const QJsonValue& src = *reinterpret_cast<const QJsonValue*>(pSrc); | ||
| 236 | return engine->newVariant(src.toVariant()); | 132 | return engine->newVariant(src.toVariant()); |
| 237 | } | 133 | } |
| 238 | 134 | ||
| 239 | static bool JsonValueFromScriptValue(const ScriptValue& src, void* pDest) { | 135 | static bool JsonValueFromScriptValue(const ScriptValue& src, QJsonValue& dest) { |
| 240 | QJsonValue& dest = *reinterpret_cast<QJsonValue*>(pDest); | ||
| 241 | dest = QJsonValue::fromVariant(src.toVariant()); | 136 | dest = QJsonValue::fromVariant(src.toVariant()); |
| 242 | return true; | 137 | return true; |
| 243 | } | 138 | } |
| 244 | 139 | ||
| 245 | static ScriptValue JsonObjectToScriptValue(ScriptEngine* engine, const void* pSrc) { | 140 | static ScriptValue JsonObjectToScriptValue(ScriptEngine* engine, const QJsonObject& src) { |
| 246 | const QJsonObject& src = *reinterpret_cast<const QJsonObject*>(pSrc); | ||
| 247 | QVariantMap map = src.toVariantMap(); | 141 | QVariantMap map = src.toVariantMap(); |
| 248 | ScriptValue dest = engine->newObject(); | 142 | ScriptValue dest = engine->newObject(); |
| 249 | for (QVariantMap::const_iterator iter = map.cbegin(); iter != map.cend(); ++iter) { | 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 | return dest; | 146 | return dest; |
| 253 | } | 147 | } |
| 254 | 148 | ||
| 255 | static bool JsonObjectFromScriptValue(const ScriptValue& src, void* pDest) { | 149 | static bool JsonObjectFromScriptValue(const ScriptValue& src, QJsonObject& dest) { |
| 256 | QJsonObject& dest = *reinterpret_cast<QJsonObject*>(pDest); | ||
| 257 | QVariantMap map; | 150 | QVariantMap map; |
| 258 | ScriptValueIteratorPointer iter = src.newIterator(); | 151 | ScriptValueIteratorPointer iter = src.newIterator(); |
| 259 | while (iter->hasNext()) { | 152 | while (iter->hasNext()) { |
| @@ -264,8 +157,7 @@ static bool JsonObjectFromScriptValue(const ScriptValue& src, void* pDest) { · 4 unmodified lines | |||
| 264 | return true; | 157 | return true; |
| 265 | } | 158 | } |
| 266 | 159 | ||
| 267 | static ScriptValue JsonArrayToScriptValue(ScriptEngine* engine, const void* pSrc) { | 160 | static ScriptValue JsonArrayToScriptValue(ScriptEngine* engine, const QJsonArray& src) { |
| 268 | const QJsonArray& src = *reinterpret_cast<const QJsonArray*>(pSrc); | ||
| 269 | QVariantList list = src.toVariantList(); | 161 | QVariantList list = src.toVariantList(); |
| 270 | int len = list.length(); | 162 | int len = list.length(); |
| 271 | ScriptValue dest = engine->newArray(len); | 163 | ScriptValue dest = engine->newArray(len); |
| @@ -275,9 +167,8 @@ static ScriptValue JsonArrayToScriptValue(ScriptEngine* engine, const void* pSrc · 3 unmodified lines | |||
| 275 | return dest; | 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 | if(!src.isArray()) return false; | 171 | if(!src.isArray()) return false; |
| 280 | QJsonArray& dest = *reinterpret_cast<QJsonArray*>(pDest); | ||
| 281 | QVariantList list; | 172 | QVariantList list; |
| 282 | int len = src.property("length").toInteger(); | 173 | int len = src.property("length").toInteger(); |
| 283 | for (int idx = 0; idx < len; ++idx) { | 174 | for (int idx = 0; idx < len; ++idx) { |
| @@ -292,63 +183,33 @@ static bool JsonArrayFromScriptValue(const ScriptValue& src, void* pDest) { · 8 unmodified lines | |||
| 292 | void ScriptEngineQtScript::registerSystemTypes() { | 183 | void ScriptEngineQtScript::registerSystemTypes() { |
| 293 | qScriptRegisterMetaType(this, ScriptValueToQScriptValue, ScriptValueFromQScriptValue); | 184 | qScriptRegisterMetaType(this, ScriptValueToQScriptValue, ScriptValueFromQScriptValue); |
| 294 | 185 | ||
| 295 | QMutexLocker guard(&_customTypeProtect); | 186 | scriptRegisterMetaType(this, StringListToScriptValue, StringListFromScriptValue); |
| 296 | 187 | scriptRegisterMetaType(this, VariantListToScriptValue, VariantListFromScriptValue); | |
| 297 | { | 188 | scriptRegisterMetaType(this, VariantMapToScriptValue, VariantMapFromScriptValue); |
| 298 | CustomMarshal& customType = _customTypes.insert(QMetaType::QStringList, CustomMarshal()).value(); | 189 | scriptRegisterMetaType(this, VariantHashToScriptValue, VariantHashFromScriptValue); |
| 299 | customType.demarshalFunc = StringListFromScriptValue; | 190 | scriptRegisterMetaType(this, JsonValueToScriptValue, JsonValueFromScriptValue); |
| 300 | customType.marshalFunc = StringListToScriptValue; | 191 | scriptRegisterMetaType(this, JsonObjectToScriptValue, JsonObjectFromScriptValue); |
| 301 | } | 192 | scriptRegisterMetaType(this, JsonArrayToScriptValue, JsonArrayFromScriptValue); |
| 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 | } | ||
| 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 | // if we're not particularly interested in a specific type, try to detect if we're dealing with a registered type | 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 | QObject* obj = ScriptObjectQtProxy::unwrap(val); | 199 | QObject* obj = ScriptObjectQtProxy::unwrap(val); |
| 339 | if (obj) { | 200 | if (obj) { |
| 340 | for (const QMetaObject* metaObject = obj->metaObject(); metaObject; metaObject = metaObject->superClass()) { | 201 | for (const QMetaObject* metaObject = obj->metaObject(); metaObject; metaObject = metaObject->superClass()) { |
| 341 | QByteArray typeName = QByteArray(metaObject->className()) + "*"; | 202 | QByteArray typeName = QByteArray(metaObject->className()) + "*"; |
| 342 | int typeId = QMetaType::type(typeName.constData()); | 203 | int typeId = QMetaType::type(typeName.constData()); |
| 343 | if (typeId != QMetaType::UnknownType) { | 204 | if (typeId != QMetaType::UnknownType) { |
| 344 | destType = typeId; | 205 | destTypeId = typeId; |
| 345 | break; | 206 | break; |
| 346 | } | 207 | } |
| 347 | } | 208 | } |
| 348 | } | 209 | } |
| 349 | } | 210 | } |
| 350 | 211 | ||
| 351 | if (destType == qMetaTypeId<ScriptValue>()) { | 212 | if (destTypeId == qMetaTypeId<ScriptValue>()) { |
| 352 | dest = QVariant::fromValue(ScriptValue(new ScriptValueQtWrapper(this, val))); | 213 | dest = QVariant::fromValue(ScriptValue(new ScriptValueQtWrapper(this, val))); |
| 353 | return true; | 214 | return true; |
| 354 | } | 215 | } |
| @@ -357,20 +218,19 @@ bool ScriptEngineQtScript::castValueToVariant(const QScriptValue& val, QVariant& · 2 unmodified lines | |||
| 357 | ScriptEngine::DemarshalFunction demarshalFunc = nullptr; | 218 | ScriptEngine::DemarshalFunction demarshalFunc = nullptr; |
| 358 | { | 219 | { |
| 359 | QMutexLocker guard(&_customTypeProtect); | 220 | QMutexLocker guard(&_customTypeProtect); |
| 360 | CustomMarshalMap::const_iterator lookup = _customTypes.find(destType); | 221 | CustomMarshalMap::const_iterator lookup = _customTypes.find(destTypeId); |
| 361 | if (lookup != _customTypes.cend()) { | 222 | if (lookup != _customTypes.cend()) { |
| 362 | demarshalFunc = lookup.value().demarshalFunc; | 223 | demarshalFunc = lookup.value().demarshalFunc; |
| 363 | } | 224 | } |
| 364 | } | 225 | } |
| 365 | if (demarshalFunc) { | 226 | if (demarshalFunc) { |
| 366 | void* destStorage = QMetaType::create(destType); | 227 | dest = QVariant(destTypeId, static_cast<void*>(NULL)); |
| 367 | ScriptValue wrappedVal(new ScriptValueQtWrapper(this, val)); | 228 | ScriptValue wrappedVal(new ScriptValueQtWrapper(this, val)); |
| 368 | bool success = demarshalFunc(wrappedVal, destStorage); | 229 | bool success = demarshalFunc(wrappedVal, const_cast<void*>(dest.constData())); |
| 369 | dest = success ? QVariant(destType, destStorage) : QVariant(); | 230 | if(!success) dest = QVariant(); |
| 370 | QMetaType::destroy(destType, destStorage); | ||
| 371 | return success; | 231 | return success; |
| 372 | } else { | 232 | } else { |
| 373 | switch (destType) { | 233 | switch (destTypeId) { |
| 374 | case QMetaType::UnknownType: | 234 | case QMetaType::UnknownType: |
| 375 | if (val.isUndefined()) { | 235 | if (val.isUndefined()) { |
| 376 | dest = QVariant(); | 236 | dest = QVariant(); |
| @@ -443,8 +303,19 @@ bool ScriptEngineQtScript::castValueToVariant(const QScriptValue& val, QVariant& · 66 unmodified lines | |||
| 443 | break; | 303 | break; |
| 444 | default: | 304 | default: |
| 445 | // check to see if this is a pointer to a QObject-derived object | 305 | // check to see if this is a pointer to a QObject-derived object |
| 446 | if (QMetaType::typeFlags(destType) & QMetaType::PointerToQObject) { | 306 | if (QMetaType::typeFlags(destTypeId) & (QMetaType::PointerToQObject | QMetaType::TrackingPointerToQObject)) { |
| 447 | dest = QVariant::fromValue(ScriptObjectQtProxy::unwrap(val)); | 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 | break; | 319 | break; |
| 449 | } | 320 | } |
| 450 | // check to see if we have a registered prototype | 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 | QScriptValue ScriptEngineQtScript::castVariantToValue(const QVariant& val) { | 371 | QScriptValue ScriptEngineQtScript::castVariantToValue(const QVariant& val) { |
| @@ -513,16 +417,21 @@ QScriptValue ScriptEngineQtScript::castVariantToValue(const QVariant& val) { · 45 unmodified lines | |||
| 513 | return QScriptValue(this, val.toString()); | 417 | return QScriptValue(this, val.toString()); |
| 514 | case QMetaType::QVariant: | 418 | case QMetaType::QVariant: |
| 515 | return castVariantToValue(val.value<QVariant>()); | 419 | return castVariantToValue(val.value<QVariant>()); |
| 516 | case QMetaType::QObjectStar: | 420 | case QMetaType::QObjectStar: { |
| 517 | return ScriptObjectQtProxy::newQObject(this, val.value<QObject*>(), ScriptEngine::QtOwnership); | 421 | QObject* obj = val.value<QObject*>(); |
| 422 | if (obj == nullptr) return QScriptValue(this, QScriptValue::NullValue); | ||
| 423 | return ScriptObjectQtProxy::newQObject(this, obj); | ||
| 424 | } | ||
| 518 | case QMetaType::QDateTime: | 425 | case QMetaType::QDateTime: |
| 519 | return static_cast<QScriptEngine*>(this)->newDate(val.value<QDateTime>()); | 426 | return static_cast<QScriptEngine*>(this)->newDate(val.value<QDateTime>()); |
| 520 | case QMetaType::QDate: | 427 | case QMetaType::QDate: |
| 521 | return static_cast<QScriptEngine*>(this)->newDate(val.value<QDate>().startOfDay()); | 428 | return static_cast<QScriptEngine*>(this)->newDate(val.value<QDate>().startOfDay()); |
| 522 | default: | 429 | default: |
| 523 | // check to see if this is a pointer to a QObject-derived object | 430 | // check to see if this is a pointer to a QObject-derived object |
| 524 | if (QMetaType::typeFlags(valTypeId) & QMetaType::PointerToQObject) { | 431 | if (QMetaType::typeFlags(valTypeId) & (QMetaType::PointerToQObject | QMetaType::TrackingPointerToQObject)) { |
| 525 | return ScriptObjectQtProxy::newQObject(this, val.value<QObject*>(), ScriptEngine::QtOwnership); | 432 | QObject* obj = val.value<QObject*>(); |
| 433 | if (obj == nullptr) return QScriptValue(this, QScriptValue::NullValue); | ||
| 434 | return ScriptObjectQtProxy::newQObject(this, obj); | ||
| 526 | } | 435 | } |
| 527 | // have we set a prototype'd variant? | 436 | // have we set a prototype'd variant? |
| 528 | { | 437 | { |