Structs in gobject-introspection + Javascript
Owen Taylor <[email protected]> Sat, 08 Nov 2008 17:07:04 -0500
| Newsgroups | gmane.comp.gnome.language-bindings |
|---|---|
| Message-ID | <[email protected]> |
[ Sorry for the long cc: list. Do we need [email protected]? ] So, I've gotten a little annoyed recently at the lack of struct support in gjs. So, I was trying to think through how exactly the mapping between gobject-introspection structures and Javascript should work. Here's what I came up with. An actual attempt to implement structures would likely run into issues I haven't thought of here. - Owen ==== 1. Structs are supported if they are: - Have no pointer fields. (They can have nested structures{1} and union fields). Call these simple structures. Or: - Are registered as boxed types with GObject Note that some structures, such as GdkRectangle or GdkColor are both boxed and simple structures. {2} 2. When a structure is passed from C to Javascript, there is an implicit copy made. Thus: var some_global; widget.connect('size-allocate', function(widget, allocation) { some_global = allocation; }); Is safe. 3. In a callback that has an out parameter, there is a copy made on when the function exits (no copy is made if the function throws an exception.) Thus: widget.connect('size-request', function(widget, request) { request.width = 100; request.height = 50; }); Is safe. For an in/out parameter, copies are made both ways. [1] 4. In any place a a simple structure is expected, any other object that has properties for all the objects fields can be used. So, you can do: window.invalidate_rect({ x: 5, y: 5, width: 100, height: 100 }, true); 5a. Simple structures support a "copy constructor" that takes another object with the right fields. 5b. Boxed structs that are not simple structs have a copy constructor corresponding to the boxed copy function. 5c. There may a constructor declared in the introspection information. This is "overloaded" based on argument type with the copy constructor. The copy constructor takes precedence in ambiguous situations. 6. Every structure object has methods: copy() - returns a new object that is a copy of this object [2] set() - assigns a value of another object of the same type to the object [3] So, equivalent to the size-request example above you can do: widget.connect('size-request', function(widget, request) { request.set({ width: 100, height: 50 }); }); 7. Any field declared in the introspection information can be read as an object property. 8. Any field in a simple structure can be set by assignment to an object property. Fields in non-simple structures cannot be set. {3} 9. Assignment to a nested structure has the effect of copying the structure passed in. So given: struct B { int x; }; struct A { B b; }; === a = new A({ b: { x: 1 } }); b = new B({ x: 2 }); a.b = b a.b.x = 3 log(b.x) === Gives 2, not 3. Mapping concerns ================ [1] Or is it better to do out structure parameters like you would do out integer parameters - as a return value or an array of return values? I generally like the suggested method better because it corresponds to C code and to some of the existing GObject language bindings. [2] Is the copy() method necessary? It duplicates the copy constructor described above. [3] The set() method is needed for for certain out and in/out parameters, like the 'pos' argument to GtkTextView::insert-text. It isn't necessary if we did out parameters as in [1]. gobject-introspection concerns: =============================== {1} There is no representation in the .gir format that distinguishes a nested structure from a pointer to a nested structure, other than c:type. The typelib format is OK. {2} There is no way to tell distinguish a a simple structure registered as a boxed from a boxed object with internal private state. {3} There may be examples where setting non-pointer fields on non-simple structures would be useful, I think that would need to be marked in the introspection information if it comes up in practice. _______________________________________________ language-bindings mailing list [email protected] http://mail.gnome.org/mailman/listinfo/language-bindings