-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathcommand.c
More file actions
executable file
·74 lines (64 loc) · 2.02 KB
/
command.c
File metadata and controls
executable file
·74 lines (64 loc) · 2.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/* command.c */
#include <stdio.h>
#include "baize.h"
#include "command.h"
#include "ui.h"
struct Command {
// ISO C forbids conversion of object pointer to function pointer type [-Werror=pedantic]
// so we hide our function pointer in a struct
CommandFunction cf;
void *param; // NULL, or a pointer to a block of memory owned by widget
// i.e. the Widget frees this memory, no-one else
// currently used by TextWidget in variantDrawer: strdup(vname)
};
struct Array* CommandQueue = NULL;
void StartCommandQueue(void)
{
CommandQueue = ArrayNew(8);
}
void StopCommandQueue(void)
{
if (CommandQueue) {
ArrayFree(CommandQueue);
}
}
void PostCommand(CommandFunction cf, void *param)
{
struct Command *c = calloc(1, sizeof(struct Command));
if (c) {
c->cf = cf;
c->param = param;
CommandQueue = ArrayPush(CommandQueue, c);
}
}
void PostUniqueCommand(CommandFunction cf, void *param)
{
_Bool found = 0;
size_t index;
for ( struct Command *c = ArrayFirst(CommandQueue, &index); c; c = ArrayNext(CommandQueue, &index) ) {
if (c->cf == cf) {
fprintf(stdout, "INFO: %s: command already in queue\n", __func__);
found = 1;
break;
}
}
if (!found) {
PostCommand(cf, param);
}
}
void ServiceCommandQueue(struct Baize *const baize)
{
if ( ArrayLen(CommandQueue) > 0 ) {
// ISO C forbids conversion of object pointer to function pointer type [-Werror=pedantic]
struct Command *c = ArrayGet(CommandQueue, 0);
if (c) {
if ( c->cf ) {
UiHideDrawers(baize->ui);
c->cf(baize, c->param); // param is owned by Widget (most likely a TextWidget in variantDrawer)
}
ArrayDelete(CommandQueue, 0, free); // tell Array to free the Command object allocated in NewCommand()
} else {
ArrayDelete(CommandQueue, 0, NULL); // no Command object to free
}
}
}