cl-liballegro
cl-liballegro copied to clipboard
Simplify interfacing with Allegro foreign structs
This could make accessing slots of foreign structures much easier: https://common-lisp.net/project/cffi/manual/html_node/Foreign-Structure-Types.html#Foreign-Structure-Types
After trying to implement this, it might be a little heavy handed. Most of the Allegro5 structures are opaque so translation isn't needed for most structs. CFFI also already defaults to exploding structs to a plist with MEM-REF in which members are easily accessible with GETF. CFFI also has macros for accessing the foreign slots of the structures. I don't think there's any performance improvement to be found using structs over plists when the number elements aren't expected to be large.
It'd probably be better to add helper functions/macros that aren't intrusive and documentation on common patterns of interacting with CFFI.
I'll keep thinking for a bit if there is a use case. Maybe in the future when library can be improved in some way that this will come about again.
As a heavy user of cl-liballegro I might add that there's also the issue with convenience. Surely you can use CFFI utilities to access struct fields, but in that case e.g. even simplest accessing of al_event type to dispatch on it looks like
(cffi:foreign-slot-value event '(:union al:event) 'al::type)
which is like super-verbose compared to some theoretical helper like (al:event-type event)
.
(Although my knowledge of CFFI is inferior compared to yours, maybe I'm missing something and you can suggest something here.)
So anyway the idea to use lisp defstruct
's seems like a nice one to me.
My thoughts is the same on creating helper functions, just how to implement would differ so I'm interested in your experience as a user. Of the situations and resulting changes below, I was thinking of 1) but if you've come across 2) or 3) I'm down to implement whichever one.
For non-opaque structures you've come across do you...
1.) Simply read values?
New functions added
(al:event-type event)
is (cffi:foreign-slot-value event '(:union al:event) 'al::type)
2.) Find yourself wanting a DEFSTRUCT? New simple data structure added with basic accessors and setters Memory translation
3.) Find yourself wanting a DEFCLASS? New data structure added with accessors and setters Memory translation
I think as long as we leave performance questions out of consideration, the 1) approach would do just fine - if you're fine with manually writing bunch of accessors for every structure field, of course. DEFSTRUCT does that for you, but it'll also require writing custom foreign translation methods (which are, by the looks of it, are not that hard to implement, and have the nice property of improving performance which you've mentioned in #20). Anyways, if I'd be you, I think I'd go with 2) approach, just because I hate a lot of manual work :sweat_smile:
DEFCLASS, on the other hand, seems to be overkill because, again, performance reasons: DEFSTRUCT's field access compiles to one indirect MOV instruction, while DEFCLASS's field access compiles to the entire function call (SLOT-VALUE or similar).
#20 is actually in reference to this issue to optimize the overhead created by the memory translation from a foreign struct to a lisp struct rather than overall improvement in performance.
I hate a lot of manual work
Me too, this is where macros and/or a good text editor can dissolve a lot of it.
One of my worries was possible feature creep and imposing the overheard of managing a new structure, but getting an ok from a user opens up more possibilities to making higher level decisions in that case. I'll keep thinking of the options.
As a user there's going to be a simpler interface regardless of implementation, so no worries. Just keep making cool stuff! :smile:
As a user there's going to be a simpler interface regardless of implementation, so no worries. Just keep making cool stuff!
Thanks man, you too :slightly_smiling_face: