Skip to content

Commit 3f47eb5

Browse files
authored
Merge pull request #296 from ntd/progress-callback
Progress callback
2 parents 48ff62e + 7f8fc55 commit 3f47eb5

File tree

3 files changed

+90
-17
lines changed

3 files changed

+90
-17
lines changed

lgi/callable.c

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -324,11 +324,32 @@ callable_allocate (lua_State *L, int nargs, ffi_type ***ffi_args)
324324
return callable;
325325
}
326326

327+
static Param *
328+
callable_get_param (Callable *callable, gint n)
329+
{
330+
Param *param;
331+
332+
if (n < 0 || n >= callable->nargs)
333+
return NULL;
334+
335+
param = &callable->params[n];
336+
if (!param->has_arg_info)
337+
{
338+
/* Ensure basic fields are initialized. */
339+
g_callable_info_load_arg (callable->info, n, &param->ai);
340+
param->has_arg_info = TRUE;
341+
param->ti = g_arg_info_get_type (&param->ai);
342+
param->dir = g_arg_info_get_direction (&param->ai);
343+
param->transfer = g_arg_info_get_ownership_transfer (&param->ai);
344+
}
345+
return param;
346+
}
347+
327348
int
328349
lgi_callable_create (lua_State *L, GICallableInfo *info, gpointer addr)
329350
{
330351
Callable *callable;
331-
Param *param;
352+
Param *param, *data_param;
332353
ffi_type **ffi_arg, **ffi_args;
333354
ffi_type *ffi_retval;
334355
gint nargs, argi, arg;
@@ -377,32 +398,32 @@ lgi_callable_create (lua_State *L, GICallableInfo *info, gpointer addr)
377398
*ffi_arg++ = &ffi_type_pointer;
378399

379400
/* Process the rest of the arguments. */
380-
param = &callable->params[0];
381-
for (argi = 0; argi < nargs; argi++, param++, ffi_arg++)
401+
for (argi = 0; argi < nargs; argi++, ffi_arg++)
382402
{
383-
g_callable_info_load_arg (callable->info, argi, &param->ai);
384-
param->has_arg_info = TRUE;
385-
param->ti = g_arg_info_get_type (&param->ai);
386-
param->dir = g_arg_info_get_direction (&param->ai);
387-
param->transfer = g_arg_info_get_ownership_transfer (&param->ai);
403+
param = callable_get_param (callable, argi);
388404
*ffi_arg = (param->dir == GI_DIRECTION_IN)
389405
? get_ffi_type (param) : &ffi_type_pointer;
390406

391-
/* Mark closure-related user_data fields and possibly destroy_notify
392-
fields as internal. */
407+
/* Mark closure-related user_data fields as internal. */
393408
arg = g_arg_info_get_closure (&param->ai);
394-
if (arg >= 0 && arg < nargs)
409+
data_param = callable_get_param (callable, arg);
410+
/* `arg` is defined also on callbacks, so check for invalid scope
411+
to avoid setting the internal flag on them. */
412+
if (data_param != NULL && g_arg_info_get_scope (&data_param->ai) == GI_SCOPE_TYPE_INVALID)
395413
{
396-
callable->params[arg].internal = TRUE;
414+
data_param->internal = TRUE;
397415
if (arg == argi)
398-
callable->params[arg].internal_user_data = TRUE;
399-
callable->params[arg].n_closures++;
416+
data_param->internal_user_data = TRUE;
417+
data_param->n_closures++;
400418
if (g_arg_info_get_scope (&param->ai) == GI_SCOPE_TYPE_CALL)
401-
callable->params[arg].call_scoped_user_data = TRUE;
419+
data_param->call_scoped_user_data = TRUE;
402420
}
421+
422+
/* Mark destroy_notify fields as internal. */
403423
arg = g_arg_info_get_destroy (&param->ai);
404-
if (arg > 0 && arg < nargs)
405-
callable->params[arg].internal = TRUE;
424+
data_param = callable_get_param (callable, arg);
425+
if (data_param != NULL)
426+
data_param->internal = TRUE;
406427

407428
/* Similarly for array length field. */
408429
callable_mark_array_length (callable, param->ti);

tests/progress.lua

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
--[[--------------------------------------------------------------------------
2+
3+
LGI testsuite, progress callback checking
4+
5+
Copyright (c) 2022 Nicola Fontana
6+
Licensed under the MIT license:
7+
http://www.opensource.org/licenses/mit-license.php
8+
9+
--]]--------------------------------------------------------------------------
10+
11+
local lgi = require 'lgi'
12+
local Gio = lgi.Gio
13+
local GLib = lgi.GLib
14+
15+
local check = testsuite.check
16+
17+
local progress = testsuite.group.new('progress')
18+
19+
local function check_gerror(namespace, api, ...)
20+
local result, err = namespace[api](...)
21+
check(result, string.format('Error during %s() call: %s',
22+
api, tostring(err)))
23+
return result
24+
end
25+
26+
function progress.file_copy()
27+
local File = Gio.File
28+
local loop = GLib.MainLoop.new()
29+
30+
31+
-- This assumes a valid and readable filename is passed as arg[0]
32+
local src = check_gerror(File, 'new_for_path', arg[0])
33+
local dst = check_gerror(File, 'new_tmp')
34+
local flags = Gio.FileCopyFlags.OVERWRITE
35+
local priority = 0
36+
local cancellable = nil
37+
38+
local progress_callback = function (partial, total)
39+
check(partial <= total,
40+
string.format('Writing too many bytes (%d > %d)', partial, total))
41+
end
42+
43+
local finish_callback = function (self, result)
44+
check_gerror(Gio.File, 'copy_finish', self, result)
45+
loop:quit()
46+
end
47+
48+
src:copy_async(dst, flags, priority, cancellable,
49+
progress_callback, finish_callback)
50+
loop:run()
51+
end

tests/test.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ for _, sourcefile in ipairs {
118118
'cairo.lua',
119119
'pango.lua',
120120
'gio.lua',
121+
'progress.lua',
121122
} do
122123
dofile(testpath .. '/' .. sourcefile)
123124
end

0 commit comments

Comments
 (0)