Example #1
0
/** Newindex function of wtable objects.
 * \param L The Lua VM state.
 * \return The number of elements pushed on stack.
 */
static int
luaA_wtable_newindex(lua_State *L)
{
    bool invalid = false;

    /* push key on top */
    lua_pushvalue(L, 2);
    /* get current key value in content table */
    lua_rawget(L, lua_upvalueindex(1));
    /* if value is a widget, notify change */
    if(lua_istable(L, -1) || luaA_toudata(L, -1, &widget_class))
        invalid = true;

    lua_pop(L, 1); /* remove value */

    /* if new value is a widget or a table */
    if(lua_istable(L, 3))
    {
        luaA_table2wtable(L);
        invalid = true;
    }
    else if(!invalid && luaA_toudata(L, 3, &widget_class))
        invalid = true;

    /* upvalue 1 is content table */
    lua_rawset(L, lua_upvalueindex(1));

    if(invalid)
        luaA_wibox_invalidate_byitem(L, lua_topointer(L, 1));

    return 0;
}
Example #2
0
/** Convert a Lua table to a list of widget nodes.
 * \param L The Lua VM state.
 * \param widgets The linked list of widget node.
 */
static void
luaA_table2widgets(lua_State *L, widget_node_array_t *widgets)
{
    if(lua_istable(L, -1))
    {
        lua_pushnil(L);
        while(luaA_next(L, -2))
            luaA_table2widgets(L, widgets);
        /* remove the table */
        lua_pop(L, 1);
    }
    else
    {
        widget_t *widget = luaA_toudata(L, -1, &widget_class);
        if(widget)
        {
            widget_node_t w;
            p_clear(&w, 1);
            w.widget = luaA_object_ref(L, -1);
            widget_node_array_append(widgets, w);
        }
        else
            lua_pop(L, 1); /* remove value */
    }
}
Example #3
0
/** Emit a signal.
 * @tparam string name A signal name.
 * @param[opt] ... Various arguments.
 * @function emit_signal
 */
void
luaA_object_emit_signal(lua_State *L, int oud,
                        const char *name, int nargs)
{
    int oud_abs = luaA_absindex(L, oud);
    lua_class_t *lua_class = luaA_class_get(L, oud);
    lua_object_t *obj = luaA_toudata(L, oud, lua_class);
    if(!obj) {
        luaA_warn(L, "Trying to emit signal '%s' on non-object", name);
        return;
    }
    else if(lua_class->checker && !lua_class->checker(obj)) {
        luaA_warn(L, "Trying to emit signal '%s' on invalid object", name);
        return;
    }
    signal_t *sigfound = signal_array_getbyid(&obj->signals,
                                              a_strhash((const unsigned char *) name));
    if(sigfound)
    {
        int nbfunc = sigfound->sigfuncs.len;
        luaL_checkstack(L, lua_gettop(L) + nbfunc + nargs + 2, "too much signal");
        /* Push all functions and then execute, because this list can change
         * while executing funcs. */
        foreach(func, sigfound->sigfuncs)
            luaA_object_push_item(L, oud_abs, *func);

        for(int i = 0; i < nbfunc; i++)
        {
            /* push object */
            lua_pushvalue(L, oud_abs);
            /* push all args */
            for(int j = 0; j < nargs; j++)
                lua_pushvalue(L, - nargs - nbfunc - 1 + i);
            /* push first function */
            lua_pushvalue(L, - nargs - nbfunc - 1 + i);
            /* remove this first function */
            lua_remove(L, - nargs - nbfunc - 2 + i);
            luaA_dofunction(L, nargs + 1, 0);
        }
    } else {
        luaA_warn(L, "Trying to emit unknown signal '%s'", name);
        return;
    }

    /* Then emit signal on the class */
    lua_pushvalue(L, oud);
    lua_insert(L, - nargs - 1);
    luaA_class_emit_signal(L, luaA_class_get(L, - nargs - 1), name, nargs + 1);
}
Example #4
0
/** Set a key array with a Lua table.
 * \param L The Lua VM state.
 * \param oidx The index of the object to store items into.
 * \param idx The index of the Lua table.
 * \param keys The array key to fill.
 */
void
luaA_key_array_set(lua_State *L, int oidx, int idx, key_array_t *keys)
{
    luaA_checktable(L, idx);

    foreach(key, *keys)
        luaA_object_unref_item(L, oidx, *key);

    key_array_wipe(keys);
    key_array_init(keys);

    lua_pushnil(L);
    while(lua_next(L, idx))
        if(luaA_toudata(L, -1, &key_class))
            key_array_append(keys, luaA_object_ref_item(L, oidx, -1));
        else
            lua_pop(L, 1);
}
Example #5
0
/** Set a button array with a Lua table.
 * \param L The Lua VM state.
 * \param oidx The index of the object to store items into.
 * \param idx The index of the Lua table.
 * \param buttons The array button to fill.
 */
void
luaA_button_array_set(lua_State *L, int oidx, int idx, button_array_t *buttons)
{
    luaA_checktable(L, idx);

    foreach(button, *buttons)
        luaA_object_unref_item(L, oidx, *button);

    button_array_wipe(buttons);
    button_array_init(buttons);

    lua_pushnil(L);
    while(lua_next(L, idx))
        if(luaA_toudata(L, -1, &button_class))
            button_array_append(buttons, luaA_object_ref_item(L, oidx, -1));
        else
            lua_pop(L, 1);
}