File indexing completed on 2025-01-05 04:26:52
0001 /**************************************************************************************** 0002 * Copyright (c) 2013 Anmol Ahuja <darthcodus@gmail.com> * 0003 * * 0004 * This program is free software; you can redistribute it and/or modify it under * 0005 * the terms of the GNU General Public License as published by the Free Software * 0006 * Foundation; either version 2 of the License, or (at your option) any later * 0007 * version. * 0008 * * 0009 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 0010 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 0011 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 0012 * * 0013 * You should have received a copy of the GNU General Public License along with * 0014 * this program. If not, see <http://www.gnu.org/licenses/>. * 0015 ****************************************************************************************/ 0016 0017 #ifndef AMAROKSCRIPT_SCRIPTING_DEFINES_H 0018 #define AMAROKSCRIPT_SCRIPTING_DEFINES_H 0019 0020 #include <QHash> 0021 #include <QObject> 0022 #include <QJSEngine> 0023 #include <QJSValue> 0024 #include <QJSValueIterator> 0025 0026 class QMetaEnum; 0027 0028 namespace AmarokScript 0029 { 0030 template <class type, class WrapperType> 0031 void fromScriptValue( const QJSValue &obj, type &object ) 0032 { 0033 const WrapperType *wrapper = dynamic_cast<WrapperType*>( obj.toQObject() ); 0034 if( wrapper ) 0035 object = wrapper->data(); 0036 else 0037 object = nullptr; 0038 } 0039 0040 template <class type, class WrapperType> 0041 QJSValue toScriptValue( QJSEngine *engine, type const &object ) 0042 { 0043 WrapperType *wrapper = new WrapperType( object ); 0044 return engine->newQObject( wrapper ); 0045 } 0046 0047 template <class Container> 0048 QJSValue toScriptArray( QJSEngine *engine, const Container &container ) 0049 { 0050 QJSValue scriptArray = engine->newArray(); 0051 typename Container::const_iterator begin = container.begin(); 0052 typename Container::const_iterator end = container.end(); 0053 typename Container::const_iterator it; 0054 for( it = begin; it != end; ++it ) 0055 scriptArray.setProperty( quint32(it - begin), engine->toScriptValue(*it) ); 0056 return scriptArray; 0057 } 0058 0059 template <class Container> 0060 void fromScriptArray( const QJSValue &value, Container &container ) 0061 { 0062 quint32 len = value.property( QStringLiteral("length") ).toUInt(); 0063 for( quint32 i = 0; i < len; ++i ) 0064 { 0065 QJSValue item = value.property( i ); 0066 typedef typename Container::value_type ContainerValue; 0067 container.push_back( qjsvalue_cast<ContainerValue>(item) ); 0068 } 0069 } 0070 0071 template <class Map> 0072 QJSValue toScriptMap( QJSEngine *engine, const Map &map ) 0073 { 0074 QJSValue scriptMap = engine->newObject(); 0075 for( typename Map::const_iterator it( map.begin() ); it != map.end(); ++it ) 0076 scriptMap.setProperty( it.key(), engine->toScriptValue( it.value() ) ); 0077 return scriptMap; 0078 } 0079 0080 template <class Map> 0081 void fromScriptMap( const QJSValue &value, Map &map ) 0082 { 0083 QJSValueIterator it( value ); 0084 while( it.hasNext() ) 0085 { 0086 it.next(); 0087 map[it.name()] = qjsvalue_cast<typename Map::mapped_type>( it.value() ); 0088 } 0089 } 0090 0091 /** 0092 * SCRIPTDOX _ 0093 */ 0094 class AmarokScriptEngine : public QJSEngine 0095 { 0096 Q_OBJECT 0097 0098 public: 0099 explicit AmarokScriptEngine( QObject *parent ); 0100 ~AmarokScriptEngine() override; 0101 0102 void setDeprecatedProperty( const QString &parent, const QString &name, const QJSValue &property ); 0103 // exposing the metaobject directly also exposes >900 other values 0104 QJSValue enumObject( const QMetaEnum &metaEnum ); 0105 0106 template <class T> 0107 void registerArrayType() 0108 { 0109 qRegisterMetaType<T>(); 0110 QMetaType::registerConverter<QJSValue,T>( [] (QJSValue scriptObj) { 0111 T arrayObj; 0112 fromScriptArray( scriptObj, arrayObj ); 0113 return arrayObj; 0114 }); 0115 QMetaType::registerConverter<T,QJSValue>( [this] (T arrayObj) { return toScriptArray( this, arrayObj ); } ); 0116 } 0117 template <class Map> 0118 void registerMapType() 0119 { 0120 qRegisterMetaType<Map>(); 0121 QMetaType::registerConverter<QJSValue,Map>( [] (QJSValue scriptObj) { 0122 Map mapObj; 0123 fromScriptMap( scriptObj, mapObj ); 0124 return mapObj; 0125 }); 0126 QMetaType::registerConverter<Map,QJSValue>( [this] (Map mapObj) { return toScriptMap( this, mapObj ); } ); 0127 } 0128 0129 // SCRIPTDOX exclude 0130 Q_INVOKABLE void invokableDeprecatedCall( const QString &call ); 0131 0132 /** 0133 * @param function The function to invoke after time @param time in milliseconds. 0134 * @param thisObject [Optional] The this object this function is invoked with. 0135 * @param args [Optional] An array containing arguments this function is to be invoked with. 0136 */ 0137 Q_INVOKABLE void setTimeout( const QJSValue &function, int time, 0138 const QJSValue &thisObject = QJSValue(), 0139 const QJSValue &args = QJSValue() ); 0140 0141 private Q_SLOTS: 0142 void slotTimeout(); 0143 0144 Q_SIGNALS: 0145 void deprecatedCall(const QString &); 0146 0147 private: 0148 const QString internalObject; 0149 QHash<QObject*, QJSValueList> m_callbacks; 0150 }; 0151 } 0152 0153 #endif // AMAROKSCRIPT_SCRIPTING_DEFINES_H