diff options
author | Determinant <[email protected]> | 2015-06-22 19:01:29 +0800 |
---|---|---|
committer | Determinant <[email protected]> | 2015-06-22 19:01:29 +0800 |
commit | 2497fd9e7a0fae5ee4887890d7a312e0e08a93b8 (patch) | |
tree | 382f97575bd2df9ee6abb1662b11b279fc22d72b /nerv/examples/oop_example.c | |
parent | 196e9b48a3541caccdffc5743001cced70667091 (diff) |
major change: use luarocks to manage project
Diffstat (limited to 'nerv/examples/oop_example.c')
-rw-r--r-- | nerv/examples/oop_example.c | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/nerv/examples/oop_example.c b/nerv/examples/oop_example.c new file mode 100644 index 0000000..59dfc5a --- /dev/null +++ b/nerv/examples/oop_example.c @@ -0,0 +1,101 @@ +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include "../common.h" + +#define SQR(x) ((x) * (x)) + +const char *point_tname = "nerv.Point"; +const char *better_point_tname = "nerv.BetterPoint"; + +typedef struct { + double x, y; +} Point; + +static int point_norm (lua_State *L) { + Point *p = luaT_checkudata(L, 1, point_tname); + lua_pushnumber(L, sqrt(SQR(p->x) + SQR(p->y))); + return 1; +} + +static int point_set_x (lua_State *L) { + Point *p = luaT_checkudata(L, 1, point_tname); + p->x = luaL_checknumber(L, 2); + return 0; +} + +static int point_set_y (lua_State *L) { + Point *p = luaT_checkudata(L, 1, point_tname); + p->y = luaL_checknumber(L, 2); + return 0; +} + +/* generic constructor */ +void point_new_(Point *self, double x, double y) { + self->x = x; + self->y = y; +} + +int point_new(lua_State *L) { + /* `_new` function should create the object itself */ + Point *self = (Point *)malloc(sizeof(Point)); + point_new_(self, luaL_checknumber(L, 1), luaL_checknumber(L, 2)); + luaT_pushudata(L, self, point_tname); + fprintf(stderr, "[example] %s constructor is invoked\n", + point_tname); + return 1; +} + +static const luaL_Reg point_methods[] = { + {"set_x", point_set_x}, + {"set_y", point_set_y}, + {"norm", point_norm}, + {NULL, NULL} +}; + + +/* the subclass method overrides the one from baseclass */ +static int better_point_norm (lua_State *L) { + Point *p = luaT_checkudata(L, 1, point_tname); + lua_pushnumber(L, fabs(p->x) + fabs(p->y)); + return 1; +} + +int better_point_new(lua_State *L) { + /* `_new` function should create the object itself */ + Point *self = (Point *)malloc(sizeof(Point)); + point_new_(self, luaL_checknumber(L, 1), luaL_checknumber(L, 2)); + luaT_pushudata(L, self, better_point_tname); + fprintf(stderr, "[example] %s constructor is invoked\n", + better_point_tname); + return 1; +} + +static const luaL_Reg better_point_methods[] = { + {"norm", better_point_norm}, + {NULL, NULL} +}; + +void nerv_point_init(lua_State *L) { + /* create a class and let luaT know */ + luaT_newmetatable(L, point_tname, NULL, point_new, NULL, NULL); + /* register member functions */ + luaL_register(L, NULL, point_methods); + /* keep the stack balanced, see `nerv.c` */ + lua_pop(L, 1); +} + +void nerv_better_point_init(lua_State *L) { + /* create a class and let luaT know */ + luaT_newmetatable(L, better_point_tname, point_tname, + better_point_new, NULL, NULL); + /* register member functions */ + luaL_register(L, NULL, better_point_methods); + /* keep the stack balanced, see `nerv.c` */ + lua_pop(L, 1); +} + +void nerv_example_init(lua_State *L) { + nerv_point_init(L); + nerv_better_point_init(L); +} |