summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-12-09 11:34:33 +0200
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-12-09 11:34:33 +0200
commitf969ea2d93208bcc99eb9e513275686dfee5108a (patch)
tree3fd7e2abb93589482bc8b046eea06c8f6f63159c /src
parent1545ef0167fbfa91744e612adb22fa92cad38091 (diff)
Avoid allocations in event processing
The command string processing is done very often (e.g., whenever the mouse moves, potentially), so avoid allocating garbage-collected memory.
Diffstat (limited to 'src')
-rw-r--r--src/ui/command.c77
1 files changed, 53 insertions, 24 deletions
diff --git a/src/ui/command.c b/src/ui/command.c
index 3ae0f0c9..d6c668db 100644
--- a/src/ui/command.c
+++ b/src/ui/command.c
@@ -26,6 +26,34 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
26#include <the_Foundation/string.h> 26#include <the_Foundation/string.h>
27#include <ctype.h> 27#include <ctype.h>
28 28
29iDeclareType(Token)
30
31#define maxLen_Token 64
32
33struct Impl_Token {
34 char buf[64];
35 size_t size;
36};
37
38static void init_Token(iToken *d, const char *label) {
39 const size_t len = strlen(label);
40 iAssert(len < sizeof(d->buf) - 3);
41 d->buf[0] = ' ';
42 memcpy(d->buf + 1, label, len);
43 d->buf[1 + len] = ':';
44 d->buf[1 + len + 1] = 0;
45 d->size = len + 2;
46}
47
48static iRangecc find_Token(const iToken *d, const char *cmd) {
49 iRangecc range = iNullRange;
50 range.start = strstr(cmd, d->buf);
51 if (range.start) {
52 range.end = range.start + d->size;
53 }
54 return range;
55}
56
29iBool equal_Command(const char *cmdWithArgs, const char *cmd) { 57iBool equal_Command(const char *cmdWithArgs, const char *cmd) {
30 if (strchr(cmdWithArgs, ':')) { 58 if (strchr(cmdWithArgs, ':')) {
31 return startsWith_CStr(cmdWithArgs, cmd) && cmdWithArgs[strlen(cmd)] == ' '; 59 return startsWith_CStr(cmdWithArgs, cmd) && cmdWithArgs[strlen(cmd)] == ' ';
@@ -33,15 +61,12 @@ iBool equal_Command(const char *cmdWithArgs, const char *cmd) {
33 return equal_CStr(cmdWithArgs, cmd); 61 return equal_CStr(cmdWithArgs, cmd);
34} 62}
35 63
36static const iString *tokenString_(const char *label) {
37 return collectNewFormat_String(" %s:", label);
38}
39
40int argLabel_Command(const char *cmd, const char *label) { 64int argLabel_Command(const char *cmd, const char *label) {
41 const iString *tok = tokenString_(label); 65 iToken tok;
42 const char *ptr = strstr(cmd, cstr_String(tok)); 66 init_Token(&tok, label);
43 if (ptr) { 67 iRangecc ptr = find_Token(&tok, cmd);
44 return atoi(ptr + size_String(tok)); 68 if (ptr.start) {
69 return atoi(ptr.end);
45 } 70 }
46 return 0; 71 return 0;
47} 72}
@@ -51,19 +76,21 @@ int arg_Command(const char *cmd) {
51} 76}
52 77
53uint32_t argU32Label_Command(const char *cmd, const char *label) { 78uint32_t argU32Label_Command(const char *cmd, const char *label) {
54 const iString *tok = tokenString_(label); 79 iToken tok;
55 const char *ptr = strstr(cmd, cstr_String(tok)); 80 init_Token(&tok, label);
56 if (ptr) { 81 const iRangecc ptr = find_Token(&tok, cmd);
57 return strtoul(ptr + size_String(tok), NULL, 10); 82 if (ptr.start) {
83 return strtoul(ptr.end, NULL, 10);
58 } 84 }
59 return 0; 85 return 0;
60} 86}
61 87
62float argfLabel_Command(const char *cmd, const char *label) { 88float argfLabel_Command(const char *cmd, const char *label) {
63 const iString *tok = tokenString_(label); 89 iToken tok;
64 const char *ptr = strstr(cmd, cstr_String(tok)); 90 init_Token(&tok, label);
65 if (ptr) { 91 const iRangecc ptr = find_Token(&tok, cmd);
66 return strtof(ptr + size_String(tok), NULL); 92 if (ptr.start) {
93 return strtof(ptr.end, NULL);
67 } 94 }
68 return 0.0f; 95 return 0.0f;
69} 96}
@@ -77,11 +104,12 @@ float argf_Command(const char *cmd) {
77} 104}
78 105
79void *pointerLabel_Command(const char *cmd, const char *label) { 106void *pointerLabel_Command(const char *cmd, const char *label) {
80 const iString *tok = tokenString_(label); 107 iToken tok;
81 const char *ptr = strstr(cmd, cstr_String(tok)); 108 init_Token(&tok, label);
82 if (ptr) { 109 const iRangecc ptr = find_Token(&tok, cmd);
110 if (ptr.start) {
83 void *val = NULL; 111 void *val = NULL;
84 sscanf(ptr + size_String(tok), "%p", &val); 112 sscanf(ptr.end, "%p", &val);
85 return val; 113 return val;
86 } 114 }
87 return NULL; 115 return NULL;
@@ -92,10 +120,11 @@ void *pointer_Command(const char *cmd) {
92} 120}
93 121
94const char *suffixPtr_Command(const char *cmd, const char *label) { 122const char *suffixPtr_Command(const char *cmd, const char *label) {
95 const iString *tok = tokenString_(label); 123 iToken tok;
96 const char *ptr = strstr(cmd, cstr_String(tok)); 124 init_Token(&tok, label);
97 if (ptr) { 125 const iRangecc ptr = find_Token(&tok, cmd);
98 return ptr + size_String(tok); 126 if (ptr.start) {
127 return ptr.end;
99 } 128 }
100 return NULL; 129 return NULL;
101} 130}