naev 0.10.4
nlua_news.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
10#include <lauxlib.h>
11
12#include "naev.h"
15#include "nlua_news.h"
16
17#include "array.h"
18#include "land.h"
19#include "nlua_time.h"
20#include "nluadef.h"
21#include "nstring.h"
22#include "ntime.h"
23
24extern news_t *news_list;
25extern int land_loaded;
26
27news_t* luaL_validnews( lua_State *L, int ind );
28int lua_isnews( lua_State *L, int ind );
29LuaNews_t* lua_pushnews( lua_State *L, LuaNews_t news );
30
31static int newsL_add( lua_State *L );
32static int newsL_rm( lua_State *L );
33static int newsL_get( lua_State *L );
34static int newsL_eq( lua_State *L );
35static int newsL_title( lua_State *L );
36static int newsL_desc( lua_State *L );
37static int newsL_faction( lua_State *L );
38static int newsL_date( lua_State *L );
39static int newsL_bind( lua_State *L );
40static const luaL_Reg news_methods[] = {
41 {"add", newsL_add},
42 {"rm", newsL_rm},
43 {"get", newsL_get},
44 {"title", newsL_title},
45 {"desc", newsL_desc},
46 {"faction", newsL_faction},
47 {"date", newsL_date},
48 {"bind", newsL_bind},
49 {"__eq", newsL_eq},
50 {0, 0}
51};
59int nlua_loadNews( nlua_env env )
60{
61 nlua_register(env, NEWS_METATABLE, news_methods, 1);
62 return 0; /* No error */
63}
64
72LuaNews_t* lua_tonews( lua_State *L, int ind )
73{
74 return (LuaNews_t*) lua_touserdata(L,ind);
75}
83LuaNews_t* luaL_checknews( lua_State *L, int ind )
84{
85 if (lua_isnews(L,ind))
86 return lua_tonews(L,ind);
87 luaL_typerror(L, ind, NEWS_METATABLE);
88 return NULL;
89}
97LuaNews_t* lua_pushnews( lua_State *L, LuaNews_t news )
98{
99 LuaNews_t *la = (LuaNews_t*) lua_newuserdata(L, sizeof(LuaNews_t));
100 *la = news;
101 luaL_getmetatable(L, NEWS_METATABLE);
102 lua_setmetatable(L, -2);
103 return la;
104}
112int lua_isnews( lua_State *L, int ind )
113{
114 int ret;
115
116 if (lua_getmetatable(L,ind)==0)
117 return 0;
118 lua_getfield(L, LUA_REGISTRYINDEX, NEWS_METATABLE);
119
120 ret = 0;
121 if (lua_rawequal(L, -1, -2)) /* does it have the correct mt? */
122 ret = 1;
123
124 lua_pop(L, 2); /* remove both metatables */
125 return ret;
126}
127
135news_t* luaL_validnews( lua_State *L, int ind )
136{
137 LuaNews_t *ln = luaL_checknews( L, ind );
138 news_t *n = news_get( *ln );
139 if (n==NULL)
140 NLUA_ERROR(L, _("Article is invalid."));
141 return n;
142}
143
167int newsL_add( lua_State *L )
168{
169 const char *title, *body, *faction;
170 ntime_t date, date_to_rm;
171 int priority;
172
173 title = NULL;
174 body = NULL;
175 faction = NULL;
176 priority = 5;
177
178 date = ntime_get();
179 date_to_rm = NEWS_FOREVER;
180
181 /* If a table is passed in. ugly hack */
182 if (lua_istable(L, 1)) {
183 lua_pushnil(L);
184
185 /* traverse table */
186 while (lua_next(L, -2)) {
187 /* traverse sub table */
188 if (lua_istable(L, -1)) {
189 faction = title = body = NULL;
190 priority = 5;
191 date = ntime_get();
192 date_to_rm = NEWS_FOREVER;
193
194 lua_getfield( L, -1, "faction" );
195 if (!lua_isnil(L,-1))
196 faction = luaL_checkstring(L,-1);
197 lua_pop(L,1);
198
199 lua_getfield( L, -1, "head" );
200 if (!lua_isnil(L,-1))
201 title = luaL_checkstring(L,-1);
202 lua_pop(L,1);
203
204 lua_getfield( L, -1, "body" );
205 if (!lua_isnil(L,-1))
206 body = luaL_checkstring(L,-1);
207 lua_pop(L,1);
208
209 lua_getfield( L, -1, "date" );
210 if (!lua_isnil(L,-1)) {
211 if (lua_isnumber(L,-1))
212 date = lua_tonumber(L,-1);
213 else
214 date = luaL_validtime(L,-1);
215 }
216 lua_pop(L,1);
217
218 lua_getfield( L, -1, "date_to_rm" );
219 if (!lua_isnil(L,-1)) {
220 if (lua_isnumber(L,-1))
221 date_to_rm = lua_tonumber(L,-1);
222 else
223 date_to_rm = luaL_validtime(L,-1);
224 }
225 lua_pop(L,1);
226
227 lua_getfield( L, -1, "priority" );
228 if (!lua_isnil(L,-1))
229 priority = luaL_checkinteger(L,-1);
230 lua_pop(L,1);
231
232 if (title && body && faction)
233 news_add( title, body, faction, NULL, date, date_to_rm, priority );
234 else
235 WARN(_("Bad arguments"));
236 }
237 lua_pop(L, 1);
238 }
239 lua_pop(L, 1);
240
241 /* If we're landed, we should regenerate the news buffer. */
242 if (landed) {
244 if (land_loaded)
245 bar_regen();
246 }
247
248 return 0;
249 }
250
251 if (!(lua_isstring(L, 1) && lua_isstring(L, 2) && lua_isstring(L, 3))) {
252 WARN(_("\nBad arguments, use "
253 "addArticle(\"Faction\",\"Title\",\"Content\",[date,[date_to_rm]])"));
254 return 0;
255 }
256
257 faction = luaL_checkstring(L, 1);
258 title = luaL_checkstring(L, 2);
259 body = luaL_checkstring(L, 3);
260 priority = luaL_optinteger(L, 6, 5);
261
262 /* Get date and date to remove, or leave at defaults. */
263 if (!lua_isnoneornil(L,4)) {
264 if (lua_istime(L, 4))
265 date_to_rm = luaL_validtime(L, 4);
266 else
267 date_to_rm = luaL_checklong(L, 4);
268 }
269 if (!lua_isnoneornil(L,5)) {
270 if (lua_istime(L, 5))
271 date = luaL_validtime(L, 5);
272 else
273 date = luaL_checklong(L, 5);
274 }
275
276 if (title && body && faction) {
277 LuaNews_t n_article = news_add( title, body, faction, NULL, date, date_to_rm, priority );
278 lua_pushnews( L, n_article );
279 }
280 else
281 NLUA_ERROR(L,_("Bad arguments"));
282
283 /* If we're landed, we should regenerate the news buffer. */
284 if (landed) {
286 if (land_loaded)
287 bar_regen();
288 }
289
290 return 1;
291}
292
298int newsL_rm( lua_State *L )
299{
300 if (lua_istable(L, 1)) {
301 lua_pushnil(L);
302 while (lua_next(L, -2)) {
303 LuaNews_t *Larticle = luaL_checknews(L, -1);
304 news_rm( *Larticle );
305 lua_pop(L, 1);
306 }
307 }
308 else {
309 LuaNews_t *Larticle = luaL_checknews(L, 1);
310 news_rm( *Larticle );
311 }
312
313 /* If we're landed, we should regenerate the news buffer. */
314 if (landed) {
316 if (land_loaded)
317 bar_regen();
318 }
319
320 return 1;
321}
322
342int newsL_get( lua_State *L )
343{
344 ntime_t date = -1;
345 const char *characteristic = NULL;
346 int print_all = 0;
347 int narticle = 1;
348
349 if (lua_isnoneornil(L, 1)) /* Case no argument */
350 print_all = 1;
351 else if (lua_isnumber(L, 1))
352 date = (ntime_t)lua_tonumber(L, 1);
353 else if (lua_isstring(L, 1))
354 characteristic = lua_tostring(L, 1);
355 else
356 NLUA_INVALID_PARAMETER(L); /* Bad Parameter */
357
358 /* Now put all the matching articles in a table. */
359 lua_newtable(L);
360 for (int i=0; i<array_size(news_list); i++) {
361 news_t *n = &news_list[i];
362
363 if ((n->title == NULL) || (n->desc == NULL) || (n->faction == NULL))
364 continue;
365
366 if (print_all || date == n->date
367 || (characteristic
368 && ((strcmp( n->title, characteristic ) == 0)
369 || (strcmp( n->desc, characteristic ) == 0)
370 || (strcmp( n->faction, characteristic ) == 0)
371 || (n->tag != NULL && strcmp( n->tag, characteristic ) == 0 )))) {
372 lua_pushnews(L, n->id); /* value */
373 lua_rawseti(L, -2, narticle++);
374 }
375 }
376
377 return 1;
378}
379
390int newsL_eq( lua_State *L )
391{
392 const LuaNews_t *a1, *a2;
393 a1 = luaL_checknews(L, 1);
394 a2 = luaL_checknews(L, 2);
395 lua_pushboolean(L, *a1 == *a2);
396 return 1;
397}
398
405int newsL_title( lua_State *L )
406{
407 news_t *article_ptr = luaL_validnews(L, 1);
408 lua_pushstring(L, article_ptr->title);
409 return 1;
410}
411
418int newsL_desc( lua_State *L )
419{
420 news_t *article_ptr = luaL_validnews(L, 1);
421 lua_pushstring(L, article_ptr->desc);
422 return 1;
423}
424
431int newsL_faction( lua_State *L )
432{
433 news_t *article_ptr = luaL_validnews(L, 1);
434 lua_pushstring(L, article_ptr->faction);
435 return 1;
436}
437
444int newsL_date( lua_State *L )
445{
446 news_t *article_ptr = luaL_validnews(L, 1);
447 lua_pushinteger(L, (lua_Integer)article_ptr->date);
448 return 1;
449}
450
457int newsL_bind( lua_State *L )
458{
459 news_t *article_ptr;
460 LuaNews_t *a = NULL;
461
462 if (lua_istable(L, 1)) {
463 const char *tag = luaL_checkstring(L, 2);
464 lua_pop(L, 1);
465 lua_pushnil(L);
466
467 /* traverse table */
468 while (lua_next(L, -2)) {
469 if (!(a = luaL_checknews(L, -1))) {
470 WARN(_("Bad argument to news.date(), must be article or a table of articles"));
471 return 0;
472 }
473 article_ptr = news_get( *a );
474 if (article_ptr == NULL) {
475 WARN(_("Article not valid"));
476 return 0;
477 }
478 article_ptr->tag = strdup(tag);
479 lua_pop(L, 1);
480 }
481 }
482 else {
483 const char *tag;
484 if (!(a = luaL_checknews(L, 1))) {
485 WARN(_("Bad argument to news.date(), must be article or a table of articles"));
486 return 0;
487 }
488 article_ptr = news_get(*a);
489 if (article_ptr == NULL) {
490 WARN(_("Article not valid"));
491 return 0;
492 }
493
494 tag = luaL_checkstring(L, 2);
495 article_ptr->tag = strdup( tag );
496 }
497 return 1;
498}
Provides macros to work with dynamic arrays.
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
Definition: array.h:168
void bar_regen(void)
Regenerates the bar list.
Definition: land.c:452
int landed
Definition: land.c:74
Spob * land_spob
Definition: land.c:82
Header file with generic functions and naev-specifics.
int news_add(const char *title, const char *content, const char *faction, const char *tag, ntime_t date, ntime_t date_to_rm, int priority)
makes a new article and puts it into the list
Definition: news.c:100
news_t * news_get(int id)
gets the article with id ID, else NULL
Definition: news.c:176
int * generate_news(int faction)
Generates news from newslist from specific faction AND Generic news.
Definition: news.c:209
news_t * news_list
Definition: news.c:39
static int newsL_bind(lua_State *L)
Tags a news article or a table of articles with a string. Lua function parameter: Article a Article t...
Definition: nlua_news.c:457
static int newsL_eq(lua_State *L)
Check news articles for equality.
Definition: nlua_news.c:390
int lua_isnews(lua_State *L, int ind)
Checks to see if ind is a news.
Definition: nlua_news.c:112
int land_loaded
Definition: land.c:75
static const luaL_Reg news_methods[]
Definition: nlua_news.c:40
int nlua_loadNews(nlua_env env)
Loads the news library.
Definition: nlua_news.c:59
static int newsL_rm(lua_State *L)
Frees a news article or a table of articles. Lua function parameter: News n News article to free.
Definition: nlua_news.c:298
static int newsL_get(lua_State *L)
Gets all matching news articles in a table.
Definition: nlua_news.c:342
static int newsL_desc(lua_State *L)
Gets the news article description. Lua function parameter: Article a article to get the desc of Lua r...
Definition: nlua_news.c:418
LuaNews_t * luaL_checknews(lua_State *L, int ind)
Gets news at index or raises error if there is no news at index.
Definition: nlua_news.c:83
static int newsL_add(lua_State *L)
Lua bindings to interact with the news.
Definition: nlua_news.c:167
news_t * luaL_validnews(lua_State *L, int ind)
Makes sure the news is valid or raises a Lua error.
Definition: nlua_news.c:135
LuaNews_t * lua_pushnews(lua_State *L, LuaNews_t news)
Pushes a news on the stack.
Definition: nlua_news.c:97
LuaNews_t * lua_tonews(lua_State *L, int ind)
Gets news at index.
Definition: nlua_news.c:72
static int newsL_title(lua_State *L)
Gets the news article title. Lua function parameter: Article a article to get the title of Lua return...
Definition: nlua_news.c:405
static int newsL_date(lua_State *L)
Gets the news article date. Lua function parameter: Article a article to get the date of Lua return p...
Definition: nlua_news.c:444
static int newsL_faction(lua_State *L)
Gets the news article faction. Lua function parameter: Article a article to get the faction of Lua re...
Definition: nlua_news.c:431
int lua_istime(lua_State *L, int ind)
Checks to see if ind is a time.
Definition: nlua_time.c:141
ntime_t luaL_validtime(lua_State *L, int ind)
Gets a time directly.
Definition: nlua_time.c:115
ntime_t ntime_get(void)
Gets the current time.
Definition: ntime.c:108
int faction
Definition: space.h:66
SpobPresence presence
Definition: space.h:102
Represents a news article.
Definition: news.h:16
char * faction
Definition: news.h:22
char * title
Definition: news.h:20
ntime_t date
Definition: news.h:25
char * tag
Definition: news.h:23
char * desc
Definition: news.h:21