~rootmos/lua-hack

a74fe9dcef4ea9cda234956dc37d52b16d043e5f — Gustav Behm 7 months ago 34ae9de
Add an notification object
2 files changed, 89 insertions(+), 11 deletions(-)

M notify/go.lua
M notify/notify.c
M notify/go.lua => notify/go.lua +2 -1
@@ 1,3 1,4 @@
local N = require("notify")
N.name = "foo"
print(N.name)

local n = N:new()

M notify/notify.c => notify/notify.c +87 -10
@@ 7,23 7,96 @@
#include "r.h"

#define TYPE_NOTIFY "notify"
#define TYPE_NOTIFICATION "notify.notification"

struct notify {
    int ref;
};

static struct notify* notify_ref(struct notify* notify)
{
    notify->ref += 1;
    return notify;
}

static void notify_unref(struct notify* notify)
{
    if(--notify->ref == 0) {
        debug("libnotify uninit");
        notify_uninit();
    }
}

static int notify_gc(lua_State* L)
{
    luaR_stack(L);
    notify_unref(luaL_checkudata(L, 1, TYPE_NOTIFY));
    luaR_return(L, 0);
}


    debug("libnotify uninit");
    notify_uninit();
struct notification {
    int ref;
    struct notify* notify;

    NotifyNotification* n;
};

static struct notification* notification_ref(struct notification* notification)
{
    notification->ref += 1;
    return notification;
}

static void notification_unref(struct notification* notification)
{
    if(--notification->ref == 0) {
        g_object_unref(G_OBJECT(notification->n));
        notify_unref(notification->notify);
    }
}

static int notification_gc(lua_State* L)
{
    luaR_stack(L);
    notification_unref(luaL_checkudata(L, 1, TYPE_NOTIFICATION));
    luaR_return(L, 0);
}

static int notification_new(lua_State* L)
{
    luaR_stack(L);
    struct notify* notify = luaL_checkudata(L, 1, TYPE_NOTIFY);

    struct notification* notification = lua_newuserdatauv(L, sizeof(struct notification), 0);
    memset(notification, 0, sizeof(*notification));
    notification_ref(notification);
    notification->notify = notify_ref(notify);

    notification->n = notify_notification_new("hello", NULL, NULL);
    CHECK_NOT(notification->n, NULL, "notify_notification_new");

    if(luaL_newmetatable(L, TYPE_NOTIFICATION)) {
        lua_pushcfunction(L, notification_gc);
        lua_setfield(L, -2, "__gc");
    }
    lua_setmetatable(L, -2);

    luaR_return(L, 1);
}

static int notify_index(lua_State* L)
{
    luaR_stack(L);
    luaR_checkmetatable(L, 1, TYPE_NOTIFY);
    luaL_checkany(L, 2);

    lua_pushvalue(L, 2);
    if(lua_gettable(L, lua_upvalueindex(1)) != LUA_TNIL) {
        luaR_return(L, 1);
    }
    lua_pop(L, 1);

    lua_pushliteral(L, "name");
    int r = lua_rawequal(L, 2, -1);
    lua_pop(L, 1);


@@ 61,23 134,27 @@ int luaopen_notify(lua_State* L)
    luaL_checkversion(L);
    luaR_stack(L);

    struct notify* notify = lua_newuserdatauv(L, sizeof(struct notify), 0);
    memset(notify, 0, sizeof(*notify));
    notify_ref(notify);

    if(notify_init("lua") != TRUE) {
        return luaL_error(L, "unable to initialize libnotify");
    }
    debug("libnotify init: %s", notify_get_app_name());

    luaL_Reg l[] = {
        { NULL, NULL },
    };
    luaL_newlib(L, l);

    if(luaL_newmetatable(L, TYPE_NOTIFY)) {
        luaL_Reg l[] = {
            { "new", notification_new },
            { NULL, NULL },
        };
        luaL_newlib(L, l);
        lua_pushcclosure(L, notify_index, 1);
        lua_setfield(L, -2, "__index");

        lua_pushcfunction(L, notify_gc);
        lua_setfield(L, -2, "__gc");

        lua_pushcfunction(L, notify_index);
        lua_setfield(L, -2, "__index");

        lua_pushcfunction(L, notify_newindex);
        lua_setfield(L, -2, "__newindex");
    }