#ifndef JS_raylib_texture #define JS_raylib_texture #include #include #include #include #ifndef countof #define countof(x) (sizeof(x) / sizeof((x)[0])) #endif // 1. class id static JSClassID js_image_class_id; // 2. finalize static void js_image_finalizer(JSRuntime *rt, JSValue val) { Image *image = JS_GetOpaque(val, js_image_class_id); if (image) { puts("Finalize image"); UnloadImage(*image); js_free_rt(rt, image); } } // 3. getter/setter static JSValue js_image_get_width(JSContext *ctx, JSValueConst this_val) { Image *image = JS_GetOpaque2(ctx, this_val, js_image_class_id); if (!image) { return JS_EXCEPTION; } int width = image->width; return JS_NewInt32(ctx, width); } static JSValue js_image_get_height(JSContext *ctx, JSValueConst this_val) { Image *image = JS_GetOpaque2(ctx, this_val, js_image_class_id); if (!image) { return JS_EXCEPTION; } int height = image->height; return JS_NewInt32(ctx, height); } // 4. class members static const JSCFunctionListEntry js_image_proto_funcs[] = { JS_CGETSET_DEF("width", js_image_get_width, NULL), JS_CGETSET_DEF("height", js_image_get_height, NULL), JS_PROP_STRING_DEF("[Symbol.toStringTag]", "Image", JS_PROP_CONFIGURABLE), }; // 5. class declaration static int js_declare_image(JSContext *ctx, JSModuleDef *m){ // Define image struct JS_NewClassID(&js_image_class_id); JSClassDef js_image_class_def = { .class_name = "Image", .finalizer = js_image_finalizer, }; JS_NewClass(JS_GetRuntime(ctx), js_image_class_id, &js_image_class_def); JSValue proto = JS_NewObject(ctx); JS_SetPropertyFunctionList(ctx, proto, js_image_proto_funcs, countof(js_image_proto_funcs)); JS_SetClassProto(ctx, js_image_class_id, proto); return 0; } static JSValue js_LoadImage(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) { const char *filename = JS_ToCString(ctx, argv[0]); Image _struct = LoadImage(filename); Image* ptr = (Image*)js_malloc(ctx, sizeof(Image)); *ptr = _struct; JSValue obj = JS_NewObjectClass(ctx, js_image_class_id); JS_SetOpaque(obj, ptr); JS_FreeCString(ctx, filename); return obj; } static const JSCFunctionListEntry js_raylib_texture_funcs[] = { JS_CFUNC_DEF("loadImage", 1, js_LoadImage) }; static int js_raylib_texture_init(JSContext *ctx, JSModuleDef *m) { // 6. call declaration js_declare_image(ctx, m); JS_SetModuleExportList(ctx, m, js_raylib_texture_funcs, countof(js_raylib_texture_funcs)); // Implement constructor JSValue constr = JS_NewCFunction2(ctx, js_LoadImage, "Image", 4, JS_CFUNC_constructor_or_func, 0); JS_SetModuleExport(ctx, m, "Image", constr); // TODO export module constants //JS_SetModuleExport(ctx, m, "in", js_new_std_file(ctx, stdin, FALSE, FALSE)); return 0; } JSModuleDef *js_init_module_raylib_texture(JSContext *ctx, const char *module_name) { JSModuleDef *m; m = JS_NewCModule(ctx, module_name, js_raylib_texture_init); if (!m) return NULL; JS_AddModuleExportList(ctx, m, js_raylib_texture_funcs,countof(js_raylib_texture_funcs)); //TODO export module contants JS_AddModuleExport(ctx, m, "Image"); return m; } #endif