<div dir="ltr">Julien, thank you also for that reply. I have made those changes in my module and it's working as I wanted it to.<div><a class="gmail_plusreply" id="plusReplyChip-0" href="mailto:zoltan.somogyi@runbox.com" tabindex="-1">@Zoltan Somogyi</a> thank you too!<br></div><div><br></div><div>Sean.</div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, 10 Jul 2019 at 10:26, Julien Fischer <<a href="mailto:jfischer@opturion.com">jfischer@opturion.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
Hi Sean,<br>
<br>
On Wed, 10 Jul 2019, emacstheviking wrote:<br>
<br>
> Any clues in the documentation as to where I can find out how to do<br>
> this? I've looked (and failed) to figure out how to call "maybe(T)"<br>
<br>
You don't call maybe(T), in this case you are attempting to construct<br>
it.<br>
<br>
> from C, basically I have the result of calling a C function that<br>
> reutns NULL or a window pointer:<br>
> SDL_WIndow *w = SDL_CreateWindow(...);<br>
> <br>
> and I want the pred to return maybe(sdl_window) where so in my main code I can switch on the result blah blah<br>
> <br>
> sdl_creatwindow(..., MW, ..., !IO),<br>
> (<br>
> MW = yes(Wnd),<br>
> % start my app<br>
> ;<br>
> MW = no,<br>
> % fail path<br>
> ),<br>
> <br>
> <br>
> :- type sdl_window.<br>
> :- pragma foreign_type("C", sdl_window, "SDL_Window *", [can_pass_as_mercury_type]).<br>
> <br>
> It's just knowing what the "way" is?!?!<br>
<br>
The two usual approaches here would be:<br>
<br>
1. Export a Mercury function to C that wraps the result of<br>
SDL_CreatWindow and call that from within the foreign_proc for<br>
sdl_createwindow. E.g.<br>
<br>
:- pragma foreign_export("C", maybe_yes_window(in) = out,<br>
"MER_maybe_yes_window").<br>
:- func maybe_yes_window(sdl_window) = maybe(sdl_window).<br>
maybe_yes_window(W) = yes(W).<br>
<br>
:- pragma foreign_export("C", maybe_no_window = out,<br>
"MER_maybe_no_window").<br>
:- func maybe_no_window = maybe(sdl_window).<br>
maybe_no_window = no.<br>
<br>
:- pragma foreign_proc("C",<br>
sdl_createwindow(... MW::in, ... _IO0::di, IO::uo),<br>
[will_call_mercury, promise_pure],<br>
"<br>
SDL_Window *w = <<create the window>>;<br>
if (w == null) {<br>
MW = MER_maybe_no_window();<br>
} else {<br>
MW = MER_maybe_yes_window(w);<br>
}<br>
").<br>
<br>
NOTE: since sdl_createwindow will make calls back to Mercury the<br>
'will_call_mercury' foreign code attribute must be set on the foreign<br>
proc.<br>
<br>
2. Return an additional flag indicating if the window pointer is null or<br>
not.<br>
<br>
sdl_createwindow(..., MW, ..., !IO) :-<br>
do_createwindow(..., IsNull, W, !IO),<br>
(<br>
IsNull = no,<br>
MW = yes(W)<br>
;<br>
IsNull = yes,<br>
MW = no<br>
).<br>
<br>
:- pred do_createwindow(..., bool::out, sdl_window::out,<br>
io::di, io::uo) is det.<br>
:- pragma foreign_proc("C",<br>
do_create_window(..., IsNull::out, W::out, _IO0::, _IO::uo),<br>
[will_not_call_mercury, promise_pure],<br>
"<br>
W = <<create the window>>;<br>
IsNull = (W == null) ? MR_YES : MR_NO;<br>
").<br>
<br>
Julien.</blockquote></div>