From: Martin Baulig <martin@home-of-linux.org>
To: guile-gtk <guile-gtk@sourceware.cygnus.com>
Cc: gnome-hackers@gnome.org
Subject: Announcing guile-gobject
Date: Thu, 05 Apr 2001 05:28:00 -0000 [thread overview]
Message-ID: <86y9tfa5qx.fsf_-_@einstein.home-of-linux.org> (raw)
In-Reply-To: <3ACC4BFB.CBEA2943@altosw.be>
Hi guys,
about a week ago I started some little hacking project because I felt
like I must hack something to feel good.
The result of this hacking week is now in GNOME CVS in the `guile-gobject'
module, right in time before GUADEC ...
Unfortunately, I don't have much time to write what guile-gobject is and
how it is different from guile-gtk since I need to leave to GUADEC soon,
but maybe we can have some little BOF about it there.
It's basically a new set of scheme / guile bindings for GNOME 2.0 which is
based on gobject. The main difference to guile-gtk is that it is using goops
and g-wrap and that it's based on gobject.
Basically, with guile-gobject you don't need any C compiled glue code to
access arbitrary GObject's and other glib/gobject based types such as
GEnum and GFlags. This all works with very little C code, most of the stuff
is done in scheme.
The other big advantage of guile-gobject is that it's a two-way wrapper;
you cannot only access a GObject which is defined in some C library from
Guile, you can also write your own GObjects in Guile and access them from C.
This code is still very experimental and unfinished, I just hacked on it for
about a week or so.
Here's some example code:
====
(use-modules (gobject gobject) (oop goops))
;; Assuming your C code has a GObject `Foo' and there's
;; a C function foo_get_type ().
(define-class <foo> (<gobject>))
(define foo (make <foo>))
;; Assuming there's a GObject `Bar' and a scheme function
;; (bar-get-type) returning Bar's GType.
(define bar (make <gobject> #:type (bar-get-type)))
;; Derive `Bar', creating your own `SuperBar' GObject in scheme
(define super-bar-type (g-type-create-object (bar-get-type) 'SuperBar '()))
(define super-bar-class (g-object-class-from-type super-bar-type))
(define super-bar (make <gobject> #:type super-bar-type))
;; Assuming `Foo' has a boolean `foo property
(g-object-get-property foo 'foo)
(g-object-set-property foo 'foo #t)
;; Assuming `Foo' has a signal 'hello' which takes a boolean and a float
;; argument and returns a long
(define retval (g-object-signal-emit foo 'hello #t 3.45))
(display retval) (newline) ;; this will be a long
;; Now let's connect something to the 'hello' signal:
(g-object-signal-connect foo 'hello
(lambda (object a b)
(display (list "HELLO" object a b "END")) (newline)
305))
;; Add a new boolean `super' property to the `SuperBar' GObject
(g-object-class-install-property super-bar-class
(make <gparam-spec-wrapper> #:name 'super #:value-type g-type-boolean))
====
So all glue code that's needed is for C functions, but the whole object
management can be done directly in Scheme. The following isn't finished
yet, but basically it'll be possible to do something like this:
====
;; Assume you have a C function `void test_func (GObject *object)' and its
;; scheme wrapper, you can create your own GObject and pass it to this
;; function
(define super-bar-type (g-type-create-object g-type-object 'SuperBar '()))
(define super-bar-class (g-object-class-from-type super-bar-type))
(define super-bar-get-type (lambda () super-bar-type))
;; This will assume there is a `super-bar-get-type' function
(define-class <super-bar> (<gobject>))
;; You can also say
(define-class <super-bar> (<gobject>) #:type super-bar-type)
;; This create a new instance of `SuperBar'.
(define super-bar (make <super-bar>))
;; You can also use this without creating a class:
(define super-bar (make <gobject> #:type super-bar-type))
;; (test-func) takes a GObject, so let's pass it our `SuperBar':
(test-func super-bar)
====
For the C part, I also had a new and much simpler idea how to wrap a
GObject and how to do the reference counting.
For each GObject, there's a GObjectWrapper:
===
struct _GuileGObject {
int ref_count;
gboolean floating;
size_t size;
void (*finalize) (gpointer);
SCM scm_class;
};
struct _GObjectWrapper {
GuileGObject guile;
GObject *object;
};
===
This wrapper is created on-the-fly when a GObject is about to be passed to
Scheme code and it'll only stay around as long as it's needed:
* when a GObject is passed to Scheme code, a new GObjectWrapper object is
created and the GObject ref'ed.
* the GObjectWrapper is freeded during garbage collecting which will cause
the GObject to be unref'ed.
So when we create a new GObject, it'll be "owned" by its GObjectWrapper and
the unref during garbage collecting will cause it to be destroyed.
* when we call a C function from scheme which takes a GObject, we pass the
GObject itself to C and not its Scheme wrapper; the GObject doesn't know
anything about its GObjectWrapper so that the wrapper can safely be freed
during garbage collecting even if the GObject is still in use (since the C
code must ref the object anyways because it's owned by the caller).
This also works when we create our own GObjects in scheme:
* (g-type-create-object) basically calls g_type_register_static() to register
a new type for the derived object (with the same class and instance sizes
as its parent type) and uses g_type_set_qdata() to assign some per-class
data with the new type. It provides a custom class_init function for the new
type which will override the `get_property', `set_property' etc. functions.
--
Martin Baulig
martin@gnome.org (private)
baulig@suse.de (work)
next prev parent reply other threads:[~2001-04-05 5:28 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2001-04-04 5:50 gtk: toolbar space style David Pirotte
[not found] ` <986400337.1886.1.camel@soleil>
2001-04-04 12:40 ` David Pirotte
[not found] ` <986428047.18191.5.camel@soleil>
2001-04-05 2:41 ` David Pirotte
2001-04-05 5:28 ` Martin Baulig [this message]
2001-04-09 9:25 ` Announcing guile-gobject Marius Vollmer
[not found] ` <986508739.1535.0.camel@soleil>
2001-04-06 10:03 ` gtk: toolbar space style David Pirotte
2001-04-04 12:41 ` David Pirotte
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=86y9tfa5qx.fsf_-_@einstein.home-of-linux.org \
--to=martin@home-of-linux.org \
--cc=gnome-hackers@gnome.org \
--cc=guile-gtk@sourceware.cygnus.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).