The Programs of the Week We Put Our Face in the Phone
This Week’s Program: Sep 11 - Sep 15
Yo dawgs. I heard you like GObjects. So I put GObjects in your objects so you can Racket when you C.
I wrote a bunch of stuff this week! I had a little mini-light bulb moment and just started writing. Code, docs, all that stuff.
I think I’ve completed the documentation for
ffi/unsafe/introspection
. It’s been kind of painful writing this, as
I had to confront all the little flaws and inconsistencies in the
API. But the little light bulb moment I had, along with some more
mastery of Scribble led me to get over this hump. You can read the
documentation for this
module
here.
Here are some highlights from the commits this week that led to this final doc.
0ce0ad4ea996c0de8619e0bdade0988b976f2ed7
I update my Makefile
to run a slightly altered version of the raco
scribble
command:
raco scribble +m --html-tree 1 --redirect-main $(RACKET_DOCS) --dest-name $@ $<
This command now tells scribble to make a html-tree
with a depth of
1
- that is, instead of a single HTML document, make a directory
with one level of depth, and write it out to the destination directory
named $@
; for those unversed in Makefile quirks that means the thing
on the left side of the :
— the target, which in this case is
“docs”.
3045ffa87c4eacce60c731a6da77b7137927ae4f
Here’s the challenge: I want to bridge the GObject struct that I use
to represent instances with
the
racket/class
OOP
library. There are a lot of synergies that can be drawn from using the
latter. The question is how. After a bit of brooding and mulling, I
turn
to
structure type properties. Like
prop:cpointer
and prop:procedure
, structure type properties are
things that allow a structure type to behave a certain way. They’re a
bit like Interfaces (The concept. Not to be confused with,
uh,
interfaces). Instances
of a struct type that implement a structure type property conform to
certain behaviors. Like how the gi-function
struct type implements
the prop:procedure
property and so returns #t
to procedure?
.
make-struct-property
creates the prop:gobject
structure type
property, as well as functions to act as a predicate (gobject?
) and
retrieve the value of the property from the struct gobject-ref
. The
value of prop:gobject
should be a gtype-instance
or a function
that accepts the struct and returns a gtype-instance
. On the newly
renamed gobject-instance
and the gstruct
struct types, I implement
this prop with the function identity
. Now I can change a bunch of
contracts to accept gobject?
. Any thing that implements the
prop:gobject
property can be a GObject.
d98086b796311916f1d253459680a683a9282e2f
Now comes the bridge. First is gobject<%>
(the <%>
suffix is a convention for
a Racket interface). I create this with interface*
; this form
allows me to attach structure type properties to the interface. I add
prop:gobject
and look for a field on the object called pointer
for
the value of the property. Now, every object that implements
gobject<%>
can be used interchangeably with other gobjects. I also
create a base class that extends this interface, for convenience sake.
So the class gobject%
extends gobject<%>
with the property
prop:gobject
so that instances will respond #t
to gobject?
.
I am gobsmacked by the gobs of gobjects!
d083b34e2bb5ce9c1ac19647b385ea8160a9d6b9
Here’s some cute Scribble tricks:
- I pair
racketresult
withracketinput
(and learn aboutunsyntax
aka@#,
) together to make something that looks like a REPL interaction. - The
procedure
function will make content “look” like a Racket procedure: it wraps it like#<procedure:x>
. racketmodname
will automatically link a module path likeracket/class
to its documentation.
And there we have it. This feels like a good place to end this spike of work on documentation and GObject Introspection and move on to focusing on GStreamer specifically, using the new tools for OOP to make the ergonomics of that module real good.
👺 Mark