static int l_etable_add(lua_State *L) { struct aura_export_table *tbl; const char *name, *arg, *ret; TRACE(); aura_check_args(L, 4); if (!lua_islightuserdata(L, 1)) aura_typeerror(L, 1, "ludata"); if (!lua_isstring(L, 2)) aura_typeerror(L, 1, "string"); if (!lua_isstring(L, 3)) aura_typeerror(L, 1, "string"); if (!lua_isstring(L, 4)) aura_typeerror(L, 1, "string"); tbl = lua_touserdata(L, 1); name = lua_tostring(L, 2); arg = lua_tostring(L, 3); ret = lua_tostring(L, 4); aura_etable_add(tbl, name, arg, ret); return 0; }
/*** Setup the callback for node status change notifications. @function aura.status_cb @tparam node node The node that we want to get status notifications about @tparam function callback the function to call when status change occurs @param arg user argument to pass to the callback */ static int l_set_status_change_cb(lua_State *L) { struct laura_node *lnode; struct aura_node *node; TRACE(); aura_check_args(L, 3); lnode = lua_fetch_node(L, 1); if (!lnode) return luaL_error(L, "Failed to retrieve node"); node = lnode->node; if (!lua_isfunction(L, 2)) aura_typeerror(L, 2, "function"); if (lnode->refs & REF_STATUS_CB) { luaL_unref(L, LUA_REGISTRYINDEX, lnode->status_changed_arg_ref); luaL_unref(L, LUA_REGISTRYINDEX, lnode->status_changed_ref); } lnode->refs |= REF_STATUS_CB; lnode->status_changed_arg_ref = luaL_ref(L, LUA_REGISTRYINDEX); lnode->status_changed_ref = luaL_ref(L, LUA_REGISTRYINDEX); aura_status_changed_cb(node, status_cb, lnode); return 0; }
static int l_wait_status(lua_State *L) { struct laura_node *lnode; TRACE(); aura_check_args(L, 2); lnode = lua_fetch_node(L, 1); aura_wait_status(lnode->node, lua_tonumber(L, 2)); return 0; }
/*** Get current node status. The status is either aura.STATUS_ONLINE or aura.STATUS_OFFLINE @function aura.status @tparam node node An open node object to operate on */ static int l_status(lua_State *L) { struct laura_node *lnode; TRACE(); aura_check_args(L, 1); lnode = lua_fetch_node(L, 1); if (!lnode) return luaL_error(L, "Failed to retrieve lnode"); lua_pushnumber(L, aura_get_status(lnode->node)); return 1; }
/*** Open a node (private). This is an internal function, implemented in C. User should NOT call it directly. Call aura.open() wrapper instead @see aura.open @function aura.core_open @tparam string name transport name @tparam string opts transport options, if any @return The node object */ static int l_open_node(lua_State *L) { struct aura_node *node; TRACE(); aura_check_args(L, 2); node = aura_open(lua_tostring(L, 1), lua_tostring(L, 2)); if (!node) return luaL_error(L, "Failed to open node"); return check_node_and_push(L, node); }
static int l_slog_init(lua_State *L) { const char *fname; int level; TRACE(); aura_check_args(L, 2); fname = lua_tostring(L, 1); level = lua_tonumber(L, 2); slog_init(fname, level); return 0; }
static int l_etable_activate(lua_State *L) { struct aura_export_table *tbl; TRACE(); aura_check_args(L, 1); if (!lua_islightuserdata(L, 1)) aura_typeerror(L, 1, "ludata"); tbl = lua_touserdata(L, 1); aura_etable_activate(tbl); return 0; }
static int l_eventloop_del(lua_State *L) { struct laura_node *lnode; TRACE(); aura_check_args(L, 1); lnode = lua_fetch_node(L, 1); if (!lnode) return luaL_error(L, "Failed to retrive arguments"); aura_eventloop_del(lnode->node); return 0; }
/*** Run the event processing loop and dispatch callbacks. @function aura.eventloop_dispatch @param loop [loop] eventloop instance @param flags [number, optional] bitmask of the following flags aura.EVTLOOP_ONCE and aura.EVTLOOP_NONBLOCK */ static int l_eventloop_dispatch(lua_State *L) { struct laura_eventloop *lloop; int flags = 0; TRACE(); aura_check_args(L, 1); if (!lua_isuserdata(L, 1)) aura_typeerror(L, 1, "ludata"); lloop = lua_touserdata(L, 1); if (lua_gettop(L) == 2) flags = lua_tonumber(L, 2); aura_eventloop_dispatch(lloop->loop, flags); return 0; }
static int l_wait_status(lua_State *L) { struct laura_node *lnode; TRACE(); /* Mandatory arguments: node, status */ int status; aura_check_args(L, 2); lnode = lua_fetch_node(L, 1); /* optional arg - timeout */ if (lua_isnumber(L, 3)) { struct timeval tv; lua_totimeout(L, 3, &tv); status = aura_wait_status_timeout(lnode->node, lua_tonumber(L, 2), &tv); } else { status = aura_wait_status(lnode->node, lua_tonumber(L, 2)); } lua_pushnumber(L, status); return 1; }
static int l_etable_get(lua_State *L) { struct laura_node *lnode = NULL; struct aura_node *node = NULL; TRACE(); aura_check_args(L, 1); if (lua_islightuserdata(L, 1)) node = lua_touserdata(L, 1); else lnode = lua_fetch_node(L, 1); if (lnode) node = lnode->node; if (!node) return luaL_error(L, "Failed to fetch node"); return lua_push_etable(L, node->tbl); }
static int l_set_node_container(lua_State *L) { struct laura_node *lnode; TRACE(); aura_check_args(L, 2); if (!lua_isuserdata(L, 1)) aura_typeerror(L, 1, "udata"); if (!lua_istable(L, 2)) aura_typeerror(L, 2, "table"); lnode = lua_touserdata(L, 1); lnode->node_container = luaL_ref(L, LUA_REGISTRYINDEX); lnode->refs |= REF_NODE_CONTAINER; aura_unhandled_evt_cb(lnode->node, event_cb, lnode); return 0; }
static int l_eventloop_add(lua_State *L) { struct laura_node *lnode; struct laura_eventloop *lloop; TRACE(); aura_check_args(L, 2); if (!lua_isuserdata(L, 1)) aura_typeerror(L, 1, "ludata (eventloop)"); lnode = lua_fetch_node(L, 2); lloop = lua_touserdata(L, 1); if (!lloop || !lnode) return luaL_error(L, "Failed to retrive arguments"); aura_eventloop_add(lloop->loop, lnode->node); return 0; }
static int l_etable_create(lua_State *L) { struct aura_node *node; int count = 0; struct aura_export_table *tbl; TRACE(); aura_check_args(L, 2); if (!lua_islightuserdata(L, 1)) aura_typeerror(L, 1, "ludata"); if (!lua_isnumber(L, 2)) aura_typeerror(L, 1, "number"); node = lua_touserdata(L, 1); count = lua_tonumber(L, 2); tbl = aura_etable_create(node, count); if (!tbl) return luaL_error(L, "error creating etable for %d elements", count); lua_pushlightuserdata(L, tbl); return 1; }
/*** Terminate the event processing loop (Internal). Do not call this functuion directly. @see eventloop.loopexit The timeout is given in seconds, fractions of seconds are welcome. Zero timeout or omitting the second argument will cause immediate eventloop termination. ProTIP: You can call this function BEFORE aura.eventloop_dispatch() @function aura.eventloop_loopexit @param loop [loop] eventloop instance @param timeout [number, optional] if specified, the eventloop will be terminated after timeout number of seconds. If no timeout given - the eventloop will be stop immediately. */ static int l_eventloop_loopexit(lua_State *L) { TRACE(); struct laura_eventloop *lloop; aura_check_args(L, 1); struct timeval tv; if (!lua_isuserdata(L, 1)) aura_typeerror(L, 1, "ludata"); lloop = lua_touserdata(L, 1); if (lua_isnumber(L,2)) { lua_totimeout(L, 2, &tv); } else { tv.tv_sec = 0; tv.tv_usec = 0; } aura_eventloop_loopexit(lloop->loop, &tv); return 0; }
static int l_eventloop_destroy(lua_State *L) { struct laura_eventloop *lloop; TRACE(); aura_check_args(L, 1); if (!lua_isuserdata(L, 1)) aura_typeerror(L, 2, "ludata (eventloop)"); lloop = lua_touserdata(L, 1); if (!lloop) return luaL_error(L, "Failed to retrive arguments"); if (!lloop->loop) return 0; aura_eventloop_destroy(lloop->loop); lloop->loop = NULL; return 0; }
/*** Terminate the event processing loop (Internal). Do not call this functuion directly. @see eventloop.loopexit The timeout is given in seconds, fractions of seconds are welcome. Zero timeout or omitting the second argument will cause immediate eventloop termination. ProTIP: You can call this function BEFORE aura.eventloop_dispatch() @function aura.eventloop_loopexit @param loop [loop] eventloop instance @param timeout [number, optional] if specified, the eventloop will be terminated after timeout number of seconds. If no timeout given - the eventloop will be stop immediately. */ static int l_eventloop_loopexit(lua_State *L) { TRACE(); struct laura_eventloop *lloop; double timeout; aura_check_args(L, 1); struct timeval tv; if (!lua_isuserdata(L, 1)) aura_typeerror(L, 1, "ludata"); lloop = lua_touserdata(L, 1); if (lua_gettop(L) == 2) { timeout = lua_tonumber(L, 2); tv.tv_sec = floor(timeout); tv.tv_usec = (timeout - tv.tv_sec) * 1000000; } else { tv.tv_sec = 0; tv.tv_usec = 0; } aura_eventloop_loopexit(lloop->loop, &tv); return 0; }