[m-users.] Does Mercury have a 'reference' type other than thread.mvar ?

Sean Charles (emacstheviking) objitsu at gmail.com
Fri Jul 21 07:39:02 AEST 2023


Does mercury have anything like a reference type?

Having now overcome the obstacles required to render things using a graphics library called raylib, I am beginning to focus on exactly how I am going to represent an eventually complex tree of UI components; each component may be comprised of nested components etc etc.

My first problem is how to update a single arbitrary object e.g. keyboard events are routed to the object 'with focus' and will cause it to change state, case in point, my simple line input edit controller, as you type, it adds the key code to the end of the buffer and the renderer will then show the current contents etc That was the plan. My first attempt was to have a list of UI objects, then render them, that's fine. The object with focus is kept in the world object as a maybe(ui_object), and when I update it, the screen doesn't change because the object I have kept in the maybe record is not the same instance as the one being updated.

My creation code is like this:

    some [ !World ] (
        mk_world(144, !:World, !IO),
        INPUT = mk_input_line("*", 20, 200, 20, color(green)),
        ui_focus(yes(INPUT), !World),
        A0 = app_state(
            AppFont,
            [
                mk_kbdmon(100,  0, 20, color(red)),
                mk_mousemon(0, 35, 20, color(white)),
                mk_timermon(0, 70, 20, color(yellow)),
                mk_cursor(144, 105,    color(green)),
                INPUT
            ]
        ),
        ui_run_loop(A0, _, !.World, _, !IO),
        unload_font(AppFont, !IO),
        close_window(!IO)
    ).

In the loop updating code, I check for any key pressed, and pass it to the currently focused input object:

consume_keyboard(!W, !IO) :-
    get_key_pressed_int(Key, !IO),
    ( if  Key > 0 then
        (
            w_focus(!.W) = yes(Target),
            trace_info("ui_object:keyboard:%s", [ s(string(Key)) ], !IO),
            ( if key_pressed_to(Key, Target, Out, !W) then
                !:W = !.W ^w_focus := yes(Out)
            else
                true
            )
        ;
            w_focus(!.W) = no,
            trace_info("desktop:keyboard:%s", [ s(string(Key)) ], !IO)
        )
    else true).

The lines in bold show that, having passed the key to the object, it is expected to return a modified instance, this is all fine, it works, 

INFO: ui_object:keyboard:84
chars2:['*']
INFO: ui_object:keyboard:69
chars2:['T', '*']
INFO: ui_object:keyboard:83
chars2:['E', 'T', '*']
INFO: ui_object:keyboard:84
chars2:['S', 'E', 'T', '*']

The reason that the screen is not showing the new keys (reversed, I know) is because the INPUT in the list is, after the first event update, no longer the same object now held in the 'focus' slot in the world state.

I apologise for the lengthy description thus far but I am just trying to give some background in my though processes, or lack thereof so far I guess.
I am currently reading the docs for thread.mvar as it seems like it might be what I need but then again maybe not as I am not threading per se.

Presumably I now have to find a scheme whereby I can iterate a tree of objects, and then update the one with event focus but there other problems to solve to like finding out which component is uder a mouse down event etc. I have a suspicion that my long time owned and once read copy of Purely Functional Data Structures (Okasaki) might be useful?

If I was writing code in pure C it wouldn't be an issue, I've done things like this before, but never in a language like Mercury,

So...any idea, hints, sources of things to read etc will be most welcome. I think this will be a most interesting problem to solve,

:)


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurylang.org/archives/users/attachments/20230720/844dc345/attachment.html>


More information about the users mailing list