int jive_style_array_int(lua_State *L, int index, const char *array, int n, const char *key, int def) { int value; JIVEL_STACK_CHECK_BEGIN(L); lua_pushcfunction(L, jiveL_style_array_value); lua_pushvalue(L, index); lua_pushstring(L, array); lua_pushnumber(L, n); lua_pushstring(L, key); lua_pushinteger(L, def); lua_call(L, 5, 1); if (lua_isboolean(L, -1)) { value = lua_toboolean(L, -1); } else { value = lua_tointeger(L, -1); } lua_pop(L, 1); JIVEL_STACK_CHECK_END(L); return value; }
int jive_style_array_size(lua_State *L, int index, char *key) { size_t size = 0; JIVEL_STACK_CHECK_BEGIN(L); lua_pushcfunction(L, jiveL_style_value); lua_pushvalue(L, index); lua_pushstring(L, key); lua_pushnil(L); lua_call(L, 3, 1); if (lua_type(L, -1) != LUA_TTABLE) { lua_pop(L, 1); JIVEL_STACK_CHECK_ASSERT(L); return 0; } /* the array should use integer indexes, but it may be sparse * so iterate over is to find the maximum index. */ lua_pushnil(L); while (lua_next(L, -2) != 0) { size = MAX(size, lua_tonumber(L, -2)); lua_pop(L, 1); } lua_pop(L, 1); JIVEL_STACK_CHECK_END(L); return size; }
Uint32 jive_style_array_color(lua_State *L, int index, const char *array, int n, const char *key, Uint32 def, bool *is_set) { Uint32 col; JIVEL_STACK_CHECK_BEGIN(L); lua_pushcfunction(L, jiveL_style_array_color); lua_pushvalue(L, index); lua_pushstring(L, array); lua_pushnumber(L, n); lua_pushstring(L, key); lua_pushnil(L); lua_call(L, 5, 1); if (lua_isnil(L, -1)) { lua_pop(L, 1); if (is_set) { *is_set = 0; } return def; } col = (Uint32) lua_tointeger(L, -1); if (is_set) { *is_set = 1; } lua_pop(L, 1); JIVEL_STACK_CHECK_END(L); return col; }
static int jiveL_process_events(lua_State *L) { Uint32 r = 0; SDL_Event event; /* stack: * 1 : jive.ui.Framework */ JIVEL_STACK_CHECK_BEGIN(L); /* Exit if we have no windows */ lua_getfield(L, 1, "windowStack"); if (lua_objlen(L, -1) == 0) { lua_pop(L, 1); lua_pushboolean(L, 0); return 1; } lua_rawgeti(L, -1, 1); /* pump keyboard/mouse events once per frame */ SDL_PumpEvents(); if (jive_sdlevent_pump) { jive_sdlevent_pump(L); } /* process events */ process_timers(L); while (SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_ALLEVENTS) > 0 ) { r |= process_event(L, &event); } lua_pop(L, 2); JIVEL_STACK_CHECK_END(L); if (r & JIVE_EVENT_QUIT) { lua_pushboolean(L, 0); return 1; } lua_pushboolean(L, 1); return lua_yield(L, 1); }
JiveTile *jive_style_tile(lua_State *L, int index, const char *key, JiveTile *def) { JiveTile *value; JIVEL_STACK_CHECK_BEGIN(L); lua_pushcfunction(L, jiveL_style_value); lua_pushvalue(L, index); lua_pushstring(L, key); tolua_pushusertype(L, def, "Tile"); lua_call(L, 3, 1); value = tolua_tousertype(L, -1, 0); lua_pop(L, 1); JIVEL_STACK_CHECK_END(L); return value; }
JiveFont *jive_style_array_font(lua_State *L, int index, const char *array, int n, const char *key) { JiveFont *value; JIVEL_STACK_CHECK_BEGIN(L); lua_pushcfunction(L, jiveL_style_array_value); lua_pushvalue(L, index); lua_pushstring(L, array); lua_pushnumber(L, n); lua_pushstring(L, key); lua_pushnil(L); lua_call(L, 5, 1); value = (JiveFont *) tolua_tousertype(L, -1, NULL); lua_pop(L, 1); JIVEL_STACK_CHECK_END(L); return value; }
JiveAlign jive_style_align(lua_State *L, int index, char *key, JiveAlign def) { int v; const char *options[] = { "center", "left", "right", "top", "bottom", "top-left", "top-right", "bottom-left", "bottom-right", NULL }; JIVEL_STACK_CHECK_BEGIN(L); lua_pushcfunction(L, jiveL_style_value); lua_pushvalue(L, index); lua_pushstring(L, key); lua_pushnil(L); lua_call(L, 3, 1); if (lua_isnil(L, -1)) { lua_pop(L, 1); JIVEL_STACK_CHECK_ASSERT(L); return def; } v = luaL_checkoption(L, -1, options[def], options); lua_pop(L, 1); JIVEL_STACK_CHECK_END(L); return (JiveAlign) v; }
void jive_style_insets(lua_State *L, int index, char *key, JiveInset *inset) { JIVEL_STACK_CHECK_BEGIN(L); lua_pushcfunction(L, jiveL_style_value); lua_pushvalue(L, index); lua_pushstring(L, key); lua_pushnil(L); lua_call(L, 3, 1); if (lua_isinteger(L, -1)) { int v = lua_tointeger(L, -1); inset->left = v; inset->top = v; inset->right = v; inset->bottom = v; } else if (lua_istable(L, -1)) { lua_rawgeti(L, -1, 1); lua_rawgeti(L, -2, 2); lua_rawgeti(L, -3, 3); lua_rawgeti(L, -4, 4); inset->left = luaL_optinteger(L, -4, 0); inset->top = luaL_optinteger(L, -3, 0); inset->right = luaL_optinteger(L, -2, 0); inset->bottom = luaL_optinteger(L, -1, 0); lua_pop(L, 4); } else { memset(inset, 0, sizeof(JiveInset)); } lua_pop(L, 1); JIVEL_STACK_CHECK_END(L); }
static int _draw_screen(lua_State *L) { JiveSurface *srf; Uint32 t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0; clock_t c0 = 0, c1 = 0; bool_t standalone_draw, drawn = false; JIVEL_STACK_CHECK_BEGIN(L); /* stack is: * 1: framework * 2: surface (in screen format) * 3: standalone_draw (used to draw screen to a new surface) */ srf = tolua_tousertype(L, 2, 0); standalone_draw = lua_toboolean(L, 3); /* Exit if we have no windows, nothing to draw */ lua_getfield(L, 1, "windowStack"); if (lua_objlen(L, -1) == 0) { lua_pop(L, 1); JIVEL_STACK_CHECK_ASSERT(L); return 0; } lua_rawgeti(L, -1, 1); // topwindow if (perfwarn.screen) { t0 = jive_jiffies(); c0 = clock(); } do { jive_origin = next_jive_origin; /* Layout window and widgets */ if (jive_getmethod(L, -1, "checkLayout")) { lua_pushvalue(L, -2); lua_call(L, 1, 0); } /* check in case the origin changes during layout */ } while (jive_origin != next_jive_origin); if (perfwarn.screen) t1 = jive_jiffies(); /* Widget animations - don't update in a standalone draw as its not the main screen update */ if (!standalone_draw) { lua_getfield(L, 1, "animations"); lua_pushnil(L); while (lua_next(L, -2) != 0) { lua_getfield(L, -1, "animations"); lua_pushnil(L); while (lua_next(L, -2) != 0) { int frame; /* stack is: * -2: key * -1: table */ lua_rawgeti(L, -1, 2); frame = lua_tointeger(L, -1) - 1; if (frame == 0) { lua_rawgeti(L, -2, 1); // function lua_pushvalue(L, -6); // widget lua_call(L, 1, 0); // function is poped by lua_call lua_rawgeti(L, -2, 3); lua_rawseti(L, -3, 2); } else { lua_pushinteger(L, frame); lua_rawseti(L, -3, 2); } lua_pop(L, 2); } lua_pop(L, 2); } lua_pop(L, 1); } if (perfwarn.screen) t2 = jive_jiffies(); /* Window transitions */ lua_getfield(L, 1, "transition"); if (!lua_isnil(L, -1)) { /* Draw background */ jive_surface_set_clip(srf, NULL); jive_tile_set_alpha(jive_background, 0); // no alpha channel jive_tile_blit(jive_background, srf, 0, 0, screen_w, screen_h); if (perfwarn.screen) t3 = jive_jiffies(); /* Animate screen transition */ lua_pushvalue(L, -1); lua_pushvalue(L, -3); // widget lua_pushvalue(L, 2); // surface lua_call(L, 2, 0); drawn = true; } else if (jive_dirty_region.w || standalone_draw) { SDL_Rect dirty; /* only redraw dirty region for non standalone draws */ if (!standalone_draw) { jive_rect_union(&jive_dirty_region, &last_dirty_region, &dirty); jive_surface_set_clip(srf, &dirty); } #if 0 printf("REDRAW: %d,%d %dx%d\n", jive_dirty_region.x, jive_dirty_region.y, jive_dirty_region.w, jive_dirty_region.h); printf("--> %d,%d %dx%d\n", dirty.x, dirty.y, dirty.w, dirty.h); #endif /* Draw background */ jive_tile_blit(jive_background, srf, 0, 0, screen_w, screen_h); if (perfwarn.screen) t3 = jive_jiffies(); /* Draw screen */ if (jive_getmethod(L, -2, "draw")) { lua_pushvalue(L, -3); // widget lua_pushvalue(L, 2); // surface lua_pushinteger(L, JIVE_LAYER_ALL); // layer lua_call(L, 3, 0); } #if 0 // show the dirty region for debug purposes: jive_surface_rectangleColor(srf, jive_dirty_region.x, jive_dirty_region.y, jive_dirty_region.x + jive_dirty_region.w, jive_dirty_region.y + jive_dirty_region.h, 0xFFFFFFFF); #endif /* clear the dirty region for non standalone draws */ if (!standalone_draw) { memcpy(&last_dirty_region, &jive_dirty_region, sizeof(last_dirty_region)); jive_dirty_region.w = 0; } drawn = true; } if (perfwarn.screen) { t4 = jive_jiffies(); c1 = clock(); if (t4-t0 > perfwarn.screen) { if (!t3) { t3 = t2; } printf("update_screen > %dms: %4dms (%dms) [layout:%dms animate:%dms background:%dms draw:%dms]\n", perfwarn.screen, t4-t0, (int)((c1-c0) * 1000 / CLOCKS_PER_SEC), t1-t0, t2-t1, t3-t2, t4-t3); } } lua_pop(L, 3); JIVEL_STACK_CHECK_END(L); lua_pushboolean(L, drawn); return 1; }