One more step along the Wayland#
Tue, 12 Mar 2013 13:57:03 +0000
Yesterday's lunchtime hacking was all about splitting the project into multiple files and getting it into git and onto Github - note that the mere fact of it being publically browsable does not imply that it will run, build, walk, make tea, perform any other useful function, or even forbear from exploding inside your computer and rendering the SSD to molten slag. Nor that I'm not still ashamed of it. It just keeps me slightly more honest.
Today I implemented enough of pack-message
to be able to recreate
the initial client->compositor message that we observed weston-info
send last week. Still taking extraordinary liberties with signed vs
unsigned longs, and plase note that all this code will work only on
little-endian machines (there are any big-endian machines left?).
Lessons, puzzles
Leiningen does not need you to list the source files in your repository individually: it finds them magically. I believed otherwise for a while, but it turned out (slightly embarrassingly) that I had a parenthesis in the wrong place. My working hypothesis is that it assumes there is one namespace for each file, and that any reference to a namespace it doesn't know about it can be satisfied by loading a file with that name.
If I type (in-ns 'psadan.core)
at the repl and that ns does not
include a (:refer-clojure)
form, I can't use the symbols in
clojure.core
at the repl. I have not observed a similar issue wrt
uses of clojure.core/foo
in core.clj itself, just at the repl.
atoms! An atom is dead simple, really - conceptually at least, if not
also under the hood: it's a wrapper for an object that lets you look
inside with deref
and lets you change what's inside with swap!
.
For each connection we use an atom holding a mapping from object ids
to the corresponding objects, which starts out holding the singleton
object for wl_display
and then needs to be updated each time we
generate an object locally and each time we learn of a new object from
the peer.
(defn open-connection [name] (let [s (cx.ath.matthew.unix.UnixSocket. name) in (. s getInputStream) out (. s getOutputStream) wl-display (global-object-factory) ] {:socket s :input in :output out :display wl-display :objects (atom (assoc {} 1 wl-display)) }))(defn remember-object [conn id object] ;; (swap r fn args...) gets the current value of the atom inside r, ;; which for the sake of argument we shall call oldval, then sets the atom ;; to the result of calling (fn oldval args...) (swap! (:objects conn) assoc id object) object)
(defn get-object [conn id] ;;
foo is another way to write (deref foo) (let [o (get
(:objects conn) id)] o))
I have probably not chosen the fastest possible way of building up the messages I plan to send, in terms of fiddling around sticking vectors of bytes together. Will worry about that later if it turns out to be a bottleneck (but suggestions are welcome).
There was not a lot of Wayland learning this time. In the next round
we shall be sending it the messages we have so lovingly composed from
whole cloth and see if it reacts the same way as it did when the same
bytes were sent from weston-info