Differences From
Artifact [70ed0e36b0]:
1 -/* [ʞ] util.h
1 +/* [ʞ] src/util-gd.h
2 2 * ~ lexi hale <lexi@hale.su>
3 3 * 🄯 AGPLv3
4 - * ? encapsulate annoying operations (read: pitiful, fragile blast
5 - * shield over the most indefensibly psychotic pieces of the godot
6 - * "type" "system")
7 - *
8 - * if you want to use this outside gdjn, redefine the macro _t
9 - * from gdjn.h appropriately.
10 - *
11 - * (honestly tho you should use c-bind-gen.janet too)
4 + * ? encapsulate annoying godot operations (read: pitiful,
5 + * fragile blast shield over the most indefensibly psychotic
6 + * pieces of the godot "type" "system")
12 7 */
13 8
14 9 #pragma once
15 10 #include "gdjn.h"
16 11 #include <string.h>
12 +#include "type.h"
17 13
18 14 static inline gd_string
19 15 gdu_string_of_stringName(const gd_stringName* const s) {
20 16 gd_string r;
21 17 _t(string).fromStringName(&r, (void*)&s);
22 18 return r;
23 19 }
................................................................................
75 71 #define _refMut(x) typeof(typeof(x) * const)
76 72 #define _with(T, k, v, ...) ({\
77 73 typeof(gd_##T) k = v; \
78 74 do { __VA_ARGS__; } while (0); \
79 75 _t(T).dtor(&k); \
80 76 })
81 77
82 -#define _withSym(k, v, ...) \
83 - _with(stringName, k, gdu_intern(v), __VA_ARGS__)
84 78 #define _withSym0(k, ...) \
85 79 _with(stringName, k, {}, __VA_ARGS__)
86 -#define _withStr(k, v, ...) \
87 - _with(string, k, gdu_str(v), __VA_ARGS__)
88 -#define _withStr0(k, v, ...) \
80 +#define _withSymSz(k, v, sz, ...) \
81 + _with(stringName, k, gdu_intern_sz(v, sz), __VA_ARGS__)
82 +#define _withSym(k, v, ...) \
83 + _withSymSz(k, _strDynMem(v), _strDynSz(v), __VA_ARGS__)
84 +#define _withSymLit(k, v, ...) \
85 + _withSymSz(k, _litSz(v), __VA_ARGS__)
86 +
87 +#define _withStr0(k, ...) \
89 88 _with(string, k, {}, __VA_ARGS__)
90 -
91 -#define _typeEq(a, b) \
92 - __builtin_classify_type(typeof(a)) == _builtin_classify_type(typeof(b))
93 -
94 -#define _refVal 0
95 -#define _refPtr 1
96 -#define _refArray 2
97 -
98 -#define _indirect(a) \
99 - __builtin_types_compatible_p(typeof(a), void*)
100 -
101 -#define _refKind(a) \
102 - __builtin_choose( _typeEq(typeof_unqual(a), \
103 - typeof_unqual(a[0]) []), _refArray \
104 - /* false */ __builtin_choose(_typeEq(a, (typeof_unqual(a[0]) *)), _refPtr ))
105 -
106 -#define _szElse(a, zero) \
107 - __builtin_choose(_refKind(a) == _refArray, \
108 - /* true */ _sz(a), \
109 - /* false */ __builtin_choose(_refKind(a) == _refPtr, \
110 - /* true */ (__builtin_counted_by(ptr) != nullptr ? \
111 - *__builtin_counted_by(ptr) : (zero)) \
112 - /* false */ (void)0 /* bad type */ ))
113 -#define _sz0(a) _szElse(a,0)
114 -#define _szStr(a) \
115 - __builtin_choose(_typeEq((a), pstr), (a).sz, _szElse(a, strlen(a)))
116 -
117 -#define _array(t) struct {t* v; size_t sz;}
118 -typedef _array(char) pstr;
119 -
120 -#define _strWithSz(a) (a), _strLen(a)
89 +#define _withStrSz(k, v, sz, ...) \
90 + _with(string, k, gdu_str_sz(v, sz), __VA_ARGS__)
91 +#define _withStr(k, v, ...) \
92 + _withStrSz(k, _strDynMem(v), _strDynSz(v), __VA_ARGS__)
93 +#define _withStrLit(k, v, ...) \
94 + _withStrSz(k, _litSz(v), __VA_ARGS__)
121 95
122 96 static inline bool
123 97 gdu_symIs
124 98 ( gd_stringName const* const a,
125 99 gd_stringName const* const b
126 100 ) {
127 101 bool res;
................................................................................
225 199 char* buf = _alloc(char, len);
226 200 gdu_string_emit(s, buf, len - 1);
227 201 return (pstr){buf,len};
228 202 }
229 203
230 204 static inline gd_string
231 205 gdu_string_dup (_ref(gd_string) s) {
232 - gd_string cp;
233 - _t(string).copy(&cp, (void const*[]) {s});
234 - return cp;
206 + /* the godot copy method seems to be broken somehow,
207 + * probably for reasons that have to do with the
208 + * hypercomplicated CoW implementation that i think
209 + * is meant to be handled on this end somehow? we
210 + * can seemingly avoid crashes and memory corruption
211 + * if we copy the string through C, forcing a clean
212 + * new string to be generated on the godot side. */
213 + // _t(string).copy(&cp, (void const*[]) {s});
214 + auto cstr = gdu_string_pdup(s);
215 + auto copied = gdu_str_sz(cstr.v, cstr.sz);
216 + _drop(cstr);
217 + return copied;
235 218 }
236 219
237 220 #define _cat(x,y) x##y
238 221 #define __cat(x,y) _cat(x,y)
239 222 #define _gensym __cat(_sym_,__COUNTER__)
240 223
241 224 #define __gdu_string_auto(szid, name, str) \
................................................................................
371 354 static inline GDExtensionObjectPtr
372 355 gdu_cast
373 356 ( GDExtensionConstObjectPtr what,
374 357 _ref(char) to
375 358 ) {
376 359 return _t(object).castTo(what, gdu_classTag(to));
377 360 }
361 +
362 +static inline void
363 +gdu_setKey
364 +( gd_dictionary* const dict,
365 + pstr const key,
366 + _ref(gd_variant) val
367 +) {
368 + gd_variant v = gd_variant_of_dictionary(*dict);
369 + _withSym(keyName, key, {
370 + uint8_t ok = false;
371 + _t(variant).setNamed(&v, &keyName, val, &ok);
372 + });
373 +}
374 +