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
racketresultwithracketinput(and learn aboutunsyntaxaka@#,) together to make something that looks like a REPL interaction. - The
procedurefunction will make content “look” like a Racket procedure: it wraps it like#<procedure:x>. racketmodnamewill automatically link a module path likeracket/classto 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