[Kde-bindings] KDE/kdelibs/kparts
Maks Orlovich
maksim at kde.org
Sun Jun 20 21:38:07 UTC 2010
SVN commit 1140507 by orlovich:
- Adjust this for the refined refcounting protocol based on
feedback --- both in comments and the bridge.
- Add some helpers for operations that will be common for
client code with this refcounting protocol
- Remove DBus marshallers. I thought it will have at least 2 clients,
but it seems like it'll be 0, so it would be wrong to keep them in.
CCMAIL: kde-bindings at kde.org
M +39 -68 scriptableextension.cpp
M +27 -28 scriptableextension.h
--- trunk/KDE/kdelibs/kparts/scriptableextension.cpp #1140506:1140507
@@ -21,7 +21,6 @@
#include "scriptableextension_p.h"
#include <kglobal.h>
#include <kdebug.h>
-#include <QDBusMetaType>
namespace KParts {
@@ -34,9 +33,7 @@
ScriptableExtension::ScriptableExtension(QObject* parent):
QObject(parent), d(new ScriptableExtensionPrivate)
-{
- registerDBusTypes();
-}
+{}
ScriptableExtension::~ScriptableExtension()
{
@@ -195,11 +192,35 @@
Q_UNUSED(objId);
}
+QVariant ScriptableExtension::acquireValue(const QVariant& v)
+{
+ if (v.canConvert<Object>()) {
+ Object o = v.value<Object>();
+ o.owner->acquire(o.objId);
+ } else if (v.canConvert<FunctionRef>()) {
+ FunctionRef fr = v.value<FunctionRef>();
+ fr.base.owner->acquire(fr.base.objId);
+ }
+ return v;
+}
+
void ScriptableExtension::release(quint64 objId)
{
Q_UNUSED(objId);
}
+QVariant ScriptableExtension::releaseValue(const QVariant& v)
+{
+ if (v.canConvert<Object>()) {
+ Object o = v.value<Object>();
+ o.owner->release(o.objId);
+ } else if (v.canConvert<FunctionRef>()) {
+ FunctionRef fr = v.value<FunctionRef>();
+ fr.base.owner->release(fr.base.objId);
+ }
+ return v;
+}
+
// LiveConnectExtension -> ScriptableExtension adapter. We use
// lc object IDs as our own object IDs.
// ----------------------------------------------------------------------------
@@ -215,13 +236,15 @@
QVariant ScriptableLiveConnectExtension::rootObject()
{
// Plugin root is always LC object #0.
- return QVariant::fromValue(ScriptableExtension::Object(this, 0));
+ return acquireValue(QVariant::fromValue(ScriptableExtension::Object(this, 0)));
}
bool ScriptableLiveConnectExtension::hasProperty(ScriptableExtension*, quint64 objId, const QString& propName)
{
QVariant val = get(0, objId, propName);
- return !val.canConvert<ScriptableExtension::Exception>();
+ bool ok = !val.canConvert<ScriptableExtension::Exception>();
+ releaseValue(val);
+ return ok;
}
// Note that since we wrap around a plugin, and do not implement the browser,
@@ -242,7 +265,7 @@
unsigned long retObjId;
QString retVal;
if (wrapee->call((unsigned long)o, f, qargs, retType, retObjId, retVal)) {
- return fromLC(QString(), retType, retObjId, retVal);
+ return acquireValue(fromLC(QString(), retType, retObjId, retVal));
} else {
return unimplemented();
}
@@ -255,7 +278,7 @@
unsigned long retObjId;
QString retVal;
if (wrapee->get((unsigned long)objId, propName, retType, retObjId, retVal)) {
- return fromLC(propName, retType, retObjId, retVal);
+ return acquireValue(fromLC(propName, retType, retObjId, retVal));
} else {
// exception signals failure. ### inellegant
return unimplemented();
@@ -364,6 +387,7 @@
// We want to evaluate in the enclosure's context.
QVariant enclosure = enclosingObject();
if (!enclosure.canConvert<Object>()) {
+ releaseValue(enclosure);
kDebug(1000) << "No enclosure, can't evaluate";
return;
}
@@ -371,6 +395,7 @@
Object enclosureObj = enclosure.value<Object>();
if (!host()->isScriptLanguageSupported(ECMAScript)) {
+ releaseValue(enclosure);
kDebug(1000) << "Host can't evaluate ECMAScript";
}
@@ -397,8 +422,12 @@
kDebug(1000) << script;
- // Ask host to evaluate.
- host()->evaluateScript(this, enclosureObj.objId, script);
+ // Ask host to evaluate.. (unfortunately, we can't do anything with the result,
+ // but anything that uses this interface isn't expective one in the first place)
+ QVariant result = host()->evaluateScript(this, enclosureObj.objId, script);
+
+ releaseValue(result);
+ releaseValue(enclosure);
}
// hash functions
@@ -417,65 +446,7 @@
} // namespace KParts
-// DBus stuff
-// ----------------------------------------------------------------------------
-void KParts::ScriptableExtension::registerDBusTypes()
-{
- qDBusRegisterMetaType<Null>();
- qDBusRegisterMetaType<Undefined>();
- qDBusRegisterMetaType<Exception>();
-}
-KPARTS_EXPORT const QDBusArgument& operator<<(QDBusArgument& arg,
- const KParts::ScriptableExtension::Null&)
-{
- arg.beginStructure();
- arg.endStructure();
- return arg;
-}
-
-KPARTS_EXPORT const QDBusArgument& operator>>(const QDBusArgument& arg,
- KParts::ScriptableExtension::Null&)
-{
- arg.beginStructure();
- arg.endStructure();
- return arg;
-}
-
-KPARTS_EXPORT const QDBusArgument& operator<<(QDBusArgument& arg,
- const KParts::ScriptableExtension::Undefined&)
-{
- arg.beginStructure();
- arg.endStructure();
- return arg;
-}
-
-KPARTS_EXPORT const QDBusArgument& operator>>(const QDBusArgument& arg,
- KParts::ScriptableExtension::Undefined&)
-{
- arg.beginStructure();
- arg.endStructure();
- return arg;
-}
-
-KPARTS_EXPORT const QDBusArgument& operator<<(QDBusArgument& arg,
- const KParts::ScriptableExtension::Exception& e)
-{
- arg.beginStructure();
- arg << e.message;
- arg.endStructure();
- return arg;
-}
-
-KPARTS_EXPORT const QDBusArgument& operator>>(const QDBusArgument& arg,
- KParts::ScriptableExtension::Exception& e)
-{
- arg.beginStructure();
- arg >> e.message;
- arg.endStructure();
- return arg;
-}
-
#include "scriptableextension.moc"
#include "scriptableextension_p.moc"
// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on;
--- trunk/KDE/kdelibs/kparts/scriptableextension.h #1140506:1140507
@@ -25,7 +25,6 @@
#include <QObject>
#include <QVariant>
#include <kparts/part.h>
-#include <QDBusArgument>
namespace KParts {
@@ -56,10 +55,6 @@
* \li @ref Exception
* \li @ref Object
* \li @ref FunctionRef
- *
- * All of these other than Object and FunctionRef also provide DBus marshallers.
- * These are registered when ScriptableExtension::registerDBusTypes()
- * is called, which is in particular done by ScriptableExtension constructor.
*/
/// Corresponds to 'null' in JavaScript
@@ -82,9 +77,17 @@
/// Objects are abstracted away as a pair of the ScriptableExtension
/// the performs operations on it, and an implementation-specific Id,
- /// which gets passed to the extension's methods. If you store a reference to
- /// an object, you should use its owner's @ref acquire and @ref release
- /// methods to update its count of external references (which starts at 0)
+ /// which gets passed to the extension's methods.
+ ///
+ /// Objects are reference-counted, with the following protocol:
+ /// 1) Return values from methods, rootObject(), enclosingObject(),
+ /// and get() are already acquired by the producer, so the consumer
+ /// should release them when done.
+ /// 2) During a call, the caller guarantees that all the arguments
+ /// will be live for the calls duration, but the callee must
+ /// acquire them if it stores it for longer than that.
+ ///
+ /// @see acquire, acquireValue, release, releaseValue
struct Object {
ScriptableExtension* owner;
quint64 objId;
@@ -131,13 +134,6 @@
static ScriptableExtension* adapterFromLiveConnect(QObject* parentObj,
LiveConnectExtension* oldApi);
- /**
- * Registers dbus encodings of Null, Undefined, and Exception.
- * This is called by the ScriptableExtension constructor, so you
- * likely will not need to do so yourself
- */
- static void registerDBusTypes();
-
//@}
@@ -273,10 +269,26 @@
virtual void acquire(quint64 objid);
/**
+ Helper that calls @ref acquire on any object or function reference base
+ stored in @p v.
+
+ @return a copy of the passed in value
+ */
+ static QVariant acquireValue(const QVariant& v);
+
+ /**
decreases reference count of object @p objId
*/
virtual void release(quint64 objid);
+ /**
+ Helper that calls @ref release on any object or function reference base
+ stored in @p v.
+
+ @return a copy of the passed in value
+ */
+ static QVariant releaseValue(const QVariant& v);
+
//@}
private:
/**
@@ -301,19 +313,6 @@
Q_DECLARE_METATYPE(KParts::ScriptableExtension::Object)
Q_DECLARE_METATYPE(KParts::ScriptableExtension::FunctionRef)
-KPARTS_EXPORT const QDBusArgument& operator<<(QDBusArgument& argument,
- const KParts::ScriptableExtension::Null& n);
-KPARTS_EXPORT const QDBusArgument& operator>>(const QDBusArgument& argument,
- KParts::ScriptableExtension::Null& n);
-KPARTS_EXPORT const QDBusArgument& operator<<(QDBusArgument& argument,
- const KParts::ScriptableExtension::Undefined& u);
-KPARTS_EXPORT const QDBusArgument& operator>>(const QDBusArgument& argument,
- KParts::ScriptableExtension::Undefined& u);
-KPARTS_EXPORT const QDBusArgument& operator<<(QDBusArgument& argument,
- const KParts::ScriptableExtension::Exception& e);
-KPARTS_EXPORT const QDBusArgument& operator>>(const QDBusArgument& argument,
- KParts::ScriptableExtension::Exception& e);
-
#endif
// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on;
More information about the Kde-bindings
mailing list