static int l_window___newindex(lua_State* L) { Window* win = l_toWindow(L, 1); const char* key = luaL_checkstring(L, 2); if (!lua_isfunction(L, 3)) return luaL_typerror(L, 3, "function"); if ((0 != strcmp("draw", key)) && (0 != strcmp("reshape", key)) && (0 != strcmp("update", key)) && (0 != strcmp("visibility", key)) && (0 != strcmp("keyboard", key)) && (0 != strcmp("mousereleased", key)) && (0 != strcmp("mousepressed", key)) && (0 != strcmp("mousedrag", key)) && (0 != strcmp("mousemove", key)) && (0 != strcmp("mouseleave", key)) && (0 != strcmp("mouseenter", key))) { return luaL_error(L, "Invalid key: %s", key); } // get callback registry for active window lua_pushstring(L, CALLBACKS_NAME); lua_rawget(L, LUA_REGISTRYINDEX); lua_pushinteger(L, win->id); lua_rawget(L, -2); // callbacks[win->id][key] = func lua_pushvalue(L, 2); lua_pushvalue(L, 3); lua_rawset(L, -3); return 0; }
static int l_window___index(lua_State* L) { luaL_getmetatable(L, INTERNAL_NAME); lua_pushvalue(L, 2); lua_gettable(L, -2); if (!lua_isnoneornil(L, -1)) return 1; if (!lua_isstring(L, 2)) return 0; const char* key = lua_tostring(L, 2); Window* win = l_toWindow(L, 1); if (get_callback(win->id, key)) return 1; int current = glutGetWindow(); glutSetWindow(win->id); if (0 == strcmp("pos", key)) { lua_createtable(L, 2, 0); lua_pushinteger(L, glutGet(GLUT_WINDOW_X)); lua_setfield(L, -2, "x"); lua_pushinteger(L, glutGet(GLUT_WINDOW_Y)); lua_setfield(L, -2, "y"); } else if (0 == strcmp("x", key)) { lua_pushinteger(L, glutGet(GLUT_WINDOW_X)); } else if (0 == strcmp("y", key)) { lua_pushinteger(L, glutGet(GLUT_WINDOW_Y)); } else if (0 == strcmp("size", key)) { lua_createtable(L, 2, 0); lua_pushinteger(L, glutGet(GLUT_WINDOW_WIDTH)); lua_setfield(L, -2, "width"); lua_pushinteger(L, glutGet(GLUT_WINDOW_HEIGHT)); lua_setfield(L, -2, "height"); } else if (0 == strcmp("width", key)) { lua_pushinteger(L, glutGet(GLUT_WINDOW_WIDTH)); } else if (0 == strcmp("height", key)) { lua_pushinteger(L, glutGet(GLUT_WINDOW_HEIGHT)); } else { lua_pushnil(L); } glutSetWindow(current); return 1; }