2023-01-10 07:13:00 -06:00
|
|
|
#ifndef FFI_H
|
|
|
|
#define FFI_H
|
|
|
|
|
2024-05-21 18:50:53 -05:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
2023-04-18 14:49:17 -05:00
|
|
|
#include "quickjs/quickjs.h"
|
2023-12-22 11:50:03 -06:00
|
|
|
#include "HandmadeMath.h"
|
2024-04-02 07:41:46 -05:00
|
|
|
#include <stdarg.h>
|
2024-05-20 13:50:57 -05:00
|
|
|
#include <chipmunk/chipmunk.h>
|
|
|
|
|
2024-08-06 14:23:21 -05:00
|
|
|
void script_report_gc_time(double t, double startmem, double mem);
|
|
|
|
|
2024-08-15 12:26:37 -05:00
|
|
|
int JS_Is(JSValue v);
|
|
|
|
|
2024-05-20 13:50:57 -05:00
|
|
|
extern JSValue cpShape2js(cpShape *s);
|
2023-01-10 07:13:00 -06:00
|
|
|
|
2024-08-08 13:25:47 -05:00
|
|
|
#define MIST_CFUNC_DEF(name, length, func1, props) { name, props, JS_DEF_CFUNC, 0, .u = { .func = { length, JS_CFUNC_generic, { .generic = func1 } } } }
|
2024-03-26 14:57:35 -05:00
|
|
|
|
2024-08-08 13:25:47 -05:00
|
|
|
#define MIST_FUNC_DEF(TYPE, FN, LEN) MIST_CFUNC_DEF(#FN, LEN, js_##TYPE##_##FN, JS_PROP_C_W_E)
|
|
|
|
#define PROTO_FUNC_DEF(TYPE, FN, LEN) MIST_CFUNC_DEF(#FN, LEN, js_##TYPE##_##FN, 0)
|
2024-03-26 14:57:35 -05:00
|
|
|
|
2024-05-21 18:50:53 -05:00
|
|
|
#define JS_SETSIG JSContext *js, JSValue self, JSValue val
|
2024-05-17 12:39:04 -05:00
|
|
|
|
2024-03-26 14:57:35 -05:00
|
|
|
#define JSC_SCALL(NAME, FN) JSC_CCALL(NAME, \
|
|
|
|
const char *str = js2str(argv[0]); \
|
2024-08-08 17:32:58 -05:00
|
|
|
{FN;} ; \
|
2024-03-26 14:57:35 -05:00
|
|
|
JS_FreeCString(js,str); \
|
|
|
|
) \
|
|
|
|
|
|
|
|
#define JSC_SSCALL(NAME, FN) JSC_CCALL(NAME, \
|
|
|
|
const char *str = js2str(argv[0]); \
|
|
|
|
const char *str2 = js2str(argv[1]); \
|
|
|
|
FN ; \
|
|
|
|
JS_FreeCString(js,str2); \
|
|
|
|
JS_FreeCString(js,str); \
|
|
|
|
) \
|
|
|
|
|
2024-04-09 16:48:15 -05:00
|
|
|
#define MIST_CGETSET_BASE(name, fgetter, fsetter, props) { name, props, JS_DEF_CGETSET, 0, .u = { .getset = { .get = { .getter = fgetter }, .set = { .setter = fsetter } } } }
|
|
|
|
#define MIST_CGETSET_DEF(name, fgetter, fsetter) MIST_CGETSET_BASE(name, fgetter, fsetter, JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE)
|
|
|
|
#define MIST_CGETET_HID(name, fgetter, fsetter) MIST_CGETSET_BASE(name, fgetter, fsetter, JS_PROP_CONFIGURABLE)
|
2024-03-26 14:57:35 -05:00
|
|
|
#define MIST_GET(name, fgetter) { #fgetter , JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE, JS_DEF_CGETSET, 0, .u = { .getset = { .get = { .getter = js_##name##_get_##fgetter } } } }
|
|
|
|
|
2024-04-10 16:21:46 -05:00
|
|
|
#define CGETSET_ADD_NAME(ID, ENTRY, NAME) MIST_CGETSET_DEF(#NAME, js_##ID##_get_##ENTRY, js_##ID##_set_##ENTRY)
|
2024-03-26 14:57:35 -05:00
|
|
|
#define CGETSET_ADD(ID, ENTRY) MIST_CGETSET_DEF(#ENTRY, js_##ID##_get_##ENTRY, js_##ID##_set_##ENTRY)
|
2024-04-09 16:48:15 -05:00
|
|
|
#define CGETSET_ADD_HID(ID, ENTRY) MIST_CGETSET_BASE(#ENTRY, js_##ID##_get_##ENTRY, js_##ID##_set_##ENTRY, JS_PROP_CONFIGURABLE)
|
2024-03-26 14:57:35 -05:00
|
|
|
|
2024-05-21 18:50:53 -05:00
|
|
|
#define JSC_CCALL(NAME, FN) JSValue js_##NAME (JSContext *js, JSValue self, int argc, JSValue *argv) { \
|
2024-03-26 14:57:35 -05:00
|
|
|
JSValue ret = JS_UNDEFINED; \
|
|
|
|
{FN;} \
|
|
|
|
return ret; \
|
|
|
|
} \
|
|
|
|
|
|
|
|
#define GETSETPAIR(ID, ENTRY, TYPE, FN) \
|
2024-05-17 12:39:04 -05:00
|
|
|
JSValue js_##ID##_set_##ENTRY (JS_SETSIG) { \
|
2024-05-21 18:50:53 -05:00
|
|
|
js2##ID (self)->ENTRY = js2##TYPE (val); \
|
2024-03-26 14:57:35 -05:00
|
|
|
{FN;} \
|
|
|
|
return JS_UNDEFINED; \
|
|
|
|
} \
|
|
|
|
\
|
2024-05-21 18:50:53 -05:00
|
|
|
JSValue js_##ID##_get_##ENTRY (JSContext *js, JSValue self) { \
|
|
|
|
return TYPE##2js(js2##ID (self)->ENTRY); \
|
2024-03-26 14:57:35 -05:00
|
|
|
} \
|
|
|
|
|
|
|
|
#define JSC_GETSET(ID, ENTRY, TYPE) GETSETPAIR( ID , ENTRY , TYPE , ; )
|
2024-05-21 18:50:53 -05:00
|
|
|
#define JSC_GETSET_APPLY(ID, ENTRY, TYPE) GETSETPAIR(ID, ENTRY, TYPE, ID##_apply(js2##ID (self));)
|
2024-03-26 14:57:35 -05:00
|
|
|
#define JSC_GETSET_HOOK(ID, ENTRY) GETSETPAIR(ID, ENTRY, JSValue, ;)
|
|
|
|
|
|
|
|
#define JSC_GETSET_GLOBAL(ENTRY, TYPE) \
|
2024-05-17 12:39:04 -05:00
|
|
|
JSValue js_global_set_##ENTRY (JS_SETSIG) { \
|
2024-03-26 14:57:35 -05:00
|
|
|
ENTRY = js2##TYPE (val); \
|
|
|
|
return JS_UNDEFINED; \
|
|
|
|
} \
|
|
|
|
\
|
2024-05-21 18:50:53 -05:00
|
|
|
JSValue js_global_get_##ENTRY (JSContext *js, JSValue self) { \
|
2024-03-26 14:57:35 -05:00
|
|
|
return TYPE##2js(ENTRY); \
|
|
|
|
} \
|
|
|
|
|
|
|
|
#define JSC_GETSET_BODY(ENTRY, CPENTRY, TYPE) \
|
2024-05-17 12:39:04 -05:00
|
|
|
JSValue js_gameobject_set_##ENTRY (JS_SETSIG) { \
|
2024-05-21 18:50:53 -05:00
|
|
|
cpBody *b = js2gameobject(self)->body; \
|
2024-03-26 14:57:35 -05:00
|
|
|
cpBodySet##CPENTRY (b, js2##TYPE (val)); \
|
|
|
|
return JS_UNDEFINED; \
|
|
|
|
} \
|
|
|
|
\
|
2024-05-21 18:50:53 -05:00
|
|
|
JSValue js_gameobject_get_##ENTRY (JSContext *js, JSValue self) { \
|
|
|
|
cpBody *b = js2gameobject(self)->body; \
|
2024-03-26 14:57:35 -05:00
|
|
|
return TYPE##2js (cpBodyGet##CPENTRY (b)); \
|
|
|
|
} \
|
|
|
|
|
|
|
|
#define JSC_GET(ID, ENTRY, TYPE) \
|
2024-05-21 18:50:53 -05:00
|
|
|
JSValue js_##ID##_get_##ENTRY (JSContext *js, JSValue self) { \
|
|
|
|
return TYPE##2js(js2##ID (self)->ENTRY); } \
|
2024-03-26 14:57:35 -05:00
|
|
|
|
|
|
|
#define QJSCLASS(TYPE)\
|
|
|
|
static JSClassID js_##TYPE##_id;\
|
|
|
|
static void js_##TYPE##_finalizer(JSRuntime *rt, JSValue val){\
|
|
|
|
TYPE *n = JS_GetOpaque(val, js_##TYPE##_id);\
|
|
|
|
TYPE##_free(n);}\
|
|
|
|
static JSClassDef js_##TYPE##_class = {\
|
|
|
|
#TYPE,\
|
|
|
|
.finalizer = js_##TYPE##_finalizer,\
|
|
|
|
};\
|
2024-05-28 13:39:02 -05:00
|
|
|
TYPE *js2##TYPE (JSValue val) { \
|
2024-07-18 17:09:35 -05:00
|
|
|
if (JS_IsUndefined(val)) return NULL; \
|
2024-05-28 13:39:02 -05:00
|
|
|
assert(JS_GetClassID(val) == js_##TYPE##_id); \
|
|
|
|
return JS_GetOpaque(val,js_##TYPE##_id); \
|
|
|
|
}\
|
2024-05-20 13:50:57 -05:00
|
|
|
JSValue TYPE##2js(TYPE *n) { \
|
2024-03-26 14:57:35 -05:00
|
|
|
JSValue j = JS_NewObjectClass(js,js_##TYPE##_id);\
|
|
|
|
JS_SetOpaque(j,n);\
|
|
|
|
return j; }\
|
2024-04-02 07:41:46 -05:00
|
|
|
\
|
2024-05-21 18:50:53 -05:00
|
|
|
static JSValue js_##TYPE##_memid (JSContext *js, JSValue self) { return str2js("%p", js2##TYPE(self)); } \
|
2024-08-05 15:26:18 -05:00
|
|
|
static JSValue js_##TYPE##_memsize (JSContext *js, JSValue self) { return number2js(sizeof(TYPE)); } \
|
2024-03-26 14:57:35 -05:00
|
|
|
|
|
|
|
#define QJSGLOBALCLASS(NAME) \
|
|
|
|
JSValue NAME = JS_NewObject(js); \
|
|
|
|
JS_SetPropertyFunctionList(js, NAME, js_##NAME##_funcs, countof(js_##NAME##_funcs)); \
|
|
|
|
JS_SetPropertyStr(js, globalThis, #NAME, NAME); \
|
|
|
|
|
|
|
|
#define QJSCLASSPREP(TYPE) \
|
|
|
|
JS_NewClassID(&js_##TYPE##_id);\
|
|
|
|
JS_NewClass(JS_GetRuntime(js), js_##TYPE##_id, &js_##TYPE##_class);\
|
|
|
|
|
|
|
|
/* Defines a class and uses its function list as its prototype */
|
|
|
|
#define QJSCLASSPREP_FUNCS(TYPE) \
|
|
|
|
QJSCLASSPREP(TYPE); \
|
|
|
|
JSValue TYPE##_proto = JS_NewObject(js); \
|
|
|
|
JS_SetPropertyFunctionList(js, TYPE##_proto, js_##TYPE##_funcs, countof(js_##TYPE##_funcs)); \
|
2024-04-02 07:41:46 -05:00
|
|
|
JS_SetPropertyStr(js, TYPE##_proto, "memid", JS_NewCFunction(js, &js_##TYPE##_memid, "memid", 0)); \
|
2024-08-05 15:26:18 -05:00
|
|
|
JS_SetPropertyStr(js, TYPE##_proto, "memsize", JS_NewCFunction(js, &js_##TYPE##_memsize, "memsize", 0)); \
|
2024-03-26 14:57:35 -05:00
|
|
|
JS_SetClassProto(js, js_##TYPE##_id, TYPE##_proto); \
|
|
|
|
|
|
|
|
#define countof(x) (sizeof(x)/sizeof((x)[0]))
|
|
|
|
|
2023-01-10 07:13:00 -06:00
|
|
|
void ffi_load();
|
|
|
|
|
2024-03-13 03:51:44 -05:00
|
|
|
JSValue vec22js(HMM_Vec2 v);
|
2023-11-14 09:20:09 -06:00
|
|
|
HMM_Vec2 js2vec2(JSValue v);
|
2024-09-14 23:42:46 -05:00
|
|
|
HMM_Vec4 js2vec4(JSValue v);
|
2023-02-02 17:52:15 -06:00
|
|
|
|
2024-05-21 18:50:53 -05:00
|
|
|
const char *js2str(JSValue v);
|
|
|
|
char *js2strdup(JSValue v);
|
|
|
|
|
2023-04-18 14:49:17 -05:00
|
|
|
JSValue bitmask2js(cpBitmask mask);
|
|
|
|
cpBitmask js2bitmask(JSValue v);
|
2023-10-10 17:37:58 -05:00
|
|
|
int js_print_exception(JSValue v);
|
2023-02-02 17:52:15 -06:00
|
|
|
|
2023-05-16 01:31:13 -05:00
|
|
|
struct rgba js2color(JSValue v);
|
2024-09-14 23:42:46 -05:00
|
|
|
|
2023-04-19 15:16:35 -05:00
|
|
|
double js2number(JSValue v);
|
2024-01-14 10:24:31 -06:00
|
|
|
JSValue number2js(double g);
|
2024-05-21 18:50:53 -05:00
|
|
|
|
|
|
|
uint64_t js2uint64(JSValue v);
|
|
|
|
|
2024-04-02 07:41:46 -05:00
|
|
|
JSValue str2js(const char *c, ...);
|
2023-04-18 17:58:44 -05:00
|
|
|
|
2024-08-25 15:29:35 -05:00
|
|
|
struct texture;
|
|
|
|
struct texture *js2texture(JSValue v);
|
|
|
|
|
2024-01-14 12:56:52 -06:00
|
|
|
void nota_int(char *blob);
|
|
|
|
|
2024-09-14 09:36:40 -05:00
|
|
|
void js_setprop_num(JSValue a, uint32_t n, JSValue v);
|
2024-04-30 10:32:27 -05:00
|
|
|
JSValue js_getpropidx(JSValue v, uint32_t i);
|
|
|
|
JSValue js_getpropstr(JSValue v, const char *str);
|
|
|
|
void jsfreestr(const char *str);
|
2024-05-06 21:59:22 -05:00
|
|
|
int js_arrlen(JSValue v);
|
2024-05-21 18:50:53 -05:00
|
|
|
void js_setpropstr(JSValue v, const char *str, JSValue p);
|
2024-09-04 07:41:48 -05:00
|
|
|
void js2floatarr(JSValue v, int n, float *a);
|
|
|
|
JSValue floatarr2js(int n, float *a);
|
2024-05-21 18:50:53 -05:00
|
|
|
|
2024-09-14 09:36:40 -05:00
|
|
|
float *js2newfloatarr(JSValue v);
|
|
|
|
|
2024-05-21 18:50:53 -05:00
|
|
|
int js2boolean(JSValue v);
|
|
|
|
JSValue boolean2js(int b);
|
|
|
|
|
2024-09-04 13:23:20 -05:00
|
|
|
char **js2strarr(JSValue v);
|
|
|
|
|
2024-05-21 18:50:53 -05:00
|
|
|
#define PREP_PARENT(TYPE, PARENT) \
|
|
|
|
TYPE##_proto = JS_NewObject(js); \
|
|
|
|
JS_SetPropertyFunctionList(js, TYPE##_proto, js_##TYPE##_funcs, countof(js_##TYPE##_funcs)); \
|
|
|
|
JS_SetPrototype(js, TYPE##_proto, PARENT##_proto); \
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
2024-04-30 10:32:27 -05:00
|
|
|
|
2023-02-02 17:52:15 -06:00
|
|
|
#endif
|