examples/point.c: add PointEnumerable class
It is probably not trivial to guess that classes created like in the point example do not have enumerable properties (at least it was not for #315). Therefore PointEnumerable class describes how to implement such class.
This commit is contained in:
parent
6e2e68fd08
commit
ed3b3516a7
2 changed files with 95 additions and 2 deletions
|
@ -120,9 +120,77 @@ static const JSCFunctionListEntry js_point_proto_funcs[] = {
|
||||||
JS_CFUNC_DEF("norm", 0, js_point_norm),
|
JS_CFUNC_DEF("norm", 0, js_point_norm),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*PointEnumerable Class*/
|
||||||
|
|
||||||
|
static JSClassID js_pointEnumerable_class_id;
|
||||||
|
|
||||||
|
static void js_pointEnumerable_finalizer(JSRuntime *rt, JSValue val)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JSValue js_pointEnumerable_ctor(JSContext *ctx,
|
||||||
|
JSValueConst new_target,
|
||||||
|
int argc, JSValueConst *argv)
|
||||||
|
{
|
||||||
|
JSValue obj = JS_UNDEFINED;
|
||||||
|
JSValue proto;
|
||||||
|
|
||||||
|
/* using new_target to get the prototype is necessary when the
|
||||||
|
class is extended. */
|
||||||
|
proto = JS_GetPropertyStr(ctx, new_target, "prototype");
|
||||||
|
if (JS_IsException(proto))
|
||||||
|
goto fail;
|
||||||
|
obj = JS_NewObjectProtoClass(ctx, proto, js_pointEnumerable_class_id);
|
||||||
|
JS_FreeValue(ctx, proto);
|
||||||
|
JS_DefinePropertyValueStr(ctx, obj, "x", argv[0], JS_PROP_C_W_E);
|
||||||
|
JS_DefinePropertyValueStr(ctx, obj, "y", argv[1], JS_PROP_C_W_E);
|
||||||
|
if (JS_IsException(obj))
|
||||||
|
goto fail;
|
||||||
|
return obj;
|
||||||
|
fail:
|
||||||
|
JS_FreeValue(ctx, obj);
|
||||||
|
return JS_EXCEPTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JSValue js_pointEnumerable_norm(JSContext *ctx, JSValueConst this_val,
|
||||||
|
int argc, JSValueConst *argv)
|
||||||
|
{
|
||||||
|
JSValue val;
|
||||||
|
int ret, x, y;
|
||||||
|
|
||||||
|
val = JS_GetPropertyStr(ctx, this_val, "x");
|
||||||
|
if (JS_IsException(val))
|
||||||
|
return JS_EXCEPTION;
|
||||||
|
ret = JS_ToInt32(ctx, &x, val);
|
||||||
|
JS_FreeValue(ctx, val);
|
||||||
|
if (ret)
|
||||||
|
return JS_EXCEPTION;
|
||||||
|
|
||||||
|
val = JS_GetPropertyStr(ctx, this_val, "y");
|
||||||
|
if (JS_IsException(val))
|
||||||
|
return JS_EXCEPTION;
|
||||||
|
ret = JS_ToInt32(ctx, &y, val);
|
||||||
|
JS_FreeValue(ctx, val);
|
||||||
|
if (ret)
|
||||||
|
return JS_EXCEPTION;
|
||||||
|
|
||||||
|
return JS_NewFloat64(ctx, sqrt((double)x * x + (double)y * y));
|
||||||
|
}
|
||||||
|
|
||||||
|
static JSClassDef js_pointEnumerable_class = {
|
||||||
|
"PointEnumerable",
|
||||||
|
.finalizer = js_pointEnumerable_finalizer,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const JSCFunctionListEntry js_pointEnumerable_proto_funcs[] = {
|
||||||
|
JS_CFUNC_DEF("norm", 0, js_pointEnumerable_norm),
|
||||||
|
};
|
||||||
|
|
||||||
static int js_point_init(JSContext *ctx, JSModuleDef *m)
|
static int js_point_init(JSContext *ctx, JSModuleDef *m)
|
||||||
{
|
{
|
||||||
JSValue point_proto, point_class;
|
JSValue point_proto, point_class,
|
||||||
|
pointEnumerable_proto, pointEnumerable_class;
|
||||||
|
|
||||||
/* create the Point class */
|
/* create the Point class */
|
||||||
JS_NewClassID(&js_point_class_id);
|
JS_NewClassID(&js_point_class_id);
|
||||||
|
@ -137,6 +205,25 @@ static int js_point_init(JSContext *ctx, JSModuleDef *m)
|
||||||
JS_SetClassProto(ctx, js_point_class_id, point_proto);
|
JS_SetClassProto(ctx, js_point_class_id, point_proto);
|
||||||
|
|
||||||
JS_SetModuleExport(ctx, m, "Point", point_class);
|
JS_SetModuleExport(ctx, m, "Point", point_class);
|
||||||
|
|
||||||
|
/* create the PointEnumerable class */
|
||||||
|
JS_NewClassID(&js_pointEnumerable_class_id);
|
||||||
|
JS_NewClass(JS_GetRuntime(ctx), js_pointEnumerable_class_id,
|
||||||
|
&js_pointEnumerable_class);
|
||||||
|
|
||||||
|
pointEnumerable_proto = JS_NewObject(ctx);
|
||||||
|
JS_SetPropertyFunctionList(ctx, pointEnumerable_proto,
|
||||||
|
js_pointEnumerable_proto_funcs,
|
||||||
|
countof(js_pointEnumerable_proto_funcs));
|
||||||
|
|
||||||
|
pointEnumerable_class = JS_NewCFunction2(ctx, js_pointEnumerable_ctor,
|
||||||
|
"PointEnumerable", 2,
|
||||||
|
JS_CFUNC_constructor, 0);
|
||||||
|
/* set proto.constructor and ctor.prototype */
|
||||||
|
JS_SetConstructor(ctx, pointEnumerable_class, pointEnumerable_proto);
|
||||||
|
JS_SetClassProto(ctx, js_pointEnumerable_class_id, pointEnumerable_proto);
|
||||||
|
|
||||||
|
JS_SetModuleExport(ctx, m, "PointEnumerable", pointEnumerable_class);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,5 +234,6 @@ JSModuleDef *js_init_module(JSContext *ctx, const char *module_name)
|
||||||
if (!m)
|
if (!m)
|
||||||
return NULL;
|
return NULL;
|
||||||
JS_AddModuleExport(ctx, m, "Point");
|
JS_AddModuleExport(ctx, m, "Point");
|
||||||
|
JS_AddModuleExport(ctx, m, "PointEnumerable");
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/* example of JS module importing a C module */
|
/* example of JS module importing a C module */
|
||||||
import { Point } from "./point.so";
|
import { Point } from "./point.so";
|
||||||
|
import { PointEnumerable } from "./point.so";
|
||||||
|
|
||||||
function assert(b, str)
|
function assert(b, str)
|
||||||
{
|
{
|
||||||
|
@ -22,7 +23,7 @@ class ColorPoint extends Point {
|
||||||
|
|
||||||
function main()
|
function main()
|
||||||
{
|
{
|
||||||
var pt, pt2;
|
var pt, pt2, pt3;
|
||||||
|
|
||||||
pt = new Point(2, 3);
|
pt = new Point(2, 3);
|
||||||
assert(pt.x === 2);
|
assert(pt.x === 2);
|
||||||
|
@ -35,6 +36,10 @@ function main()
|
||||||
assert(pt2.x === 2);
|
assert(pt2.x === 2);
|
||||||
assert(pt2.color === 0xffffff);
|
assert(pt2.color === 0xffffff);
|
||||||
assert(pt2.get_color() === 0xffffff);
|
assert(pt2.get_color() === 0xffffff);
|
||||||
|
|
||||||
|
pt3 = new PointEnumerable(2, 3);
|
||||||
|
assert(JSON.stringify(pt) === "{}");
|
||||||
|
assert(JSON.stringify(pt3) === "{\"x\":2,\"y\":3}");
|
||||||
}
|
}
|
||||||
|
|
||||||
main();
|
main();
|
||||||
|
|
Loading…
Reference in a new issue