Skip to content

Commit 5adc663

Browse files
committed
COMMON: Allow modules to return objects with methods that take arguments
1 parent 2844d7d commit 5adc663

File tree

10 files changed

+144
-112
lines changed

10 files changed

+144
-112
lines changed

src/common/blib.c

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
#include "common/fmt.h"
1313
#include "common/keymap.h"
1414
#include "common/messages.h"
15-
#include "common/plugins.h"
1615

1716
#define STR_INIT_SIZE 256
1817
#define PKG_INIT_SIZE 5
@@ -2882,22 +2881,10 @@ void cmd_call_vfunc() {
28822881
rt_raise(ERR_NO_FUNC);
28832882
}
28842883
} else {
2885-
slib_par_t *ptable;
2886-
int pcount;
2887-
if (code_peek() == kwTYPE_LEVEL_BEGIN) {
2888-
ptable = (slib_par_t *)malloc(sizeof(slib_par_t) * MAX_PARAMS);
2889-
pcount = plugin_build_ptable(ptable, MAX_PARAMS);
2890-
} else {
2891-
ptable = NULL;
2892-
pcount = 0;
2893-
}
2894-
if (!prog_error) {
2895-
v_func->v.fn.cb(map, pcount, ptable, NULL);
2896-
}
2897-
if (ptable) {
2898-
plugin_free_ptable(ptable, pcount);
2899-
free(ptable);
2900-
}
2884+
var_t result;
2885+
v_init(&result);
2886+
v_eval_func(map, v_func, &result);
2887+
v_free(&result);
29012888
}
29022889
}
29032890

src/common/eval.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -786,7 +786,7 @@ static inline void eval_var(var_t *r, var_t *var_p) {
786786
v_set(r, var_p);
787787
break;
788788
case V_FUNC:
789-
var_p->v.fn.cb(var_p, 0, NULL, r);
789+
var_p->v.fn.cb(var_p, r);
790790
break;
791791
case V_NIL:
792792
r->type = V_NIL;

src/common/var.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,5 +800,6 @@ void v_create_func(var_p_t map, const char *name, method cb) {
800800
var_p_t v_func = map_add_var(map, name, 0);
801801
v_func->type = V_FUNC;
802802
v_func->v.fn.cb = cb;
803+
v_func->v.fn.mcb = NULL;
803804
v_func->v.fn.id = 0;
804805
}

src/common/var_eval.c

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// This program is distributed under the terms of the GPL v2.0 or later
66
// Download the GNU Public License (GPL) from www.gnu.org
77
//
8-
// Copyright(C) 2010-2014 Chris Warren-Smith. [http://tinyurl.com/ja2ss]
8+
// Copyright(C) 2010-2024 Chris Warren-Smith. [http://tinyurl.com/ja2ss]
99

1010
#include "common/sys.h"
1111
#include "common/kw.h"
@@ -14,6 +14,44 @@
1414
#include "common/smbas.h"
1515
#include "common/var.h"
1616
#include "common/var_eval.h"
17+
#include "common/plugins.h"
18+
19+
void v_eval_func(var_p_t self, var_p_t v_func, var_p_t result) {
20+
if (v_func->v.fn.cb != NULL) {
21+
// internal object method
22+
if (code_peek() == kwTYPE_LEVEL_BEGIN) {
23+
code_skipnext();
24+
}
25+
v_func->v.fn.cb(self, NULL);
26+
if (code_peek() == kwTYPE_LEVEL_END) {
27+
code_skipnext();
28+
}
29+
} else {
30+
// module callback
31+
slib_par_t *ptable;
32+
int pcount;
33+
if (code_peek() == kwTYPE_LEVEL_BEGIN) {
34+
ptable = (slib_par_t *)malloc(sizeof(slib_par_t) * MAX_PARAMS);
35+
pcount = plugin_build_ptable(ptable, MAX_PARAMS);
36+
} else {
37+
ptable = NULL;
38+
pcount = 0;
39+
}
40+
if (!prog_error) {
41+
if (!v_func->v.fn.mcb(self, pcount, ptable, result)) {
42+
if (result->type == V_STR) {
43+
err_throw(result->v.p.ptr);
44+
} else {
45+
err_throw("Undefined");
46+
}
47+
}
48+
}
49+
if (ptable) {
50+
plugin_free_ptable(ptable, pcount);
51+
free(ptable);
52+
}
53+
}
54+
}
1755

1856
/**
1957
* Convert multi-dim index to one-dim index
@@ -159,6 +197,13 @@ var_t *code_get_map_element(var_t *map, var_t *field) {
159197
}
160198
} else if (field->type == V_ARRAY) {
161199
result = code_getvarptr_arridx(field);
200+
} else if (field->type == V_FUNC) {
201+
result = map_get(map, MAP_TMP_FIELD);
202+
if (result == NULL) {
203+
result = map_add_var(map, MAP_TMP_FIELD, 0);
204+
}
205+
v_init(result);
206+
v_eval_func(map, field, result);
162207
} else {
163208
code_skipnext();
164209
var_t var;

src/common/var_eval.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,13 @@ int code_isvar(void);
6767
*/
6868
void v_eval_str(var_p_t v);
6969

70+
/**
71+
* @ingroup var
72+
*
73+
* invokes the virtual function
74+
*/
75+
void v_eval_func(var_p_t self, var_p_t v_func, var_p_t result);
76+
7077
#if defined(__cplusplus)
7178
}
7279
#endif

src/include/var.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,11 @@ typedef struct {
5656
uint8_t byref;
5757
} slib_par_t;
5858

59-
// object method signature
60-
typedef void (*method) (struct var_s *self, int param_count, slib_par_t *params, struct var_s *retval);
59+
// signature for module callback/virtual functions
60+
typedef int (*callback) (struct var_s *self, int param_count, slib_par_t *params, struct var_s *retval);
61+
62+
// signature for internal v_funcs
63+
typedef void (*method) (struct var_s *self, struct var_s *retval);
6164

6265
typedef struct var_s {
6366
union {
@@ -93,6 +96,7 @@ typedef struct var_s {
9396
// object method
9497
struct {
9598
method cb;
99+
callback mcb;
96100
uint32_t id;
97101
} fn;
98102

src/platform/console/image.cpp

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -245,15 +245,10 @@ ImageBuffer *load_xpm_image(char **data) {
245245
//
246246
// png.clip(10, 10, 10, 10)
247247
//
248-
void cmd_image_clip(var_s *self, int param_count, slib_par_t *params, var_s *) {
248+
void cmd_image_clip(var_s *self, var_s *) {
249+
var_int_t left, top, right, bottom;
249250
ImageBuffer *image = load_image(self);
250-
if (param_count != 4) {
251-
err_parm_num(param_count, 4);
252-
} else {
253-
var_int_t left = v_getint(params[0].var_p);
254-
var_int_t top = v_getint(params[1].var_p);
255-
var_int_t right = v_getint(params[2].var_p);
256-
var_int_t bottom = v_getint(params[3].var_p);
251+
if (par_massget("iiii", &left, &top, &right, &bottom) == 4) {
257252
int w = image->_width - (right + left);
258253
int h = image->_height - (bottom + top);
259254
int size = w * h * 4;
@@ -282,6 +277,8 @@ void cmd_image_clip(var_s *self, int param_count, slib_par_t *params, var_s *) {
282277
map_set_int(self, IMG_WIDTH, w);
283278
map_set_int(self, IMG_HEIGHT, h);
284279
}
280+
} else {
281+
err_throw(ERR_PARAM);
285282
}
286283
}
287284

@@ -293,7 +290,7 @@ void cmd_image_clip(var_s *self, int param_count, slib_par_t *params, var_s *) {
293290
// end
294291
// png.filter(use colorToAlpha(x))
295292
//
296-
void cmd_image_filter(var_s *self, int param_count, slib_par_t *params, var_s *) {
293+
void cmd_image_filter(var_s *self, var_s *) {
297294
ImageBuffer *image_buffer = load_image(self);
298295
if (code_peek() == kwUSE && image_buffer != nullptr) {
299296
code_skipnext();
@@ -329,22 +326,19 @@ void cmd_image_filter(var_s *self, int param_count, slib_par_t *params, var_s *)
329326
// png2 = image(w, h)
330327
// png2.paste(png1, 0, 0)
331328
//
332-
void cmd_image_paste(var_s *self, int param_count, slib_par_t *params, var_s *) {
329+
void cmd_image_paste(var_s *self, var_s *) {
330+
var_int_t x, y;
331+
var_t *var;
333332
ImageBuffer *image = load_image(self);
334-
if (image != nullptr && (param_count == 1 || param_count == 3)) {
335-
var_t *var = params[0].var_p;
333+
int count = par_massget("Piiii", &var, &x, &y);
334+
if (image != nullptr && (count == 1 || count == 3)) {
336335
ImageBuffer *srcImage = load_image(var);
337336
if (srcImage == nullptr) {
338337
err_throw(ERR_PARAM);
339338
} else {
340-
var_int_t x;
341-
var_int_t y;
342339
if (count == 1) {
343340
x = 0;
344341
y = 0;
345-
} else {
346-
x = v_getint(params[1].var_p);
347-
y = v_getint(params[2].var_p);
348342
}
349343
int dw = image->_width;
350344
int dh = image->_height;
@@ -376,7 +370,7 @@ void cmd_image_paste(var_s *self, int param_count, slib_par_t *params, var_s *)
376370
// png.save("horse1.png")
377371
// png.save(#1)
378372
//
379-
void cmd_image_save(var_s *self, int param_count, slib_par_t *params, var_s *) {
373+
void cmd_image_save(var_s *self, var_s *) {
380374
ImageBuffer *image = load_image(self);
381375
dev_file_t *filep = nullptr;
382376
byte code = code_peek();

src/ui/form.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,20 +116,29 @@ void FormLink::clicked(int x, int y, bool pressed) {
116116
}
117117
}
118118

119-
void cmd_form_close(var_s *self, int param_count, slib_par_t *params, var_s *) {
119+
void cmd_form_close(var_s *self, var_s *) {
120120
g_system->getOutput()->removeInputs();
121121
g_system->getOutput()->resetScroll();
122-
if (param_count == 1 && params[0].var_p->type == V_STR) {
123-
g_system->setLoadBreak(params[0].var_p->v.p.ptr);
122+
123+
var_t arg;
124+
v_init(&arg);
125+
eval(&arg);
126+
if (arg.type == V_STR) {
127+
g_system->setLoadBreak(arg.v.p.ptr);
124128
}
129+
v_free(&arg);
125130
}
126131

127-
void cmd_form_refresh(var_s *self, int param_count, slib_par_t *params, var_s *) {
128-
bool setVars = param_count == 1 && v_getint(params[0].var_p) != 0;
132+
void cmd_form_refresh(var_s *self, var_s *) {
133+
var_t arg;
134+
v_init(&arg);
135+
eval(&arg);
136+
bool setVars = v_getint(&arg) != 0;
137+
v_free(&arg);
129138
g_system->getOutput()->updateInputs(self, setVars);
130139
}
131140

132-
void cmd_form_do_events(var_s *self, int param_count, slib_par_t *params, var_s *) {
141+
void cmd_form_do_events(var_s *self, var_s *) {
133142
// apply any variable changes onto attached widgets
134143
if (g_system->isRunning()) {
135144
AnsiWidget *out = g_system->getOutput();

src/ui/image.cpp

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ ImageBuffer *load_xpm_image(char **data) {
370370
return result;
371371
}
372372

373-
void get_image_display(var_s *self, int param_count, slib_par_t *params, ImageDisplay *image) {
373+
void get_image_display(var_s *self, ImageDisplay *image) {
374374
image->_bid = map_get_int(self, IMG_BID, -1);
375375

376376
List_each(ImageBuffer *, it, buffers) {
@@ -381,13 +381,14 @@ void get_image_display(var_s *self, int param_count, slib_par_t *params, ImageDi
381381
}
382382
}
383383

384-
if (prog_error || image->_buffer == nullptr || param_count == 1 || param_count > 4) {
384+
var_int_t x, y, z, op;
385+
int count = par_massget("iiii", &x, &y, &z, &op);
386+
387+
if (prog_error || image->_buffer == nullptr || count == 1 || count > 4) {
385388
err_throw(ERR_PARAM);
386389
} else {
387390
// 0, 2, 3, 4 arguments accepted
388-
if (param_count >= 2) {
389-
var_int_t x = v_getint(params[0].var_p);
390-
var_int_t y = v_getint(params[1].var_p);
391+
if (count >= 2) {
391392
image->_x = x;
392393
image->_y = y;
393394
map_set_int(self, IMG_X, x);
@@ -396,15 +397,13 @@ void get_image_display(var_s *self, int param_count, slib_par_t *params, ImageDi
396397
image->_x = map_get_int(self, IMG_X, -1);
397398
image->_y = map_get_int(self, IMG_Y, -1);
398399
}
399-
if (param_count >= 3) {
400-
var_int_t z = v_getint(params[2].var_p);
400+
if (count >= 3) {
401401
image->_zIndex = z;
402402
map_set_int(self, IMG_ZINDEX, z);
403403
} else {
404404
image->_zIndex = map_get_int(self, IMG_ZINDEX, -1);
405405
}
406-
if (param_count == 4) {
407-
var_int_t op = v_getint(params[3].var_p);
406+
if (count == 4) {
408407
image->_opacity = op;
409408
map_set_int(self, IMG_OPACITY, op);
410409
} else {
@@ -422,9 +421,9 @@ void get_image_display(var_s *self, int param_count, slib_par_t *params, ImageDi
422421
//
423422
// png.show(x, y, zindex, opacity)
424423
//
425-
void cmd_image_show(var_s *self, int param_count, slib_par_t *params, var_s *) {
424+
void cmd_image_show(var_s *self, var_s *) {
426425
ImageDisplay image;
427-
get_image_display(self, param_count, params, &image);
426+
get_image_display(self, &image);
428427
if (!prog_error) {
429428
g_system->getOutput()->addImage(image);
430429
}
@@ -433,9 +432,9 @@ void cmd_image_show(var_s *self, int param_count, slib_par_t *params, var_s *) {
433432
//
434433
// png.draw(x, y, opacity)
435434
//
436-
void cmd_image_draw(var_s *self, int param_count, slib_par_t *params, var_s *) {
435+
void cmd_image_draw(var_s *self, var_s *) {
437436
ImageDisplay image;
438-
get_image_display(self, param_count, params, &image);
437+
get_image_display(self, &image);
439438
if (!prog_error) {
440439
image._opacity = image._zIndex;
441440
g_system->getOutput()->drawImage(image);
@@ -445,7 +444,7 @@ void cmd_image_draw(var_s *self, int param_count, slib_par_t *params, var_s *) {
445444
//
446445
// png.hide()
447446
//
448-
void cmd_image_hide(var_s *self, int param_count, slib_par_t *params, var_s *) {
447+
void cmd_image_hide(var_s *self, var_s *) {
449448
int id = map_get_int(self, IMG_ID, -1);
450449
g_system->getOutput()->removeImage(id);
451450
}
@@ -456,7 +455,7 @@ void cmd_image_hide(var_s *self, int param_count, slib_par_t *params, var_s *) {
456455
// png.save("horse1.png")
457456
// png.save(#1)
458457
//
459-
void cmd_image_save(var_s *self, int param_count, slib_par_t *params, var_s *) {
458+
void cmd_image_save(var_s *self, var_s *) {
460459
unsigned id = map_get_int(self, IMG_BID, -1);
461460
ImageBuffer *image = get_image(id);
462461
dev_file_t *file;
@@ -517,16 +516,17 @@ void cmd_image_save(var_s *self, int param_count, slib_par_t *params, var_s *) {
517516
//
518517
// png.clip(10, 10, 10, 10)
519518
//
520-
void cmd_image_clip(var_s *self, int param_count, slib_par_t *params, var_s *) {
519+
void cmd_image_clip(var_s *self, var_s *) {
521520
if (self->type == V_MAP) {
522521
int bid = map_get_int(self, IMG_BID, -1);
523522
if (bid != -1) {
524523
ImageBuffer *image = get_image((unsigned)bid);
525-
if (image != nullptr && param_count == 4) {
526-
map_set_int(self, IMG_OFFSET_LEFT, v_getint(params[0].var_p));
527-
map_set_int(self, IMG_OFFSET_TOP, v_getint(params[1].var_p));
528-
map_set_int(self, IMG_WIDTH, v_getint(params[2].var_p));
529-
map_set_int(self, IMG_HEIGHT, v_getint(params[3].var_p));
524+
var_int_t left, top, right, bottom;
525+
if (image != nullptr && par_massget("iiii", &left, &top, &right, &bottom)) {
526+
map_set_int(self, IMG_OFFSET_LEFT, left);
527+
map_set_int(self, IMG_OFFSET_TOP, top);
528+
map_set_int(self, IMG_WIDTH, right);
529+
map_set_int(self, IMG_HEIGHT, bottom);
530530
}
531531
}
532532
}

0 commit comments

Comments
 (0)