glib_main_context.c
changeset 0 84fdfb0344c9
equal deleted inserted replaced
-1:000000000000 0:84fdfb0344c9
       
     1 
       
     2 #include <lua.h>
       
     3 #include <lauxlib.h>
       
     4 #include <glib.h>
       
     5 
       
     6 #include "glib_types.h"
       
     7 
       
     8 /// g.main_context
       
     9 /// Glib main context object. Mainly useful when lua needs to
       
    10 /// manage glib-based libs.
       
    11 
       
    12 /// g.main_context.new
       
    13 /// Creates new main context object.
       
    14 /// R: g main context object
       
    15 static int lglib_main_context_new (lua_State *L)
       
    16 {
       
    17 	GMainContext *context = g_main_context_new ();
       
    18 	lglib_main_context_bless (L, context);
       
    19 	g_main_context_unref (context);
       
    20 	return 1;
       
    21 }
       
    22 
       
    23 /// g.main_context.bless
       
    24 /// Blesses given pointer to g main context object.
       
    25 /// A: lightuserdata (C g main context object)
       
    26 /// R: g main context object
       
    27 static int lglib_main_context_bless_lua (lua_State *L)
       
    28 {
       
    29 	luaL_argcheck (L, lua_islightuserdata (L, 1), 1, "g main context lightuserdata expected");
       
    30 	lglib_main_context_bless (L, lua_touserdata (L, 1));
       
    31 	return 1;
       
    32 }
       
    33 
       
    34 /// g.main_context.default
       
    35 /// Returns default main context object.
       
    36 /// R: g main context object
       
    37 static int lglib_main_context_default (lua_State *L)
       
    38 {
       
    39 	GMainContext *context = g_main_context_default ();
       
    40 	lglib_main_context_bless (L, context);
       
    41 	// XXX g_main_context_unref (context);
       
    42 	return 1;
       
    43 }
       
    44 
       
    45 /// main_context:iteration
       
    46 /// Performs single full iteration in blocking or non-blocking manner,
       
    47 /// depending on value of argument.
       
    48 /// Returns true, if some events have been handled.
       
    49 /// A: boolean (optional)
       
    50 /// R: boolean
       
    51 static int lglib_main_context_iteration (lua_State *L)
       
    52 {
       
    53 	lglib_main_context_t *object = luaL_checklglib_main_context (L, 1);
       
    54 	int may_block = 0;
       
    55 	if ( lua_gettop (L) > 1 ) {
       
    56 		luaL_checktype (L, 2, LUA_TBOOLEAN);
       
    57 		may_block = lua_toboolean (L, 2);
       
    58 	}
       
    59 	lua_pushboolean (L, g_main_context_iteration (object->main_context, may_block));
       
    60 	return 1;
       
    61 }
       
    62 
       
    63 /// main_context:pending
       
    64 /// Indicates, if there are present events in sources.
       
    65 /// R: boolean
       
    66 static int lglib_main_context_pending (lua_State *L)
       
    67 {
       
    68 	lglib_main_context_t *object = luaL_checklglib_main_context (L, 1);
       
    69 	lua_pushboolean (L, g_main_context_pending (object->main_context));
       
    70 	return 1;
       
    71 }
       
    72 
       
    73 /// main_context:find_source
       
    74 /// Returns source with given id.
       
    75 /// A: integer (source id)
       
    76 /// R: g main context object or nil
       
    77 static int lglib_main_context_find_source (lua_State *L)
       
    78 {
       
    79 	lglib_main_context_t *object = luaL_checklglib_main_context (L, 1);
       
    80 	int id = luaL_checkint (L, 2);
       
    81 	GSource *source = g_main_context_find_source_by_id (object->main_context, id);
       
    82 	if (source) {
       
    83 		lglib_source_bless (L, source);
       
    84 		// XXX g_source_unref (source)
       
    85 	} else
       
    86 		lua_pushnil (L);
       
    87 	return 1;
       
    88 }
       
    89 
       
    90 /// main_context:wakeup
       
    91 /// Awakes main context if it currently poll() ing.
       
    92 /// XXX Seems to be threading-related routine, how lua will work in this case?
       
    93 static int lglib_main_context_wakeup (lua_State *L)
       
    94 {
       
    95 	lglib_main_context_t *object = luaL_checklglib_main_context (L, 1);
       
    96 	g_main_context_wakeup (object->main_context);
       
    97 	return 0;
       
    98 }
       
    99 
       
   100 /// main_context:acquire
       
   101 /// Tries to own main context.
       
   102 /// R: boolean (success)
       
   103 static int lglib_main_context_acquire (lua_State *L)
       
   104 {
       
   105 	lglib_main_context_t *object = luaL_checklglib_main_context (L, 1);
       
   106 	lua_pushboolean (L, g_main_context_acquire (object->main_context));
       
   107 	return 1;
       
   108 }
       
   109 
       
   110 /// main_context:release
       
   111 /// Disowns acquired context.
       
   112 /// Note: release context as many times, as you acquired it.
       
   113 static int lglib_main_context_release (lua_State *L)
       
   114 {
       
   115 	lglib_main_context_t *object = luaL_checklglib_main_context (L, 1);
       
   116 	g_main_context_release (object->main_context);
       
   117 	return 0;
       
   118 }
       
   119 
       
   120 /// main_context:owner
       
   121 /// Indicates if current thread is owner of context.
       
   122 /// R: boolean
       
   123 static int lglib_main_context_owner (lua_State *L)
       
   124 {
       
   125 	lglib_main_context_t *object = luaL_checklglib_main_context (L, 1);
       
   126 	lua_pushboolean (L, g_main_context_is_owner (object->main_context));
       
   127 	return 1;
       
   128 }
       
   129 
       
   130 /// main_context:wait
       
   131 /// For now this will not be implemented, as it requires threading part of glib
       
   132 
       
   133 /// WARNING: conventions for next four methods are likely to change
       
   134 /// as I become more familiar with all that stuff.
       
   135 
       
   136 /// main_context:prepare
       
   137 /// Polling preparation step.
       
   138 /// R: boolean (indicates readiness for dispatching before polling), integer (priority of most important ready source, if first value is true)
       
   139 static int lglib_main_context_prepare (lua_State *L)
       
   140 {
       
   141 	lglib_main_context_t *object = luaL_checklglib_main_context (L, 1);
       
   142 	gint priority;
       
   143 	gboolean ready = g_main_context_prepare (object->main_context, &priority);
       
   144 	lua_pushboolean (L, ready);
       
   145 	if (!ready)
       
   146 		return 1;
       
   147 	lua_pushnumber (L, priority);
       
   148 	return 0;
       
   149 }
       
   150 
       
   151 /// main_context:query
       
   152 /// Get necessary for polling information.
       
   153 /// A: integer (maximum priority), integer (number of fds to allocate)
       
   154 /// R: userdata (GPollFDs), integer (number of fds required), integer (timeout)
       
   155 static int lglib_main_context_query (lua_State *L)
       
   156 {
       
   157 	lglib_main_context_t *object = luaL_checklglib_main_context (L, 1);
       
   158 	int priority = luaL_checkint (L, 2);
       
   159 	int nfds = luaL_checkint (L, 3);
       
   160 	gint timeout;
       
   161 	GPollFD *fds = lua_newuserdata (L, sizeof (GPollFD) * nfds);
       
   162 	lua_pushnumber (L, g_main_context_query (object->main_context, priority, &timeout, fds, nfds));
       
   163 	lua_pushnumber (L, timeout);
       
   164 	return 3;
       
   165 }
       
   166 
       
   167 /// main_context:check
       
   168 /// Passes results of polling back to main loop.
       
   169 /// A: integer (priority), userdata (GPollFDs), integer (number of fds)
       
   170 /// R: boolean (readiness for dispatching)
       
   171 static int lglib_main_context_check (lua_State *L)
       
   172 {
       
   173 	lglib_main_context_t *object = luaL_checklglib_main_context (L, 1);
       
   174 	int priority = luaL_checkint (L, 2);
       
   175 	GPollFD *fds = lua_touserdata (L, 3); // FIXME
       
   176 	int nfds = luaL_checkint (L, 4);
       
   177 	lua_pushboolean (L, g_main_context_check (object->main_context, priority, fds, nfds));
       
   178 	return 1;
       
   179 }
       
   180 
       
   181 /// main_context:dispatch
       
   182 /// Actually dispatches pending event sources
       
   183 static int lglib_main_context_dispatch (lua_State *L)
       
   184 {
       
   185 	lglib_main_context_t *object = luaL_checklglib_main_context (L, 1);
       
   186 	g_main_context_dispatch (object->main_context);
       
   187 	return 0;
       
   188 }
       
   189 
       
   190 /// main_context:poll_function
       
   191 /// main_context:add_poll
       
   192 /// main_context:remove_poll
       
   193 /// Let's delay implementing this until fd objects will be ready...
       
   194 
       
   195 /// main_context:pointer
       
   196 /// Returns pointe to underlying C structure.
       
   197 /// A: g main context object
       
   198 /// R: lightuserdata
       
   199 static int lglib_main_context_pointer (lua_State *L)
       
   200 {
       
   201 	lglib_main_context_t *object = luaL_checklglib_main_context (L, 1);
       
   202 	lua_pushlightuserdata (L, object->main_context);
       
   203 	return 1;
       
   204 }
       
   205 
       
   206 static int lglib_main_context_gc (lua_State *L)
       
   207 {
       
   208 	lglib_main_context_t *object = lua_touserdata (L, 1);
       
   209 	g_main_context_unref (object->main_context);
       
   210 	return 0;
       
   211 }
       
   212 
       
   213 static const luaL_Reg lglib_main_context_reg_f[] = {
       
   214 	{ "new",     lglib_main_context_new       },
       
   215 	{ "bless",   lglib_main_context_bless_lua },
       
   216 	{ "default", lglib_main_context_default   },
       
   217 	{ NULL,      NULL                         },
       
   218 };
       
   219 
       
   220 static const luaL_Reg lglib_main_context_reg_m[] = {
       
   221 	{ "iteration",   lglib_main_context_iteration   },
       
   222 	{ "pending",     lglib_main_context_pending     },
       
   223 	{ "find_source", lglib_main_context_find_source },
       
   224 	{ "wakeup",      lglib_main_context_wakeup      },
       
   225 	{ "acquire",     lglib_main_context_acquire     },
       
   226 	{ "release",     lglib_main_context_release     },
       
   227 	{ "owner",       lglib_main_context_owner       },
       
   228 	{ "prepare",     lglib_main_context_prepare     },
       
   229 	{ "query",       lglib_main_context_query       },
       
   230 	{ "check",       lglib_main_context_check       },
       
   231 	{ "dispatch",    lglib_main_context_dispatch    },
       
   232 	{ "pointer",     lglib_main_context_pointer     },
       
   233 	{ "__gc",        lglib_main_context_gc          },
       
   234 	{ NULL,          NULL                           },
       
   235 };
       
   236 
       
   237 int luaopen_glib_main_context (lua_State *L)
       
   238 {
       
   239 	luaL_newmetatable (L, "glib.main_context" );
       
   240 	lua_pushstring (L, "__index");
       
   241 	lua_pushvalue (L, -2);
       
   242 	lua_settable (L, -3);
       
   243 	luaL_register (L, NULL, lglib_main_context_reg_m);
       
   244 	lua_pop (L, 1);
       
   245 	luaL_register (L, "g.main_context", lglib_main_context_reg_f);
       
   246 	return 1;
       
   247 }
       
   248