util/src/script/api/qscriptclass.cpp
changeset 7 f7bc934e204c
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtScript module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL-ONLY$
       
    10 ** GNU Lesser General Public License Usage
       
    11 ** This file may be used under the terms of the GNU Lesser
       
    12 ** General Public License version 2.1 as published by the Free Software
       
    13 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    14 ** packaging of this file.  Please review the following information to
       
    15 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    16 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    17 **
       
    18 ** If you have questions regarding the use of this file, please contact
       
    19 ** Nokia at qt-info@nokia.com.
       
    20 ** $QT_END_LICENSE$
       
    21 **
       
    22 ****************************************************************************/
       
    23 
       
    24 #include "qscriptclass.h"
       
    25 #include "qscriptstring.h"
       
    26 
       
    27 /*!
       
    28   \since 4.4
       
    29   \class QScriptClass
       
    30 
       
    31   \brief The QScriptClass class provides an interface for defining custom behavior of (a class of) Qt Script objects.
       
    32 
       
    33   \ingroup script
       
    34   \mainclass
       
    35 
       
    36   The QScriptClass class defines an interface for handling various
       
    37   aspects of interaction with the Qt Script objects associated with
       
    38   the class. Such objects are created by calling
       
    39   QScriptEngine::newObject(), passing a pointer to the QScriptClass as
       
    40   argument.
       
    41 
       
    42   By subclassing QScriptClass, you can define precisely how access to
       
    43   properties of the objects that use your class is handled. This
       
    44   enables a fully dynamic handling of properties, e.g. it's more
       
    45   powerful than QScriptEngine::newQObject(). For example, you can use
       
    46   QScriptClass to implement array-type objects (i.e. objects that
       
    47   handle the \c{length} property, and properties whose names are valid
       
    48   array indexes, in a special way), or to implement a "live"
       
    49   (runtime-defined) proxy to an underlying object.
       
    50 
       
    51   If you just need to handle access to a set of properties that are
       
    52   known at the time an object is created (i.e. "semi-statically"), you
       
    53   might consider using QScriptValue::setProperty() to define
       
    54   getter/setter functions for the relevant properties, rather than
       
    55   subclassing QScriptClass.
       
    56 
       
    57   Reimplement queryProperty() to specify which properties are handled
       
    58   in a custom way by your script class (i.e. should be
       
    59   \bold{delegated} to the QScriptClass), and which properties should
       
    60   be handled just like normal Qt Script object properties.
       
    61 
       
    62   Reimplement property() and setProperty() to perform the actual
       
    63   access (read or write) to the properties that your class
       
    64   handles. Additionally, you can reimplement propertyFlags() to
       
    65   specify custom flags for your properties.
       
    66 
       
    67   Reimplement newIterator() to provide an iterator for objects of your
       
    68   custom class. This is only necessary if objects of your class can
       
    69   have custom properties that you want to be reported when an object
       
    70   is used together with the QScriptValueIterator class, or when an
       
    71   object is used in a for-in enumeration statement in a script.
       
    72 
       
    73   When implementing custom classes of objects, you typically use
       
    74   QScriptValue::setData() to store instance-specific data as part of
       
    75   object initialization; the data won't be accessible from scripts
       
    76   directly, but you can access it in e.g. your reimplementations of
       
    77   property() and setProperty() (by calling QScriptValue::data()) to
       
    78   perform custom processing.
       
    79 
       
    80   Reimplement prototype() to provide a custom prototype object for
       
    81   your script class.
       
    82 
       
    83   Reimplement supportsExtension() and extension() if your custom
       
    84   script class supports one or more of the extensions specified by the
       
    85   Extension enum.
       
    86 
       
    87   \sa QScriptClassPropertyIterator, QScriptEngine::newObject(), {Custom Script Class Example}
       
    88 */
       
    89 
       
    90 /*!
       
    91     \enum QScriptClass::Extension
       
    92 
       
    93     This enum specifies the possible extensions to a QScriptClass.
       
    94 
       
    95     \value Callable Instances of this class can be called as functions.
       
    96 
       
    97     \value HasInstance Instances of this class implement [[HasInstance]].
       
    98 
       
    99     \sa extension()
       
   100 */
       
   101 
       
   102 /*!
       
   103     \enum QScriptClass::QueryFlag
       
   104 
       
   105     This enum describes flags that are used to query a QScriptClass
       
   106     regarding how access to a property should be handled.
       
   107 
       
   108     \value HandlesReadAccess The QScriptClass handles read access to this property.
       
   109     \value HandlesWriteAccess The QScriptClass handles write access to this property.
       
   110 
       
   111     \sa queryProperty()
       
   112 */
       
   113 
       
   114 QT_BEGIN_NAMESPACE
       
   115 
       
   116 class QScriptClassPrivate
       
   117 {
       
   118     Q_DECLARE_PUBLIC(QScriptClass)
       
   119 public:
       
   120     QScriptClassPrivate() {}
       
   121     virtual ~QScriptClassPrivate() {}
       
   122 
       
   123     QScriptEngine *engine;
       
   124 
       
   125     QScriptClass *q_ptr;
       
   126 };
       
   127 
       
   128 /*!
       
   129   Constructs a QScriptClass object to be used in the given \a engine.
       
   130 
       
   131   The engine does not take ownership of the QScriptClass object.
       
   132 */
       
   133 QScriptClass::QScriptClass(QScriptEngine *engine)
       
   134     : d_ptr(new QScriptClassPrivate)
       
   135 {
       
   136     d_ptr->q_ptr = this;
       
   137     d_ptr->engine = engine;
       
   138 }
       
   139 
       
   140 /*!
       
   141   \internal
       
   142 */
       
   143 QScriptClass::QScriptClass(QScriptEngine *engine, QScriptClassPrivate &dd)
       
   144     : d_ptr(&dd)
       
   145 {
       
   146     d_ptr->q_ptr = this;
       
   147     d_ptr->engine = engine;
       
   148 }
       
   149 
       
   150 /*!
       
   151   Destroys the QScriptClass object.
       
   152 
       
   153   If a QScriptClass object is deleted before the associated engine(),
       
   154   any Qt Script objects using the QScriptClass will be "demoted" to
       
   155   normal Qt Script objects.
       
   156 */
       
   157 QScriptClass::~QScriptClass()
       
   158 {
       
   159 }
       
   160 
       
   161 /*!
       
   162   Returns the engine that this QScriptClass is associated with.
       
   163 */
       
   164 QScriptEngine *QScriptClass::engine() const
       
   165 {
       
   166     Q_D(const QScriptClass);
       
   167     return d->engine;
       
   168 }
       
   169 
       
   170 /*!
       
   171   Returns the object to be used as the prototype of new instances
       
   172   of this class (created with QScriptEngine::newObject()).
       
   173 
       
   174   The default implementation returns an invalid QScriptValue, meaning
       
   175   that the standard Object prototype will be used.  Reimplement this
       
   176   function to provide your own custom prototype.
       
   177 
       
   178   Typically you initialize your prototype object in the constructor of
       
   179   your class, then return it in this function.
       
   180 
       
   181   See the "Making Use of Prototype-Based Inheritance" section in the
       
   182   QtScript documentation for more information on how prototypes are
       
   183   used.
       
   184 */
       
   185 QScriptValue QScriptClass::prototype() const
       
   186 {
       
   187     return QScriptValue();
       
   188 }
       
   189 
       
   190 /*!
       
   191   Returns the name of the script class.
       
   192 
       
   193   Qt Script uses this name to generate a default string representation
       
   194   of objects in case you do not provide a toString function.
       
   195 
       
   196   The default implementation returns a null string.
       
   197 */
       
   198 QString QScriptClass::name() const
       
   199 {
       
   200     return QString();
       
   201 }
       
   202 
       
   203 /*!
       
   204   Queries this script class for how access to the property with the
       
   205   given \a name of the given \a object should be handled. The given \a
       
   206   flags specify the aspects of interest. This function should return a
       
   207   subset of \a flags to indicate which aspects of property access
       
   208   should be further handled by the script class.
       
   209 
       
   210   For example, if the \a flags contain HandlesReadAccess, and you
       
   211   would like your class to handle the reading of the property (through
       
   212   the property() function), the returned flags should include
       
   213   HandlesReadAccess. If the returned flags do not contain
       
   214   HandlesReadAccess, the property will be handled as a normal script
       
   215   object property.
       
   216 
       
   217   You can optionally use the \a id argument to store a value that will
       
   218   subsequently be passed on to functions such as property() and
       
   219   setProperty().
       
   220 
       
   221   The default implementation of this function returns 0.
       
   222 
       
   223   Note: This function is only called if the given property isn't
       
   224   already a normal property of the object. For example, say you
       
   225   advertise that you want to handle read access to property \c{foo},
       
   226   but not write access; if \c{foo} is then assigned a value, it will
       
   227   become a normal script object property, and subsequently you will no
       
   228   longer be queried regarding read access to \c{foo}.
       
   229 
       
   230   \sa property()
       
   231 */
       
   232 QScriptClass::QueryFlags QScriptClass::queryProperty(
       
   233     const QScriptValue &object, const QScriptString &name,
       
   234     QueryFlags flags, uint *id)
       
   235 {
       
   236     Q_UNUSED(object);
       
   237     Q_UNUSED(name);
       
   238     Q_UNUSED(flags);
       
   239     Q_UNUSED(id);
       
   240     return 0;
       
   241 }
       
   242 
       
   243 /*!
       
   244   Returns the value of the property with the given \a name of the given
       
   245   \a object.
       
   246 
       
   247   The \a id argument is only useful if you assigned a value to it in
       
   248   queryProperty().
       
   249 
       
   250   The default implementation does nothing and returns an invalid QScriptValue.
       
   251 
       
   252   \sa setProperty(), propertyFlags()
       
   253 */
       
   254 QScriptValue QScriptClass::property(const QScriptValue &object,
       
   255                                     const QScriptString &name, uint id)
       
   256 {
       
   257     Q_UNUSED(object);
       
   258     Q_UNUSED(name);
       
   259     Q_UNUSED(id);
       
   260     return QScriptValue();
       
   261 }
       
   262 
       
   263 /*!
       
   264   Returns the flags of the property with the given \a name of the given
       
   265   \a object.
       
   266 
       
   267   The \a id argument is only useful if you assigned a value to it in
       
   268   queryProperty().
       
   269 
       
   270   The default implementation returns 0.
       
   271 
       
   272   \sa property()
       
   273 */
       
   274 QScriptValue::PropertyFlags QScriptClass::propertyFlags(
       
   275     const QScriptValue &object, const QScriptString &name, uint id)
       
   276 {
       
   277     Q_UNUSED(object);
       
   278     Q_UNUSED(name);
       
   279     Q_UNUSED(id);
       
   280     return 0;
       
   281 }
       
   282 
       
   283 /*!
       
   284   Sets the property with the given \a name of the given \a object to
       
   285   the given \a value.
       
   286 
       
   287   The \a id argument is only useful if you assigned a value to it in
       
   288   queryProperty().
       
   289 
       
   290   The default implementation does nothing.
       
   291 
       
   292   An invalid \a value represents a request to remove the property.
       
   293 
       
   294   \sa property()
       
   295 */
       
   296 void QScriptClass::setProperty(QScriptValue &object, const QScriptString &name,
       
   297                                uint id, const QScriptValue &value)
       
   298 {
       
   299     Q_UNUSED(object);
       
   300     Q_UNUSED(name);
       
   301     Q_UNUSED(id);
       
   302     Q_UNUSED(value);
       
   303 }
       
   304 
       
   305 /*!
       
   306   Returns an iterator for traversing custom properties of the given \a
       
   307   object.
       
   308 
       
   309   The default implementation returns 0, meaning that there are no
       
   310   custom properties to traverse.
       
   311 
       
   312   Reimplement this function if objects of your script class can have
       
   313   one or more custom properties (e.g. those reported to be handled by
       
   314   queryProperty()) that you want to appear when an object's properties
       
   315   are enumerated (e.g. by a for-in statement in a script).
       
   316 
       
   317   Qt Script takes ownership of the new iterator object.
       
   318 
       
   319   \sa QScriptValueIterator
       
   320 */
       
   321 QScriptClassPropertyIterator *QScriptClass::newIterator(const QScriptValue &object)
       
   322 {
       
   323     Q_UNUSED(object);
       
   324     return 0;
       
   325 }
       
   326 
       
   327 /*!
       
   328   Returns true if the QScriptClass supports the given \a extension;
       
   329   otherwise, false is returned. By default, no extensions
       
   330   are supported.
       
   331 
       
   332   Reimplement this function to indicate which extensions your custom
       
   333   class supports.
       
   334 
       
   335   \sa extension()
       
   336 */
       
   337 bool QScriptClass::supportsExtension(Extension extension) const
       
   338 {
       
   339     Q_UNUSED(extension);
       
   340     return false;
       
   341 }
       
   342 
       
   343 /*!
       
   344   This virtual function can be reimplemented in a QScriptClass
       
   345   subclass to provide support for extensions. The optional \a argument
       
   346   can be provided as input to the \a extension; the result must be
       
   347   returned in the form of a QVariant. You can call supportsExtension()
       
   348   to check if an extension is supported by the QScriptClass.  By
       
   349   default, no extensions are supported, and this function returns an
       
   350   invalid QVariant.
       
   351 
       
   352   If you implement the Callable extension, Qt Script will call this
       
   353   function when an instance of your class is called as a function
       
   354   (e.g. from a script or using QScriptValue::call()).  The \a argument
       
   355   will contain a pointer to the QScriptContext that represents the
       
   356   function call, and you should return a QVariant that holds the
       
   357   result of the function call. In the following example the sum of the
       
   358   arguments to the script function are added up and returned:
       
   359 
       
   360   \snippet doc/src/snippets/code/src_script_qscriptclass.cpp 0
       
   361 
       
   362   If you implement the HasInstance extension, Qt Script will call this
       
   363   function as part of evaluating the \c{instanceof} operator, as
       
   364   described in ECMA-262 Section 11.8.6. The \a argument is a
       
   365   QScriptValueList containing two items: The first item is the object
       
   366   that HasInstance is being applied to (an instance of your class),
       
   367   and the second item can be any value. extension() should return true
       
   368   if the value delegates behavior to the object, false otherwise.
       
   369 
       
   370   \sa supportsExtension()
       
   371 */
       
   372 QVariant QScriptClass::extension(Extension extension, const QVariant &argument)
       
   373 {
       
   374     Q_UNUSED(extension);
       
   375     Q_UNUSED(argument);
       
   376     return QVariant();
       
   377 }
       
   378 
       
   379 QT_END_NAMESPACE