Re: Common FFI declarations

  • From: Cosmin Apreutesei <cosmin.apreutesei@xxxxxxxxx>
  • To: luajit@xxxxxxxxxxxxx
  • Date: Wed, 9 May 2012 13:21:07 +0300

On Wed, May 9, 2012 at 4:44 AM, William Adams <william_a_adams@xxxxxxx> wrote:
> You can take a look at my efforts here: http://github.com/wiladams
> for windows specific: https://github.com/Wiladams/BanateCoreWin32
> targeted to graphics specifically: https://github.com/Wiladams/HeadsUp

Cool, I'll check it out.

>
> writeups on using this stuff: http://williamaadams.wordpress.com/summaries/
>
> You've done a fair bit of work here.  Plenty of stuff for me to learn and
> build upon.

Thanks, stay tuned then.

> I noticed you used the "W" versions of functions instead of the "A"
> versions.  I wasn't aware that doing a ffi.cast("wchar_t", luastring) would
> actually make a wide character version appropriate for these calls.  Are you
> sure things like registrations of window class, and the titles of windows
> show up correctly without crashing?  I had a bear of a time with that, and
> just use the "A" versions.

I'm not casting, I'm using MultiByteToWideChar() to convert Lua strigs
assumed utf-8 to WCSs (see wcs() in auxlib.lua). AFAIK windows only
works with WCSs internally anyway, the A versions are just legacy
wrappers that do more-less the same conversion before calling the W
version internally.

> Do you intend to tackle COM interop in any way?

If there's COM goodies to bind to afterwards, sure, eg. I really need
a good editable grid (and tree view), the standard one is a joke,
maybe the office package exposes something via COM? What are you
interested in binding via COM? I'm focusing on GUI stuff right now
because that's where my need is but the library is modular so there's
no GUI bias in it outside of the GUI modules.

More importantly though I'm trying to build the necessary binding
language (set of utilities really) on top of ffi to make it so easy to
expand the library that people (including myself in the future) will
eventually consider it over binding their own from scratch. Like it or
not, this needs to be a collective effort from a certain point on if
is has any chance to get somewhere. But I'll probably need to produce
a Delphi 1-level component library before going social to have a
chance at getting people interested into joining in. In the meantime
least I can do as a matter of incentivizing is to have most modules
demonstrable by just running them. Since there's no prior setup
(dependencies to be installed), you will see some cookies on the
screen in seconds.

>
> For my message loop, I use the following, for a timed game like window:
>
> jit.off(Loop)
> function Loop(win)
>  local timerEvent = C.CreateEventA(nil, false, false, nil)
>  -- If the timer event was not created
>  -- just return
>  if timerEvent == nil then
>   error("unable to create timer")
>   return
>  end
>  local handleCount = 1
>  local handles = ffi.new('void*[1]', {timerEvent})
>  local msg = ffi.new("MSG")
>  local sw = StopWatch()
>  local tickCount = 1
>  local timeleft = 0
>  local lastTime = sw:Milliseconds()
>  local nextTime = lastTime + win.Interval * 1000
>  local dwFlags = bor(C.MWMO_ALERTABLE,C.MWMO_INPUTAVAILABLE)
>  while (win.IsRunning) do
>   while (user32.PeekMessageA(msg, nil, 0, 0, C.PM_REMOVE) ~= 0) do
>    user32.TranslateMessage(msg)
>    user32.DispatchMessageA(msg)
> --print(string.format("Loop Message: 0x%x", msg.message))
>    if msg.message == C.WM_QUIT then
>     return win:OnQuit()
>    end
>   end
>   timeleft = nextTime - sw:Milliseconds();
>   if (timeleft <= 0) then
>    win:OnTick(tickCount);
>    tickCount = tickCount + 1
>    nextTime = nextTime + win.Interval * 1000
>    timeleft = nextTime - sw:Milliseconds();
>   end
>   if timeleft < 0 then timeleft = 0 end
>   -- use an alertable wait
>   C.MsgWaitForMultipleObjectsEx(handleCount, handles, timeleft,
> C.QS_ALLEVENTS, dwFlags)
>  end
> end

Hm, can you call jit.off(Loop) before binding Loop? I'll try it out,
but I'll need to understand what the actual problem with callbacks is
in case there's other places that need fixing.

> I only put the jit.off(Loop) on this one function, and that seemed to be
> enough.  Everything else seems to work without fail.  This is a little bit
> more flexible that the standard message loop, as it can wake up after a
> specified amount of time, giving you an "Idle" time if you want to use that
> in your app.

Nice, I think I'll add an OnIdle event in the object interface as
well, I remember it being really useful in Delphi. Probably an
Application singleton will hold these things plus the message loop.

>
> There seems to be enough here and elsewhere to force the question, what
> should we do with these bindings?
>
> Perhaps a writeup on some styles, or just do a "whomever checks them in
> first" sort of thing.  I'd vote for a GitHub repository for these things,
> and sending out email soliciting people to review the stuff.
>
> -- William

Other related posts: