[m-users.] Refactoring Mercury/C FFi code
emacstheviking
objitsu at gmail.com
Mon Jul 15 08:08:13 AEST 2019
I apologise for the long code at the end but I felt it was necessary to
fully ask my question.
My SDL2 wrapper is progressing nicely, I can draw lines, rectangles, filled
rectangles and load and render textures so far all without issue
but....boiler plate.
For example. SDL_RenderCopy can be passed either a NULL or an &SDL_Rect to
indicate the source and destination rectangles from the source texture and
destination respectively allowing sprite sheets etc or image scaling to be
performed.
However, with my limited knowledge I have only so far produced the code
shown at the end and to be perfectly honest I think it stinks and is
riddled with boiler plate. My question then is what would be "the best way"
to handle this case. With two rectangles I have had to create four
predicates, with three it would be 8 etc etc and it feels like there is a
better way.
I have seen code that creates mercury predaites then exportds them so they
can be called from "C" but I don't yet fully understand that as the code I
read (https://github.com/FlyingJester/SDL2.m/blob/master/sdl2.m) is a bit
over my head for the moment!
This also comes back to my previous question about being able to use
SDL_Rect as a foreign type etc. From what I have learned so far I know that
parameters are passed in as MR_Word sized values so would it be safe for
example to cast an sdl_rect() declared as:
*:- type sdl_rect ---> sdl_rect(x::int, y::int, w::int, h::int).*
*typedef struct SDL_Rect{ int x, y; int w, h;} SDL_Rect;*
to an SDL_Rect which has the same size and shape?!?!?!?! These are thing
things holding me back right now.
Thanks,
Sean.
---> the code
*:- pred sdl_rendercopy(sdl_renderer::in, sdl_texture::in,
maybe(sdl_rect)::in, maybe(sdl_rect)::in, io::di, io::uo) is det.*
% SDL_RenderCopy
sdl_rendercopy(Rnd, Tex, no, no, !IO) :-
sdl_rendercopy_no_no(Rnd, Tex, !IO).
sdl_rendercopy(Rnd, Tex, no, yes(Dst), !IO) :-
sdl_rendercopy_no_yes(Rnd, Tex, Dst^x, Dst^y, Dst^w, Dst^h, !IO).
sdl_rendercopy(Rnd, Tex, yes(Src), no, !IO) :-
sdl_rendercopy_yes_no(Rnd, Tex, Src^x, Src^y, Src^w, Src^h, !IO).
sdl_rendercopy(Rnd, Tex, yes(Src), yes(Dst), !IO) :-
sdl_rendercopy_yes_yes(Rnd, Tex,
Src^x, Src^y, Src^w, Src^h,
Dst^x, Dst^y, Dst^w, Dst^h,
!IO).
*:- pred sdl_rendercopy_no_no(sdl_renderer::in, sdl_texture::in, io::di,
io::uo) is det.:*- pragma foreign_proc("C",
sdl_rendercopy_no_no(Rnd::in, Tex::in, _IO0::di, _IO::uo),
[promise_pure,will_not_call_mercury,does_not_affect_liveness],
"SDL_RenderCopy(Rnd, Tex, NULL, NULL);").
*:- pred sdl_rendercopy_no_yes(sdl_renderer::in, sdl_texture::in, int::in,
int::in, int::in, int::in, io::di, io::uo) is det.*:- pragma
foreign_proc("C",
sdl_rendercopy_no_yes(Rnd::in, Tex::in, X::in, Y::in, W::in, H::in,
_IO0::di, _IO::uo),
[promise_pure,will_not_call_mercury,does_not_affect_liveness],
"SDL_Rect rDst;
rDst.x = (Uint32)X;
rDst.y = (Uint32)Y;
rDst.w = (Uint32)W;
rDst.h = (Uint32)H;
SDL_RenderCopy(Rnd, Tex, NULL, &rDst);").
*:- pred sdl_rendercopy_yes_no(sdl_renderer::in, sdl_texture::in, int::in,
int::in, int::in, int::in, io::di, io::uo) is det.*:- pragma
foreign_proc("C",
sdl_rendercopy_yes_no(Rnd::in, Tex::in, X::in, Y::in, W::in, H::in,
_IO0::di, _IO::uo),
[promise_pure,will_not_call_mercury,does_not_affect_liveness],
"SDL_Rect rSrc;
rSrc.x = (Uint32)X;
rSrc.y = (Uint32)Y;
rSrc.w = (Uint32)W;
rSrc.h = (Uint32)H;
SDL_RenderCopy(Rnd, Tex, &rSrc, NULL);").
*:- pred sdl_rendercopy_yes_yes(sdl_renderer::in, sdl_texture::in, int::in,
int::in, int::in, int::in,int::in, int::in, int::in, int::in, io::di,
io::uo) is det.*:- pragma foreign_proc("C",
sdl_rendercopy_yes_yes(Rnd::in, Tex::in,
XS::in, YS::in, WS::in, HS::in,
XD::in, YD::in, WD::in, HD::in,
_IO0::di, _IO::uo),
[promise_pure,will_not_call_mercury,does_not_affect_liveness],
"SDL_Rect rDst;
SDL_Rect rSrc;
rSrc.x = (Uint32)XS;
rSrc.y = (Uint32)YS;
rSrc.w = (Uint32)WS;
rSrc.h = (Uint32)HS;
rDst.x = (Uint32)XD;
rDst.y = (Uint32)YD;
rDst.w = (Uint32)WD;
rDst.h = (Uint32)HD;
SDL_RenderCopy(Rnd, Tex, &rSrc, &rDst);").
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurylang.org/archives/users/attachments/20190714/35c053f6/attachment-0001.html>
More information about the users
mailing list