From 5f2b2c90a2ddcc04fd7501be43e95a711912512d Mon Sep 17 00:00:00 2001 From: Heather Anderson Date: Tue, 31 Aug 2021 21:28:06 -0700 Subject: [PATCH] added custom type support --- .../src/qtscript/ScriptEngineQtScript.cpp | 59 ++++++++++++++++--- .../src/qtscript/ScriptEngineQtScript.h | 13 +++- 2 files changed, 64 insertions(+), 8 deletions(-) diff --git a/libraries/script-engine/src/qtscript/ScriptEngineQtScript.cpp b/libraries/script-engine/src/qtscript/ScriptEngineQtScript.cpp index 2552856727..fe3cc76c88 100644 --- a/libraries/script-engine/src/qtscript/ScriptEngineQtScript.cpp +++ b/libraries/script-engine/src/qtscript/ScriptEngineQtScript.cpp @@ -1013,25 +1013,70 @@ bool ScriptEngineQtScript::raiseException(const ScriptValuePointer& exception) { } ScriptValuePointer ScriptEngineQtScript::create(int type, const void* ptr) { + // first we'll try custom types registered with us + ScriptEngine::MarshalFunction marshalFunc = nullptr; + ScriptValuePointer prototype; + { + std::lock_guard guard(_customTypeProtect); + TCustomTypeMap::const_iterator loc = _customTypes.find(type); + if (loc != _customTypes.end()) { + const CustomTypeInfo& typeInfo = loc->second; + marshalFunc = typeInfo.marshalFunc; + prototype = typeInfo.prototype; + } + } + if (marshalFunc) { + ScriptValuePointer result = marshalFunc(this, ptr); + if (result && prototype) { + result->setPrototype(prototype); + } + return result; + } + + // falling back to having QtScript handle it QScriptValue result = qScriptValueFromValue_helper(this, type, ptr); return ScriptValuePointer(new ScriptValueQtWrapper(const_cast(this), std::move(result))); } bool ScriptEngineQtScript::convert(const ScriptValuePointer& value, int type, void* ptr) { + // first we'll try custom types registered with us + ScriptEngine::DemarshalFunction demarshalFunc = nullptr; + { + std::lock_guard guard(_customTypeProtect); + TCustomTypeMap::const_iterator loc = _customTypes.find(type); + if (loc != _customTypes.end()) { + demarshalFunc = loc->second.demarshalFunc; + } + } + if (demarshalFunc) { + demarshalFunc(value, ptr); + return true; + } + + // falling back to having QtScript handle it ScriptValueQtWrapper* unwrapped = ScriptValueQtWrapper::unwrap(value); if (unwrapped == nullptr) { return false; } return qscriptvalue_cast_helper(unwrapped->toQtValue(), type, ptr); } -/* + void ScriptEngineQtScript::registerCustomType(int type, - ScriptEngine::MarshalFunction mf, - ScriptEngine::DemarshalFunction df, - const ScriptValuePointer& prototype) { + ScriptEngine::MarshalFunction marshalFunc, + ScriptEngine::DemarshalFunction demarshalFunc, + const ScriptValuePointer& prototype) +{ ScriptValueQtWrapper* unwrapped = ScriptValueQtWrapper::unwrap(prototype); - if (unwrapped != nullptr) { - qScriptRegisterMetaType_helper(this, type, mf, df, unwrapped->toQtValue()); + if (unwrapped == nullptr) { + return; } + + std::lock_guard guard(_customTypeProtect); + TCustomTypeMap::iterator loc = _customTypes.find(type); + if(loc == _customTypes.end()) { + _customTypes.insert(TCustomTypeMap::value_type(type, CustomTypeInfo())).first; + } + CustomTypeInfo& typeInfo = loc->second; + typeInfo.marshalFunc = marshalFunc; + typeInfo.demarshalFunc = demarshalFunc; } -*/ diff --git a/libraries/script-engine/src/qtscript/ScriptEngineQtScript.h b/libraries/script-engine/src/qtscript/ScriptEngineQtScript.h index ff704c5ad8..78b71e37b4 100644 --- a/libraries/script-engine/src/qtscript/ScriptEngineQtScript.h +++ b/libraries/script-engine/src/qtscript/ScriptEngineQtScript.h @@ -382,7 +382,8 @@ signals: public: // not for public use, but I don't like how Qt strings this along with private friend functions virtual ScriptValuePointer create(int type, const void* ptr); virtual bool convert(const ScriptValuePointer& value, int type, void* ptr); - virtual void registerCustomType(int type, ScriptEngine::MarshalFunction mf, ScriptEngine::DemarshalFunction df, const ScriptValuePointer& prototype); + virtual void registerCustomType(int type, ScriptEngine::MarshalFunction marshalFunc, + ScriptEngine::DemarshalFunction demarshalFunc, const ScriptValuePointer& prototype); protected: // like `newFunction`, but allows mapping inline C++ lambdas with captures as callable QScriptValues @@ -403,6 +404,16 @@ protected: */ Q_INVOKABLE void executeOnScriptThread(std::function function, const Qt::ConnectionType& type = Qt::QueuedConnection ); + // store for handling custom type marshaling/demarshaling + struct CustomTypeInfo { + ScriptEngine::MarshalFunction marshalFunc; + ScriptEngine::DemarshalFunction demarshalFunc; + ScriptValuePointer prototype; + }; + typedef std::map TCustomTypeMap; + TCustomTypeMap _customTypes; + std::mutex _customTypeProtect; + QPointer _manager; ScriptValuePointer _nullValue;