summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorGiovanni Campagna <gcampagna@src.gnome.org>2011-12-16 18:38:40 +0100
committerJasper St. Pierre <jstpierre@mecheye.net>2012-02-03 17:45:29 -0500
commit1292ae26b0fdb02113f302264e7d75c8cfb6ff2b (patch)
tree18ffcd72989f425b32a8678feb90a0a06a53ed5b /modules
parent6ab0ac0143d26496c7a9b50470740506fa42f002 (diff)
downloadgjs-1292ae26b0fdb02113f302264e7d75c8cfb6ff2b.tar.gz
object: Make custom types have a custom JSClass
Use gjs_define_object_class to create a dynamic JSClass for the newly registered gtype, which doesn't have any introspection info.
Diffstat (limited to 'modules')
-rw-r--r--modules/overrides/GObject.js74
1 files changed, 55 insertions, 19 deletions
diff --git a/modules/overrides/GObject.js b/modules/overrides/GObject.js
index 0cb7d9b7..cd728e9a 100644
--- a/modules/overrides/GObject.js
+++ b/modules/overrides/GObject.js
@@ -29,47 +29,45 @@ const GObjectMeta = new Lang.Class({
Extends: Lang.Class,
_init: function(params) {
- if (!params.Extends)
- params.Extends = GObject.Object;
+ this.parent(params);
- if (!this._isValidClass(params.Extends))
- throw new TypeError('GObject.Class used with invalid base class (is ' + params.Extends.prototype + ')');
+ // retrieve all parameters and remove them from params before chaining
- this.parent(params);
+ let properties = params.Properties;
+ let signals = params.Signals;
+ let ifaces = params.Implements;
- Gi.register_type(params.Extends.prototype, this.prototype, params.Name);
+ delete params.Properties;
+ delete params.Signals;
+ delete params.Implements;
- if (params.Properties) {
- for (let prop in params.Properties) {
- Gi.register_property(this.prototype, params.Properties[prop]);
+ if (properties) {
+ for (let prop in properties) {
+ Gi.register_property(this.prototype, properties[prop]);
}
}
- if (params.Signals) {
- for (let signalName in params.Signals) {
- let obj = params.Signals[signalName];
+ if (signals) {
+ for (let signalName in signals) {
+ let obj = signals[signalName];
let flags = (obj.flags !== undefined) ? obj.flags : GObject.SignalFlags.RUN_FIRST;
let accumulator = (obj.accumulator !== undefined) ? obj.accumulator : GObject.AccumulatorType.NONE;
let rtype = (obj.return_type !== undefined) ? obj.return_type : GObject.TYPE_NONE;
let paramtypes = (obj.param_types !== undefined) ? obj.param_types : [];
try {
- obj.signal_id = Gi.signal_new(this.prototype, signal_name, flags, accumulator, rtype, paramtypes);
+ obj.signal_id = Gi.signal_new(this.prototype, signalName, flags, accumulator, rtype, paramtypes);
} catch(e) {
throw new TypeError('Invalid signal ' + signal_name + ': ' + e.message);
}
}
}
- if (params.Implements) {
- for (let i = 0; i < params.Implements.length; i++)
+ if (ifaces) {
+ for (let i = 0; i < ifaces.length; i++)
Gi.add_interface(this.prototype, ifaces[i]);
}
- delete params.Properties;
- delete params.Signals;
- delete params.Implements;
-
for (let prop in params) {
let value = this.prototype[prop];
if (typeof value === 'function') {
@@ -101,6 +99,44 @@ const GObjectMeta = new Lang.Class({
// will return false.
return proto == GObject.Object.prototype ||
proto instanceof GObject.Object;
+ },
+
+ // If we want an object with a custom JSClass, we can't just
+ // use a function. We have to use a custom constructor here.
+ _construct: function(params) {
+ if (!params.Name)
+ throw new TypeError("Classes require an explicit 'Name' parameter.");
+ let name = params.Name;
+
+ let gtypename;
+ if (params.GTypeName)
+ gtypename = params.GTypeName;
+ else
+ gtypename = 'Gjs_' + params.Name;
+
+ if (!params.Extends)
+ params.Extends = GObject.Object;
+ let parent = params.Extends;
+
+ if (!this._isValidClass(parent))
+ throw new TypeError('GObject.Class used with invalid base class (is ' + parent + ')');
+
+ let newClass = Gi.register_type(parent.prototype, gtypename);
+
+ // See Class.prototype._construct in lang.js for the reasoning
+ // behind this direct __proto__ set.
+ newClass.__proto__ = this.constructor.prototype;
+ newClass.__super__ = parent;
+
+ newClass._init.apply(newClass, arguments);
+
+ Object.defineProperty(newClass.prototype, '__metaclass__',
+ { writable: false,
+ configurable: false,
+ enumerable: false,
+ value: this.constructor });
+
+ return newClass;
}
});